From 9bab06b8548db9a55dfa581fdfb726aee9f4bbd0 Mon Sep 17 00:00:00 2001 From: injectives <11927660+injectives@users.noreply.github.com> Date: Tue, 31 May 2022 13:59:31 +0100 Subject: [PATCH] Add spotless-maven-plugin for Java formatting (#1227) (#1234) * Add spotless-maven-plugin for Java formatting This update introduces similar updates to Neo4j server. * Add .gitattributes --- .gitattributes | 3 + .../java/org/neo4j/driver/AccessMode.java | 3 +- .../main/java/org/neo4j/driver/AuthToken.java | 5 +- .../java/org/neo4j/driver/AuthTokens.java | 107 +- .../main/java/org/neo4j/driver/Bookmark.java | 9 +- .../main/java/org/neo4j/driver/Config.java | 345 ++-- .../neo4j/driver/ConnectionPoolMetrics.java | 4 +- .../main/java/org/neo4j/driver/Driver.java | 10 +- .../java/org/neo4j/driver/GraphDatabase.java | 127 +- .../main/java/org/neo4j/driver/Logger.java | 17 +- .../main/java/org/neo4j/driver/Logging.java | 34 +- .../main/java/org/neo4j/driver/Metrics.java | 4 +- .../java/org/neo4j/driver/MetricsAdapter.java | 3 +- .../src/main/java/org/neo4j/driver/Query.java | 124 +- .../java/org/neo4j/driver/QueryRunner.java | 11 +- .../main/java/org/neo4j/driver/Record.java | 8 +- .../main/java/org/neo4j/driver/Records.java | 36 +- .../main/java/org/neo4j/driver/Result.java | 13 +- .../main/java/org/neo4j/driver/Session.java | 20 +- .../java/org/neo4j/driver/SessionConfig.java | 130 +- .../java/org/neo4j/driver/Transaction.java | 3 +- .../org/neo4j/driver/TransactionConfig.java | 105 +- .../org/neo4j/driver/TransactionWork.java | 5 +- .../src/main/java/org/neo4j/driver/Value.java | 57 +- .../main/java/org/neo4j/driver/Values.java | 537 +++--- .../neo4j/driver/async/AsyncQueryRunner.java | 12 +- .../org/neo4j/driver/async/AsyncSession.java | 24 +- .../neo4j/driver/async/AsyncTransaction.java | 4 +- .../driver/async/AsyncTransactionWork.java | 5 +- .../org/neo4j/driver/async/ResultCursor.java | 8 +- .../exceptions/AuthenticationException.java | 8 +- .../AuthorizationExpiredException.java | 11 +- .../driver/exceptions/ClientException.java | 18 +- .../ConnectionReadTimeoutException.java | 10 +- .../driver/exceptions/DatabaseException.java | 8 +- .../driver/exceptions/DiscoveryException.java | 8 +- .../exceptions/FatalDiscoveryException.java | 13 +- .../driver/exceptions/Neo4jException.java | 30 +- .../exceptions/NoSuchRecordException.java | 8 +- .../driver/exceptions/ProtocolException.java | 13 +- .../exceptions/ResultConsumedException.java | 8 +- .../driver/exceptions/SecurityException.java | 13 +- .../ServiceUnavailableException.java | 13 +- .../exceptions/SessionExpiredException.java | 13 +- .../exceptions/TokenExpiredException.java | 8 +- .../TransactionNestingException.java | 8 +- .../driver/exceptions/TransientException.java | 8 +- .../exceptions/UntrustedServerException.java | 6 +- .../exceptions/value/LossyCoercion.java | 9 +- .../exceptions/value/NotMultiValued.java | 9 +- .../driver/exceptions/value/Uncoercible.java | 9 +- .../driver/exceptions/value/Unsizable.java | 8 +- .../exceptions/value/ValueException.java | 8 +- .../driver/internal/AbstractQueryRunner.java | 41 +- .../org/neo4j/driver/internal/AsValue.java | 3 +- .../driver/internal/BoltServerAddress.java | 148 +- .../neo4j/driver/internal/BookmarkHolder.java | 15 +- .../driver/internal/ConnectionSettings.java | 15 +- .../neo4j/driver/internal/DatabaseName.java | 3 +- .../driver/internal/DatabaseNameUtil.java | 32 +- .../internal/DefaultBookmarkHolder.java | 20 +- .../internal/DefaultDomainNameResolver.java | 15 +- .../internal/DirectConnectionProvider.java | 55 +- .../driver/internal/DomainNameResolver.java | 5 +- .../neo4j/driver/internal/DriverFactory.java | 331 ++-- .../neo4j/driver/internal/FailableCursor.java | 3 +- .../driver/internal/ImpersonationUtil.java | 22 +- .../driver/internal/InternalBookmark.java | 94 +- .../driver/internal/InternalDatabaseName.java | 39 +- .../neo4j/driver/internal/InternalDriver.java | 114 +- .../neo4j/driver/internal/InternalEntity.java | 84 +- .../driver/internal/InternalIsoDuration.java | 191 +- .../neo4j/driver/internal/InternalNode.java | 34 +- .../neo4j/driver/internal/InternalPair.java | 41 +- .../neo4j/driver/internal/InternalPath.java | 207 +-- .../driver/internal/InternalPoint2D.java | 46 +- .../driver/internal/InternalPoint3D.java | 51 +- .../neo4j/driver/internal/InternalRecord.java | 130 +- .../driver/internal/InternalRelationship.java | 44 +- .../neo4j/driver/internal/InternalResult.java | 78 +- .../driver/internal/InternalSession.java | 137 +- .../driver/internal/InternalTransaction.java | 49 +- .../internal/ReadOnlyBookmarkHolder.java | 12 +- .../internal/ResolvedBoltServerAddress.java | 69 +- .../driver/internal/RevocationStrategy.java | 8 +- .../driver/internal/RoutingErrorHandler.java | 7 +- .../org/neo4j/driver/internal/Scheme.java | 59 +- .../driver/internal/SecuritySettings.java | 142 +- .../neo4j/driver/internal/SessionFactory.java | 6 +- .../driver/internal/SessionFactoryImpl.java | 83 +- .../async/AsyncAbstractQueryRunner.java | 30 +- .../internal/async/ConnectionContext.java | 7 +- .../async/ImmutableConnectionContext.java | 38 +- .../internal/async/InternalAsyncSession.java | 193 +- .../async/InternalAsyncTransaction.java | 25 +- .../async/LeakLoggingNetworkSession.java | 50 +- .../internal/async/NetworkConnection.java | 335 ++-- .../driver/internal/async/NetworkSession.java | 391 ++-- .../internal/async/ResultCursorsHolder.java | 53 +- .../internal/async/UnmanagedTransaction.java | 345 ++-- .../AuthorizationStateListener.java | 6 +- .../async/connection/BoltProtocolUtil.java | 59 +- .../async/connection/BootstrapFactory.java | 23 +- .../async/connection/ChannelAttributes.java | 179 +- .../connection/ChannelConnectedListener.java | 58 +- .../async/connection/ChannelConnector.java | 6 +- .../connection/ChannelConnectorImpl.java | 114 +- .../connection/ChannelPipelineBuilder.java | 8 +- .../ChannelPipelineBuilderImpl.java | 19 +- .../async/connection/DirectConnection.java | 74 +- .../connection/EventLoopGroupFactory.java | 66 +- .../HandshakeCompletedListener.java | 41 +- .../async/connection/HandshakeHandler.java | 160 +- .../connection/NettyChannelInitializer.java | 64 +- .../connection/NettyDomainNameResolver.java | 38 +- .../NettyDomainNameResolverGroup.java | 13 +- .../async/connection/RoutingConnection.java | 82 +- .../internal/async/inbound/ByteBufInput.java | 49 +- .../async/inbound/ChannelErrorHandler.java | 94 +- .../internal/async/inbound/ChunkDecoder.java | 31 +- .../async/inbound/ConnectTimeoutHandler.java | 23 +- .../inbound/ConnectionReadTimeoutHandler.java | 18 +- .../inbound/InboundMessageDispatcher.java | 222 +-- .../async/inbound/InboundMessageHandler.java | 64 +- .../async/inbound/MessageDecoder.java | 35 +- .../outbound/ChunkAwareByteBufOutput.java | 116 +- .../outbound/OutboundMessageHandler.java | 53 +- .../async/pool/ConnectionFactory.java | 6 +- .../async/pool/ConnectionPoolImpl.java | 370 ++-- .../async/pool/ExtendedChannelPool.java | 6 +- .../async/pool/NettyChannelHealthChecker.java | 92 +- .../internal/async/pool/NettyChannelPool.java | 119 +- .../async/pool/NettyChannelTracker.java | 198 +- .../async/pool/NetworkConnectionFactory.java | 12 +- .../internal/async/pool/PoolSettings.java | 33 +- .../internal/cluster/ClusterComposition.java | 136 +- .../ClusterCompositionLookupResult.java | 21 +- .../cluster/ClusterCompositionProvider.java | 7 +- .../internal/cluster/ClusterRoutingTable.java | 205 +-- .../internal/cluster/IdentityResolver.java | 17 +- .../MultiDatabasesRoutingProcedureRunner.java | 40 +- .../driver/internal/cluster/Rediscovery.java | 8 +- .../internal/cluster/RediscoveryImpl.java | 463 +++-- .../RouteMessageRoutingProcedureRunner.java | 73 +- .../internal/cluster/RoutingContext.java | 95 +- ...ngProcedureClusterCompositionProvider.java | 97 +- .../cluster/RoutingProcedureResponse.java | 39 +- .../cluster/RoutingProcedureRunner.java | 7 +- .../internal/cluster/RoutingSettings.java | 37 +- .../driver/internal/cluster/RoutingTable.java | 18 +- .../internal/cluster/RoutingTableHandler.java | 8 +- .../cluster/RoutingTableHandlerImpl.java | 158 +- .../cluster/RoutingTableRegistry.java | 10 +- .../cluster/RoutingTableRegistryImpl.java | 283 ++- .../SingleDatabaseRoutingProcedureRunner.java | 103 +- .../LeastConnectedLoadBalancingStrategy.java | 56 +- .../cluster/loadbalancing/LoadBalancer.java | 348 ++-- .../loadbalancing/LoadBalancingStrategy.java | 8 +- .../loadbalancing/RoundRobinArrayIndex.java | 24 +- .../internal/cursor/AsyncResultCursor.java | 4 +- .../cursor/AsyncResultCursorImpl.java | 119 +- .../cursor/AsyncResultCursorOnlyFactory.java | 43 +- .../cursor/DisposableAsyncResultCursor.java | 76 +- .../internal/cursor/ResultCursorFactory.java | 3 +- .../cursor/ResultCursorFactoryImpl.java | 45 +- .../internal/cursor/RxResultCursor.java | 9 +- .../internal/cursor/RxResultCursorImpl.java | 140 +- .../handlers/BeginTxResponseHandler.java | 30 +- .../ChannelReleasingResetResponseHandler.java | 45 +- .../handlers/CommitTxResponseHandler.java | 39 +- .../handlers/HelloResponseHandler.java | 103 +- .../LegacyPullAllResponseHandler.java | 272 ++- .../handlers/NoOpResponseHandler.java | 18 +- .../handlers/PingResponseHandler.java | 27 +- .../handlers/PullAllResponseHandler.java | 6 +- .../internal/handlers/PullHandlers.java | 59 +- .../PullResponseCompletionListener.java | 9 +- .../handlers/ResetResponseHandler.java | 40 +- .../handlers/RollbackTxResponseHandler.java | 30 +- .../handlers/RouteMessageResponseHandler.java | 57 +- .../handlers/RoutingResponseHandler.java | 110 +- .../internal/handlers/RunResponseHandler.java | 56 +- ...SessionPullResponseCompletionListener.java | 41 +- ...sactionPullResponseCompletionListener.java | 22 +- .../pulln/AutoPullResponseHandler.java | 250 +-- .../pulln/BasicPullResponseHandler.java | 563 +++--- .../handlers/pulln/FetchSizeUtil.java | 12 +- .../handlers/pulln/PullResponseHandler.java | 14 +- .../logging/ChannelActivityLogger.java | 46 +- .../internal/logging/ChannelErrorLogger.java | 23 +- .../internal/logging/ConsoleLogging.java | 70 +- .../internal/logging/DevNullLogger.java | 41 +- .../internal/logging/DevNullLogging.java | 17 +- .../driver/internal/logging/JULogger.java | 65 +- .../driver/internal/logging/JULogging.java | 12 +- .../driver/internal/logging/NettyLogger.java | 169 +- .../driver/internal/logging/NettyLogging.java | 12 +- .../internal/logging/PrefixedLogger.java | 19 +- .../internal/logging/ReformattedLogger.java | 64 +- .../driver/internal/logging/Slf4jLogger.java | 76 +- .../driver/internal/logging/Slf4jLogging.java | 26 +- .../messaging/AbstractMessageWriter.java | 28 +- .../internal/messaging/BoltProtocol.java | 67 +- .../messaging/BoltProtocolVersion.java | 74 +- .../driver/internal/messaging/Message.java | 3 +- .../internal/messaging/MessageEncoder.java | 5 +- .../internal/messaging/MessageFormat.java | 18 +- .../messaging/ResponseMessageHandler.java | 10 +- .../internal/messaging/ValuePacker.java | 12 +- .../internal/messaging/ValueUnpacker.java | 6 +- .../messaging/common/CommonMessageReader.java | 72 +- .../messaging/common/CommonValuePacker.java | 306 ++- .../messaging/common/CommonValueUnpacker.java | 362 ++-- .../messaging/encode/BeginMessageEncoder.java | 17 +- .../encode/CommitMessageEncoder.java | 15 +- .../encode/DiscardAllMessageEncoder.java | 15 +- .../encode/DiscardMessageEncoder.java | 17 +- .../encode/GoodbyeMessageEncoder.java | 15 +- .../messaging/encode/HelloMessageEncoder.java | 17 +- .../encode/PullAllMessageEncoder.java | 15 +- .../messaging/encode/PullMessageEncoder.java | 17 +- .../messaging/encode/ResetMessageEncoder.java | 15 +- .../encode/RollbackMessageEncoder.java | 15 +- .../messaging/encode/RouteMessageEncoder.java | 26 +- .../encode/RouteV44MessageEncoder.java | 43 +- .../encode/RunWithMetadataMessageEncoder.java | 21 +- .../request/AbstractStreamingMessage.java | 47 +- .../messaging/request/BeginMessage.java | 52 +- .../messaging/request/CommitMessage.java | 13 +- .../messaging/request/DiscardAllMessage.java | 15 +- .../messaging/request/DiscardMessage.java | 21 +- .../messaging/request/GoodbyeMessage.java | 15 +- .../messaging/request/HelloMessage.java | 56 +- .../request/MessageWithMetadata.java | 12 +- .../messaging/request/MultiDatabaseUtil.java | 27 +- .../messaging/request/PullAllMessage.java | 13 +- .../messaging/request/PullMessage.java | 16 +- .../messaging/request/ResetMessage.java | 13 +- .../messaging/request/RollbackMessage.java | 13 +- .../messaging/request/RouteMessage.java | 60 +- .../request/RunWithMetadataMessage.java | 85 +- .../request/TransactionMetadataBuilder.java | 70 +- .../messaging/response/FailureMessage.java | 43 +- .../messaging/response/IgnoredMessage.java | 21 +- .../messaging/response/RecordMessage.java | 38 +- .../messaging/response/SuccessMessage.java | 34 +- .../internal/messaging/v3/BoltProtocolV3.java | 147 +- .../messaging/v3/MessageFormatV3.java | 13 +- .../messaging/v3/MessageWriterV3.java | 32 +- .../internal/messaging/v4/BoltProtocolV4.java | 40 +- .../messaging/v4/MessageFormatV4.java | 13 +- .../messaging/v4/MessageWriterV4.java | 32 +- .../messaging/v41/BoltProtocolV41.java | 40 +- .../messaging/v42/BoltProtocolV42.java | 8 +- .../messaging/v43/BoltProtocolV43.java | 11 +- .../messaging/v43/MessageFormatV43.java | 13 +- .../messaging/v43/MessageWriterV43.java | 34 +- .../messaging/v44/BoltProtocolV44.java | 11 +- .../messaging/v44/MessageFormatV44.java | 13 +- .../messaging/v44/MessageWriterV44.java | 34 +- .../ConnectionPoolMetricsListener.java | 16 +- .../metrics/DevNullListenerEvent.java | 10 +- .../metrics/DevNullMetricsListener.java | 59 +- .../metrics/DevNullMetricsProvider.java | 11 +- .../metrics/DevNullPoolMetricsListener.java | 43 +- .../InternalConnectionPoolMetrics.java | 126 +- .../internal/metrics/InternalMetrics.java | 107 +- .../metrics/InternalMetricsProvider.java | 16 +- .../internal/metrics/ListenerEvent.java | 4 +- .../internal/metrics/MetricsListener.java | 29 +- .../internal/metrics/MetricsProvider.java | 3 +- .../MicrometerConnectionPoolMetrics.java | 186 +- .../internal/metrics/MicrometerMetrics.java | 97 +- .../metrics/MicrometerMetricsProvider.java | 25 +- .../metrics/MicrometerTimerListenerEvent.java | 14 +- .../metrics/TimeRecorderListenerEvent.java | 12 +- .../ByteArrayIncompatiblePacker.java | 15 +- .../driver/internal/packstream/PackInput.java | 5 +- .../internal/packstream/PackOutput.java | 15 +- .../internal/packstream/PackStream.java | 663 +++---- .../driver/internal/packstream/PackType.java | 14 +- .../reactive/AbstractRxQueryRunner.java | 32 +- .../internal/reactive/InternalRxResult.java | 137 +- .../internal/reactive/InternalRxSession.java | 188 +- .../reactive/InternalRxTransaction.java | 64 +- .../driver/internal/reactive/RxUtils.java | 64 +- .../retry/ExponentialBackoffRetryLogic.java | 385 ++-- .../driver/internal/retry/RetryLogic.java | 12 +- .../driver/internal/retry/RetrySettings.java | 11 +- .../internal/security/InternalAuthToken.java | 31 +- .../internal/security/SecurityPlan.java | 4 +- .../internal/security/SecurityPlanImpl.java | 169 +- .../neo4j/driver/internal/spi/Connection.java | 33 +- .../driver/internal/spi/ConnectionPool.java | 14 +- .../internal/spi/ConnectionProvider.java | 6 +- .../driver/internal/spi/ResponseHandler.java | 20 +- .../summary/InternalDatabaseInfo.java | 31 +- .../summary/InternalInputPosition.java | 37 +- .../summary/InternalNotification.java | 62 +- .../driver/internal/summary/InternalPlan.java | 124 +- .../summary/InternalProfiledPlan.java | 70 +- .../summary/InternalResultSummary.java | 139 +- .../internal/summary/InternalServerInfo.java | 39 +- .../summary/InternalSummaryCounters.java | 162 +- .../internal/svm/MicrometerSubstitutions.java | 45 +- .../internal/svm/NettySubstitutions.java | 259 ++- .../internal/svm/ZLibSubstitutions.java | 12 +- .../InternalMapAccessorWithDefaultValue.java | 272 +-- .../internal/types/InternalTypeSystem.java | 126 +- .../internal/types/TypeConstructor.java | 59 +- .../internal/types/TypeRepresentation.java | 40 +- .../driver/internal/util/CertificateTool.java | 108 +- .../org/neo4j/driver/internal/util/Clock.java | 16 +- .../neo4j/driver/internal/util/ErrorUtil.java | 180 +- .../neo4j/driver/internal/util/Extract.java | 185 +- .../neo4j/driver/internal/util/Format.java | 44 +- .../neo4j/driver/internal/util/Futures.java | 277 ++- .../neo4j/driver/internal/util/Iterables.java | 119 +- .../neo4j/driver/internal/util/LockUtil.java | 32 +- .../internal/util/MetadataExtractor.java | 220 +-- .../driver/internal/util/Preconditions.java | 24 +- .../neo4j/driver/internal/util/QueryKeys.java | 73 +- .../driver/internal/util/ServerVersion.java | 183 +- .../driver/internal/value/BooleanValue.java | 56 +- .../driver/internal/value/BytesValue.java | 48 +- .../driver/internal/value/DateTimeValue.java | 18 +- .../driver/internal/value/DateValue.java | 15 +- .../driver/internal/value/DurationValue.java | 14 +- .../internal/value/EntityValueAdapter.java | 33 +- .../driver/internal/value/FloatValue.java | 62 +- .../driver/internal/value/IntegerValue.java | 53 +- .../driver/internal/value/InternalValue.java | 5 +- .../driver/internal/value/ListValue.java | 94 +- .../internal/value/LocalDateTimeValue.java | 15 +- .../driver/internal/value/LocalTimeValue.java | 15 +- .../neo4j/driver/internal/value/MapValue.java | 92 +- .../driver/internal/value/NodeValue.java | 14 +- .../driver/internal/value/NullValue.java | 30 +- .../internal/value/NumberValueAdapter.java | 6 +- .../internal/value/ObjectValueAdapter.java | 36 +- .../driver/internal/value/PathValue.java | 18 +- .../driver/internal/value/PointValue.java | 14 +- .../internal/value/RelationshipValue.java | 14 +- .../driver/internal/value/StringValue.java | 46 +- .../driver/internal/value/TimeValue.java | 15 +- .../driver/internal/value/ValueAdapter.java | 312 ++-- .../org/neo4j/driver/net/ServerAddress.java | 8 +- .../driver/net/ServerAddressResolver.java | 5 +- .../neo4j/driver/reactive/RxQueryRunner.java | 12 +- .../org/neo4j/driver/reactive/RxResult.java | 13 +- .../org/neo4j/driver/reactive/RxSession.java | 35 +- .../neo4j/driver/reactive/RxTransaction.java | 6 +- .../driver/reactive/RxTransactionWork.java | 5 +- .../neo4j/driver/summary/DatabaseInfo.java | 3 +- .../neo4j/driver/summary/InputPosition.java | 3 +- .../neo4j/driver/summary/Notification.java | 3 +- .../java/org/neo4j/driver/summary/Plan.java | 6 +- .../neo4j/driver/summary/ProfiledPlan.java | 3 +- .../org/neo4j/driver/summary/QueryType.java | 50 +- .../neo4j/driver/summary/ResultSummary.java | 8 +- .../org/neo4j/driver/summary/ServerInfo.java | 3 +- .../neo4j/driver/summary/SummaryCounters.java | 3 +- .../java/org/neo4j/driver/types/Entity.java | 3 +- .../org/neo4j/driver/types/IsoDuration.java | 4 +- .../org/neo4j/driver/types/MapAccessor.java | 16 +- .../types/MapAccessorWithDefaultValue.java | 38 +- .../java/org/neo4j/driver/types/Node.java | 5 +- .../java/org/neo4j/driver/types/Path.java | 10 +- .../java/org/neo4j/driver/types/Point.java | 3 +- .../org/neo4j/driver/types/Relationship.java | 5 +- .../java/org/neo4j/driver/types/Type.java | 5 +- .../org/neo4j/driver/types/TypeSystem.java | 3 +- .../org/neo4j/driver/util/Experimental.java | 6 +- .../java/org/neo4j/driver/util/Immutable.java | 6 +- .../main/java/org/neo4j/driver/util/Pair.java | 3 +- .../java/org/neo4j/driver/util/Resource.java | 3 +- .../java/org/neo4j/driver/AuthTokensTest.java | 218 +-- .../java/org/neo4j/driver/ConfigTest.java | 505 +++-- .../org/neo4j/driver/GraphDatabaseTest.java | 232 ++- .../java/org/neo4j/driver/ParametersTest.java | 109 +- .../test/java/org/neo4j/driver/QueryTest.java | 88 +- .../org/neo4j/driver/SessionConfigTest.java | 221 ++- .../neo4j/driver/TransactionConfigTest.java | 136 +- .../neo4j/driver/integration/BookmarkIT.java | 191 +- .../integration/ChannelConnectorImplIT.java | 204 +- .../integration/ConnectionHandlingIT.java | 463 +++-- .../driver/integration/ConnectionPoolIT.java | 228 +-- .../driver/integration/CredentialsIT.java | 166 +- .../driver/integration/DirectDriverIT.java | 69 +- .../driver/integration/DriverCloseIT.java | 41 +- .../driver/integration/EncryptionIT.java | 109 +- .../driver/integration/EntityTypeIT.java | 50 +- .../org/neo4j/driver/integration/ErrorIT.java | 306 ++- .../neo4j/driver/integration/LoadCSVIT.java | 370 ++-- .../neo4j/driver/integration/LoggingIT.java | 47 +- .../neo4j/driver/integration/MetricsIT.java | 61 +- .../driver/integration/NestedQueries.java | 131 +- .../driver/integration/NestedQueriesIT.java | 13 +- .../driver/integration/ParametersIT.java | 489 +++-- .../org/neo4j/driver/integration/QueryIT.java | 127 +- .../integration/QueryRunnerCloseIT.java | 147 +- .../neo4j/driver/integration/ResolverIT.java | 41 +- .../driver/integration/ResultStreamIT.java | 212 +-- .../driver/integration/RoutingDriverIT.java | 55 +- .../driver/integration/ScalarTypeIT.java | 253 ++- .../driver/integration/ServerKilledIT.java | 115 +- .../driver/integration/SessionBoltV3IT.java | 377 ++-- .../neo4j/driver/integration/SessionIT.java | 1453 +++++++-------- .../driver/integration/SessionMixIT.java | 246 ++- .../driver/integration/SessionResetIT.java | 772 ++++---- .../driver/integration/SharedEventLoopIT.java | 78 +- .../driver/integration/SpatialTypesIT.java | 145 +- .../neo4j/driver/integration/SummaryIT.java | 228 +-- .../driver/integration/TemporalTypesIT.java | 397 ++-- .../integration/TransactionBoltV3IT.java | 209 +-- .../driver/integration/TransactionIT.java | 491 +++-- .../integration/TrustCustomCertificateIT.java | 69 +- .../integration/UnmanagedTransactionIT.java | 207 +-- .../integration/UnsupportedBoltV3IT.java | 74 +- .../integration/async/AsyncQueryIT.java | 50 +- .../integration/async/AsyncSessionIT.java | 1105 +++++------ .../async/AsyncSessionServerRestartIT.java | 91 +- .../integration/async/AsyncTransactionIT.java | 911 +++++---- .../reactive/RxNestedQueriesIT.java | 177 +- .../integration/reactive/RxResultIT.java | 466 ++--- .../integration/reactive/RxSessionIT.java | 218 +-- .../integration/reactive/RxTransactionIT.java | 1089 ++++++----- .../internal/CustomSecurityPlanTest.java | 64 +- .../driver/internal/DatabaseNameUtilTest.java | 33 +- .../internal/DefaultBookmarkHolderTest.java | 82 +- .../DirectConnectionProviderTest.java | 170 +- .../driver/internal/DriverFactoryTest.java | 328 ++-- .../neo4j/driver/internal/ExtractTest.java | 175 +- .../driver/internal/InternalBookmarkTest.java | 149 +- .../driver/internal/InternalDriverTest.java | 115 +- .../internal/InternalIsoDurationTest.java | 200 +- ...ternalMapAccessorWithDefaultValueTest.java | 316 ++-- .../driver/internal/InternalNodeTest.java | 57 +- .../driver/internal/InternalPairTest.java | 21 +- .../driver/internal/InternalPathTest.java | 145 +- .../driver/internal/InternalRecordTest.java | 196 +- .../internal/InternalRelationshipTest.java | 57 +- .../driver/internal/InternalResultTest.java | 308 ++-- .../internal/InternalTransactionTest.java | 144 +- .../org/neo4j/driver/internal/SchemeTest.java | 94 +- .../driver/internal/SecuritySettingsTest.java | 345 ++-- .../internal/SelfContainedNodeTest.java | 54 +- .../internal/SessionFactoryImplTest.java | 58 +- .../org/neo4j/driver/internal/ValuesTest.java | 574 +++--- .../async/AsyncResultCursorImplTest.java | 443 +++-- .../async/InternalAsyncSessionTest.java | 377 ++-- .../async/InternalAsyncTransactionTest.java | 148 +- .../async/LeakLoggingNetworkSessionTest.java | 119 +- .../internal/async/NetworkConnectionTest.java | 644 ++++--- .../internal/async/NetworkSessionTest.java | 473 +++-- .../async/ResultCursorsHolderTest.java | 140 +- .../async/UnmanagedTransactionTest.java | 581 +++--- .../connection/BoltProtocolUtilTest.java | 77 +- .../connection/ChannelAttributesTest.java | 195 +- .../ChannelConnectedListenerTest.java | 58 +- .../connection/ChannelErrorHandlerTest.java | 136 +- .../ChannelPipelineBuilderImplTest.java | 39 +- .../connection/DecoratedConnectionTest.java | 220 +-- .../connection/DirectConnectionTest.java | 23 +- .../connection/EventLoopGroupFactoryTest.java | 105 +- .../HandshakeCompletedListenerTest.java | 86 +- .../connection/HandshakeHandlerTest.java | 267 ++- .../NettyChannelInitializerTest.java | 153 +- .../connection/RoutingConnectionTest.java | 134 +- .../async/inbound/ByteBufInputTest.java | 98 +- .../async/inbound/ChunkDecoderTest.java | 188 +- .../inbound/ConnectTimeoutHandlerTest.java | 37 +- .../ConnectionReadTimeoutHandlerTest.java | 30 +- .../inbound/InboundMessageDispatcherTest.java | 489 +++-- .../inbound/InboundMessageHandlerTest.java | 137 +- .../async/inbound/MessageDecoderTest.java | 73 +- .../outbound/ChunkAwareByteBufOutputTest.java | 571 +++--- .../outbound/OutboundMessageHandlerTest.java | 125 +- .../async/pool/ConnectionPoolImplIT.java | 138 +- .../async/pool/ConnectionPoolImplTest.java | 177 +- .../pool/NettyChannelHealthCheckerTest.java | 241 ++- .../async/pool/NettyChannelPoolIT.java | 180 +- .../async/pool/NettyChannelTrackerTest.java | 233 ++- .../internal/async/pool/PoolSettingsTest.java | 72 +- .../async/pool/TestConnectionPool.java | 106 +- .../AbstractRoutingProcedureRunnerTest.java | 92 +- .../cluster/ClusterCompositionTest.java | 220 +-- .../cluster/ClusterRoutingTableTest.java | 224 ++- .../cluster/IdentityResolverTest.java | 24 +- ...tiDatabasesRoutingProcedureRunnerTest.java | 120 +- .../internal/cluster/RediscoveryTest.java | 779 ++++---- .../internal/cluster/RediscoveryUtil.java | 19 +- ...outeMessageRoutingProcedureRunnerTest.java | 193 +- .../internal/cluster/RoutingContextTest.java | 150 +- ...ocedureClusterCompositionProviderTest.java | 514 +++--- .../cluster/RoutingProcedureResponseTest.java | 81 +- .../cluster/RoutingTableHandlerTest.java | 329 ++-- .../cluster/RoutingTableRegistryImplTest.java | 212 ++- ...gleDatabaseRoutingProcedureRunnerTest.java | 134 +- ...astConnectedLoadBalancingStrategyTest.java | 198 +- .../loadbalancing/LoadBalancerTest.java | 565 +++--- .../RoundRobinArrayIndexTest.java | 46 +- .../RoutingTableAndConnectionPoolTest.java | 392 ++-- .../AsyncResultCursorOnlyFactoryTest.java | 110 +- .../DisposableAsyncResultCursorTest.java | 103 +- .../cursor/ResultCursorFactoryImplTest.java | 130 +- .../cursor/RxResultCursorImplTest.java | 256 ++- ...nnelReleasingResetResponseHandlerTest.java | 83 +- .../handlers/CommitTxResponseHandlerTest.java | 49 +- .../handlers/HelloResponseHandlerTest.java | 298 ++- .../LegacyPullAllResponseHandlerTest.java | 238 ++- .../handlers/PingResponseHandlerTest.java | 53 +- .../PullAllResponseHandlerTestBase.java | 762 ++++---- .../handlers/ResetResponseHandlerTest.java | 59 +- .../RouteMessageResponseHandlerTest.java | 115 +- .../handlers/RoutingResponseHandlerTest.java | 174 +- .../handlers/RunResponseHandlerTest.java | 231 ++- ...ionPullResponseCompletionListenerTest.java | 121 +- ...ionPullResponseCompletionListenerTest.java | 78 +- .../pulln/AutoPullResponseHandlerTest.java | 200 +- .../BasicPullResponseHandlerTestBase.java | 240 ++- ...ionPullResponseCompletionListenerTest.java | 100 +- ...ionPullResponseCompletionListenerTest.java | 98 +- .../logging/ChannelActivityLoggerTest.java | 50 +- .../internal/logging/ConsoleLoggingTest.java | 80 +- .../internal/logging/PrefixedLoggerTest.java | 199 +- .../internal/logging/Slf4jLoggerTest.java | 93 +- .../internal/logging/Slf4jLoggingTest.java | 22 +- .../internal/messaging/BoltProtocolTest.java | 50 +- .../messaging/BoltProtocolVersionTest.java | 111 +- .../internal/messaging/MessageFormatTest.java | 184 +- .../encode/BeginMessageEncoderTest.java | 85 +- .../encode/CommitMessageEncoderTest.java | 26 +- .../encode/DiscardAllMessageEncoderTest.java | 26 +- .../encode/DiscardMessageEncoderTest.java | 75 +- .../encode/GoodbyeMessageEncoderTest.java | 26 +- .../encode/HelloMessageEncoderTest.java | 74 +- .../encode/PullAllMessageEncoderTest.java | 26 +- .../encode/PullMessageEncoderTest.java | 73 +- .../encode/ResetMessageEncoderTest.java | 28 +- .../encode/RollbackMessageEncoderTest.java | 26 +- .../encode/RouteMessageEncoderTest.java | 73 +- .../RunWithMetadataMessageEncoderTest.java | 85 +- .../messaging/request/HelloMessageTest.java | 78 +- .../TransactionMetadataBuilderTest.java | 114 +- .../messaging/v3/BoltProtocolV3Test.java | 580 +++--- .../messaging/v3/MessageFormatV3Test.java | 26 +- .../messaging/v3/MessageReaderV3Test.java | 96 +- .../messaging/v3/MessageWriterV3Test.java | 153 +- .../messaging/v4/BoltProtocolV4Test.java | 591 +++--- .../messaging/v4/MessageFormatV4Test.java | 26 +- .../messaging/v4/MessageReaderV4Test.java | 96 +- .../messaging/v4/MessageWriterV4Test.java | 165 +- .../messaging/v41/BoltProtocolV41Test.java | 598 +++--- .../messaging/v41/MessageFormatV41Test.java | 26 +- .../messaging/v41/MessageReaderV41Test.java | 96 +- .../messaging/v41/MessageWriterV41Test.java | 165 +- .../messaging/v42/BoltProtocolV42Test.java | 591 +++--- .../messaging/v42/MessageFormatV42Test.java | 26 +- .../messaging/v42/MessageReaderV42Test.java | 96 +- .../messaging/v42/MessageWriterV42Test.java | 165 +- .../messaging/v43/BoltProtocolV43Test.java | 593 +++--- .../messaging/v43/MessageFormatV43Test.java | 26 +- .../messaging/v43/MessageReaderV43Test.java | 96 +- .../messaging/v43/MessageWriterV43Test.java | 176 +- .../messaging/v44/BoltProtocolV44Test.java | 593 +++--- .../messaging/v44/MessageFormatV44Test.java | 26 +- .../messaging/v44/MessageReaderV44Test.java | 96 +- .../messaging/v44/MessageWriterV44Test.java | 176 +- .../MicrometerConnectionPoolMetricsTest.java | 287 +-- .../MicrometerMetricsProviderTest.java | 22 +- .../metrics/MicrometerMetricsTest.java | 174 +- .../MicrometerTimerListenerEventTest.java | 21 +- .../net/BoltServerAddressParsingTest.java | 128 +- .../internal/net/BoltServerAddressTest.java | 131 +- .../internal/packstream/PackStreamTest.java | 621 +++---- .../reactive/InternalRxResultTest.java | 224 ++- .../reactive/InternalRxSessionTest.java | 335 ++-- .../reactive/InternalRxTransactionTest.java | 155 +- .../driver/internal/reactive/RxUtilsTest.java | 61 +- .../reactive/util/ListBasedPullHandler.java | 93 +- .../ExponentialBackoffRetryLogicTest.java | 1638 ++++++++--------- .../summary/InternalInputPositionTest.java | 21 +- .../summary/InternalNotificationTest.java | 79 +- .../internal/summary/InternalPlanTest.java | 82 +- .../summary/InternalProfiledPlanTest.java | 98 +- .../driver/internal/util/BookmarkUtil.java | 78 +- .../internal/util/ClusterCompositionUtil.java | 53 +- .../internal/util/DisabledOnNeo4jWith.java | 12 +- .../internal/util/DriverFactoryWithClock.java | 9 +- .../DriverFactoryWithFixedRetryLogic.java | 16 +- .../internal/util/EnabledOnNeo4jWith.java | 12 +- .../driver/internal/util/ErrorUtilTest.java | 154 +- .../util/FailingConnectionDriverFactory.java | 168 +- .../internal/util/FailingMessageFormat.java | 82 +- .../neo4j/driver/internal/util/FakeClock.java | 72 +- .../driver/internal/util/FixedRetryLogic.java | 21 +- .../driver/internal/util/FuturesTest.java | 327 ++-- .../ImmediateSchedulingEventExecutor.java | 159 +- .../driver/internal/util/IterablesTest.java | 50 +- .../driver/internal/util/MatcherFactory.java | 165 +- .../neo4j/driver/internal/util/Matchers.java | 190 +- .../util/MessageRecordingDriverFactory.java | 55 +- .../internal/util/MetadataExtractorTest.java | 543 +++--- .../driver/internal/util/Neo4jEdition.java | 24 +- .../driver/internal/util/Neo4jFeature.java | 21 +- .../util/Neo4jWithFeatureCondition.java | 121 +- .../internal/util/PreconditionsTest.java | 36 +- .../internal/util/ServerVersionTest.java | 71 +- .../driver/internal/util/SleeplessClock.java | 18 +- .../internal/util/ThrowingConsumer.java | 5 +- .../internal/util/ThrowingMessageEncoder.java | 14 +- .../driver/internal/util/ValueFactory.java | 46 +- .../util/io/BufferedChannelInput.java | 99 +- .../internal/util/io/ByteBufOutput.java | 37 +- .../internal/util/io/ChannelOutput.java | 53 +- ...pelineBuilderWithFailingMessageFormat.java | 19 +- .../util/io/ChannelTrackingConnector.java | 15 +- .../util/io/ChannelTrackingDriverFactory.java | 82 +- ...DriverFactoryWithFailingMessageFormat.java | 34 +- .../util/io/MessageToByteBufWriter.java | 24 +- .../AbstractMessageReaderTestBase.java | 96 +- .../AbstractMessageWriterTestBase.java | 63 +- .../util/messaging/FailureMessageEncoder.java | 21 +- .../util/messaging/IgnoredMessageEncoder.java | 9 +- .../messaging/KnowledgeableMessageFormat.java | 181 +- .../MemorizingInboundMessageDispatcher.java | 39 +- .../util/messaging/RecordMessageEncoder.java | 17 +- .../util/messaging/SuccessMessageEncoder.java | 11 +- .../internal/value/BooleanValueTest.java | 72 +- .../driver/internal/value/BytesValueTest.java | 67 +- .../internal/value/DateTimeValueTest.java | 62 +- .../driver/internal/value/DateValueTest.java | 41 +- .../internal/value/DurationValueTest.java | 53 +- .../driver/internal/value/FloatValueTest.java | 100 +- .../internal/value/IntegerValueTest.java | 112 +- .../driver/internal/value/ListValueTest.java | 29 +- .../value/LocalDateTimeValueTest.java | 49 +- .../internal/value/LocalTimeValueTest.java | 47 +- .../driver/internal/value/MapValueTest.java | 46 +- .../driver/internal/value/NodeValueTest.java | 41 +- .../driver/internal/value/NullValueTest.java | 166 +- .../driver/internal/value/PathValueTest.java | 25 +- .../internal/value/RelationshipValueTest.java | 36 +- .../internal/value/StringValueTest.java | 67 +- .../driver/internal/value/TimeValueTest.java | 49 +- .../neo4j/driver/net/ServerAddressTest.java | 28 +- .../driver/stress/AbstractAsyncQuery.java | 23 +- .../driver/stress/AbstractBlockingQuery.java | 39 +- .../neo4j/driver/stress/AbstractContext.java | 34 +- .../neo4j/driver/stress/AbstractRxQuery.java | 23 +- .../driver/stress/AbstractStressTestBase.java | 696 ++++--- .../org/neo4j/driver/stress/AsyncCommand.java | 5 +- .../driver/stress/AsyncFailingQuery.java | 39 +- .../driver/stress/AsyncFailingQueryInTx.java | 43 +- .../stress/AsyncFailingQueryWithRetries.java | 44 +- .../neo4j/driver/stress/AsyncReadQuery.java | 45 +- .../driver/stress/AsyncReadQueryInTx.java | 42 +- .../stress/AsyncReadQueryWithRetries.java | 48 +- .../neo4j/driver/stress/AsyncWriteQuery.java | 48 +- .../driver/stress/AsyncWriteQueryInTx.java | 52 +- .../stress/AsyncWriteQueryWithRetries.java | 48 +- .../neo4j/driver/stress/AsyncWrongQuery.java | 45 +- .../driver/stress/AsyncWrongQueryInTx.java | 49 +- .../stress/AsyncWrongQueryWithRetries.java | 70 +- .../neo4j/driver/stress/BlockingCommand.java | 5 +- .../driver/stress/BlockingFailingQuery.java | 30 +- .../stress/BlockingFailingQueryInTx.java | 35 +- .../BlockingFailingQueryWithRetries.java | 27 +- .../driver/stress/BlockingReadQuery.java | 36 +- .../driver/stress/BlockingReadQueryInTx.java | 38 +- .../stress/BlockingReadQueryWithRetries.java | 46 +- .../driver/stress/BlockingWriteQuery.java | 34 +- .../driver/stress/BlockingWriteQueryInTx.java | 39 +- ...WriteQueryUsingReadSessionWithRetries.java | 20 +- .../stress/BlockingWriteQueryWithRetries.java | 31 +- .../driver/stress/BlockingWrongQuery.java | 27 +- .../driver/stress/BlockingWrongQueryInTx.java | 31 +- .../stress/BlockingWrongQueryWithRetries.java | 28 +- .../driver/stress/CausalClusteringIT.java | 44 +- .../stress/CausalClusteringStressIT.java | 61 +- .../stress/DumpLogsOnFailureWatcher.java | 25 +- .../org/neo4j/driver/stress/FailedAuth.java | 26 +- .../org/neo4j/driver/stress/RxCommand.java | 5 +- .../neo4j/driver/stress/RxFailingQuery.java | 52 +- .../driver/stress/RxFailingQueryInTx.java | 52 +- .../stress/RxFailingQueryWithRetries.java | 51 +- .../org/neo4j/driver/stress/RxReadQuery.java | 52 +- .../neo4j/driver/stress/RxReadQueryInTx.java | 57 +- .../driver/stress/RxReadQueryWithRetries.java | 56 +- .../org/neo4j/driver/stress/RxWriteQuery.java | 55 +- .../neo4j/driver/stress/RxWriteQueryInTx.java | 78 +- .../stress/RxWriteQueryWithRetries.java | 56 +- .../driver/stress/SessionPoolingStressIT.java | 115 +- .../driver/stress/SingleInstanceStressIT.java | 130 +- .../neo4j/driver/types/TypeSystemTest.java | 286 ++- .../driver/util/CertificateExtension.java | 47 +- .../neo4j/driver/util/CertificateUtil.java | 257 ++- .../driver/util/CertificateUtilTest.java | 42 +- .../driver/util/DaemonThreadFactory.java | 26 +- .../neo4j/driver/util/DatabaseExtension.java | 132 +- .../neo4j/driver/util/DriverExtension.java | 30 +- .../java/org/neo4j/driver/util/FileTools.java | 239 +-- .../org/neo4j/driver/util/FileToolsTest.java | 101 +- .../org/neo4j/driver/util/Neo4jRunner.java | 314 ++-- .../org/neo4j/driver/util/Neo4jSettings.java | 111 +- .../neo4j/driver/util/ParallelizableIT.java | 13 +- .../driver/util/ProcessEnvConfigurator.java | 27 +- .../neo4j/driver/util/SessionExtension.java | 100 +- .../org/neo4j/driver/util/StdIOCapture.java | 31 +- .../org/neo4j/driver/util/TemporalUtil.java | 145 +- .../java/org/neo4j/driver/util/TestUtil.java | 910 ++++----- .../org/neo4j/driver/util/cc/Cluster.java | 323 ++-- .../neo4j/driver/util/cc/ClusterControl.java | 53 +- .../neo4j/driver/util/cc/ClusterDrivers.java | 50 +- .../driver/util/cc/ClusterExtension.java | 117 +- .../neo4j/driver/util/cc/ClusterMember.java | 78 +- .../driver/util/cc/ClusterMemberRole.java | 3 +- .../cc/ClusterMemberRoleDiscoveryFactory.java | 143 +- .../util/cc/ClusterUnavailableException.java | 8 +- .../driver/util/cc/CommandLineException.java | 13 +- .../neo4j/driver/util/cc/CommandLineUtil.java | 118 +- .../cc/LocalOrRemoteClusterExtension.java | 94 +- .../neo4j/driver/util/cc/SharedCluster.java | 131 +- .../AsyncAutocommitTransactionExample.java | 26 +- .../driver/AsyncResultConsumeExample.java | 19 +- .../AsyncRunMultipleTransactionExample.java | 70 +- .../AsyncTransactionFunctionExample.java | 25 +- .../AsyncUnmanagedTransactionExample.java | 54 +- .../driver/AutocommitTransactionExample.java | 20 +- .../neo4j/docs/driver/BaseApplication.java | 11 +- .../neo4j/docs/driver/BasicAuthExample.java | 18 +- .../neo4j/docs/driver/BearerAuthExample.java | 11 +- .../driver/ConfigConnectionPoolExample.java | 26 +- .../ConfigConnectionTimeoutExample.java | 21 +- .../driver/ConfigCustomResolverExample.java | 57 +- .../driver/ConfigMaxRetryTimeExample.java | 22 +- .../neo4j/docs/driver/ConfigTrustExample.java | 13 +- .../docs/driver/ConfigUnencryptedExample.java | 15 +- .../neo4j/docs/driver/CustomAuthExample.java | 19 +- .../neo4j/docs/driver/CypherErrorExample.java | 48 +- .../docs/driver/DatabaseSelectionExample.java | 29 +- .../driver/DriverIntroductionExample.java | 47 +- .../docs/driver/DriverLifecycleExample.java | 11 +- .../neo4j/docs/driver/HelloWorldExample.java | 48 +- .../driver/HostnameVerificationExample.java | 26 +- .../docs/driver/KerberosAuthExample.java | 11 +- .../docs/driver/PassBookmarkExample.java | 101 +- .../driver/ReadWriteTransactionExample.java | 36 +- .../docs/driver/ReadingValuesExample.java | 122 +- .../docs/driver/ResultConsumeExample.java | 26 +- .../docs/driver/ResultRetainExample.java | 57 +- .../RxAutocommitTransactionExample.java | 38 +- .../docs/driver/RxResultConsumeExample.java | 50 +- .../driver/RxTransactionFunctionExample.java | 55 +- .../driver/RxUnmanagedTransactionExample.java | 72 +- .../driver/ServiceUnavailableExample.java | 40 +- .../org/neo4j/docs/driver/SessionExample.java | 20 +- .../docs/driver/Slf4jLoggingExample.java | 30 +- .../driver/TransactionFunctionExample.java | 25 +- .../TransactionMetadataConfigExample.java | 40 +- .../TransactionTimeoutConfigExample.java | 33 +- .../org/neo4j/docs/driver/ExamplesIT.java | 681 +++---- .../neo4j/docs/driver/RoutingExamplesIT.java | 21 +- pom.xml | 53 + .../neo4j/org/testkit/backend/Runner.java | 52 +- .../testkit/backend/RxBufferedSubscriber.java | 187 +- .../org/testkit/backend/TestkitState.java | 197 +- .../handler/TestkitMessageInboundHandler.java | 47 +- .../TestkitMessageOutboundHandler.java | 13 +- .../TestkitRequestProcessorHandler.java | 183 +- .../TestkitRequestResponseMapperHandler.java | 33 +- .../backend/holder/AbstractResultHolder.java | 25 +- .../backend/holder/AbstractSessionHolder.java | 8 +- .../holder/AbstractTransactionHolder.java | 3 +- .../backend/holder/AsyncSessionHolder.java | 8 +- .../holder/AsyncTransactionHolder.java | 8 +- .../testkit/backend/holder/DriverHolder.java | 4 +- .../backend/holder/ResultCursorHolder.java | 16 +- .../testkit/backend/holder/ResultHolder.java | 16 +- .../backend/holder/RxResultHolder.java | 28 +- .../backend/holder/RxSessionHolder.java | 8 +- .../backend/holder/RxTransactionHolder.java | 8 +- .../testkit/backend/holder/SessionHolder.java | 8 +- .../backend/holder/TransactionHolder.java | 8 +- .../backend/messages/TestkitModule.java | 28 +- .../messages/requests/AuthorizationToken.java | 15 +- .../requests/CheckDriverIsEncrypted.java | 37 +- .../requests/CheckMultiDBSupport.java | 44 +- .../DomainNameResolutionCompleted.java | 12 +- .../messages/requests/DriverClose.java | 38 +- .../requests/GetConnectionPoolMetrics.java | 92 +- .../messages/requests/GetFeatures.java | 59 +- .../messages/requests/GetRoutingTable.java | 80 +- .../backend/messages/requests/NewDriver.java | 333 ++-- .../backend/messages/requests/NewSession.java | 96 +- .../requests/ResolverResolutionCompleted.java | 12 +- .../messages/requests/ResultConsume.java | 254 ++- .../backend/messages/requests/ResultList.java | 46 +- .../backend/messages/requests/ResultNext.java | 105 +- .../backend/messages/requests/ResultPeek.java | 57 +- .../messages/requests/RetryableNegative.java | 85 +- .../messages/requests/RetryablePositive.java | 47 +- .../requests/SessionBeginTransaction.java | 98 +- .../messages/requests/SessionClose.java | 42 +- .../requests/SessionLastBookmarks.java | 46 +- .../requests/SessionReadTransaction.java | 130 +- .../backend/messages/requests/SessionRun.java | 126 +- .../requests/SessionWriteTransaction.java | 136 +- .../backend/messages/requests/StartTest.java | 183 +- .../requests/TestkitCallbackResult.java | 25 +- .../messages/requests/TestkitRequest.java | 46 +- .../messages/requests/TransactionClose.java | 50 +- .../messages/requests/TransactionCommit.java | 42 +- .../requests/TransactionRollback.java | 42 +- .../messages/requests/TransactionRun.java | 89 +- .../messages/requests/VerifyConnectivity.java | 38 +- .../TestkitCypherParamDeserializer.java | 72 +- .../deserializer/TestkitListDeserializer.java | 62 +- .../messages/responses/BackendError.java | 9 +- .../backend/messages/responses/Bookmarks.java | 10 +- .../responses/ConnectionPoolMetrics.java | 9 +- .../DomainNameResolutionRequired.java | 12 +- .../backend/messages/responses/Driver.java | 9 +- .../messages/responses/DriverError.java | 9 +- .../messages/responses/DriverIsEncrypted.java | 9 +- .../messages/responses/FeatureList.java | 12 +- .../messages/responses/MultiDBSupport.java | 9 +- .../messages/responses/NullRecord.java | 6 +- .../backend/messages/responses/Record.java | 9 +- .../messages/responses/RecordList.java | 12 +- .../responses/ResolverResolutionRequired.java | 12 +- .../backend/messages/responses/Result.java | 12 +- .../messages/responses/RetryableDone.java | 6 +- .../messages/responses/RetryableTry.java | 9 +- .../messages/responses/RoutingTable.java | 12 +- .../backend/messages/responses/RunTest.java | 6 +- .../backend/messages/responses/Session.java | 9 +- .../backend/messages/responses/SkipTest.java | 9 +- .../backend/messages/responses/Summary.java | 40 +- .../messages/responses/TestkitCallback.java | 3 +- .../messages/responses/TestkitResponse.java | 5 +- .../messages/responses/Transaction.java | 9 +- .../responses/serializer/GenUtils.java | 82 +- .../serializer/TestkitBookmarkSerializer.java | 18 +- .../TestkitListValueSerializer.java | 27 +- .../serializer/TestkitMapValueSerializer.java | 38 +- .../TestkitNodeValueSerializer.java | 36 +- .../TestkitPathValueSerializer.java | 39 +- .../serializer/TestkitRecordSerializer.java | 19 +- .../TestkitRelationshipValueSerializer.java | 33 +- .../serializer/TestkitValueSerializer.java | 39 +- .../backend/MessageDeserializerTest.java | 63 +- .../backend/MessageSerializerTest.java | 20 +- 854 files changed, 37910 insertions(+), 46413 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..e8fb896e6d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.java eol=lf +*.xml eol=lf + diff --git a/driver/src/main/java/org/neo4j/driver/AccessMode.java b/driver/src/main/java/org/neo4j/driver/AccessMode.java index b4ea8ab177..3a3900d7e7 100644 --- a/driver/src/main/java/org/neo4j/driver/AccessMode.java +++ b/driver/src/main/java/org/neo4j/driver/AccessMode.java @@ -27,8 +27,7 @@ * While any {@link AccessMode} will be ignored while running transactions via a driver towards a single server. * As the single server serves both read and write operations at the same time. */ -public enum AccessMode -{ +public enum AccessMode { /** * Use this for transactions that requires a read server in a cluster */ diff --git a/driver/src/main/java/org/neo4j/driver/AuthToken.java b/driver/src/main/java/org/neo4j/driver/AuthToken.java index a5ba74c7d0..38232ba1be 100644 --- a/driver/src/main/java/org/neo4j/driver/AuthToken.java +++ b/driver/src/main/java/org/neo4j/driver/AuthToken.java @@ -27,7 +27,4 @@ * @see GraphDatabase#driver(String, AuthToken) * @since 1.0 */ -public interface AuthToken -{ - -} +public interface AuthToken {} diff --git a/driver/src/main/java/org/neo4j/driver/AuthTokens.java b/driver/src/main/java/org/neo4j/driver/AuthTokens.java index 9d49a45784..66cb0f5841 100644 --- a/driver/src/main/java/org/neo4j/driver/AuthTokens.java +++ b/driver/src/main/java/org/neo4j/driver/AuthTokens.java @@ -18,11 +18,6 @@ */ package org.neo4j.driver; -import java.util.Map; -import java.util.Objects; - -import org.neo4j.driver.internal.security.InternalAuthToken; - import static java.util.Collections.singletonMap; import static org.neo4j.driver.Values.value; import static org.neo4j.driver.internal.security.InternalAuthToken.CREDENTIALS_KEY; @@ -32,6 +27,10 @@ import static org.neo4j.driver.internal.security.InternalAuthToken.SCHEME_KEY; import static org.neo4j.driver.internal.util.Iterables.newHashMapWithSize; +import java.util.Map; +import java.util.Objects; +import org.neo4j.driver.internal.security.InternalAuthToken; + /** * This is a listing of the various methods of authentication supported by this * driver. The scheme used must be supported by the Neo4j Instance you are connecting @@ -39,8 +38,7 @@ * @see GraphDatabase#driver(String, AuthToken) * @since 1.0 */ -public class AuthTokens -{ +public class AuthTokens { /** * The basic authentication scheme, using a username and a password. * @param username this is the "principal", identifying who this token represents @@ -49,9 +47,8 @@ public class AuthTokens * @see GraphDatabase#driver(String, AuthToken) * @throws NullPointerException when either username or password is {@code null} */ - public static AuthToken basic( String username, String password ) - { - return basic( username, password, null ); + public static AuthToken basic(String username, String password) { + return basic(username, password, null); } /** @@ -63,20 +60,18 @@ public static AuthToken basic( String username, String password ) * @see GraphDatabase#driver(String, AuthToken) * @throws NullPointerException when either username or password is {@code null} */ - public static AuthToken basic( String username, String password, String realm ) - { - Objects.requireNonNull( username, "Username can't be null" ); - Objects.requireNonNull( password, "Password can't be null" ); + public static AuthToken basic(String username, String password, String realm) { + Objects.requireNonNull(username, "Username can't be null"); + Objects.requireNonNull(password, "Password can't be null"); - Map map = newHashMapWithSize( 4 ); - map.put( SCHEME_KEY, value( "basic" ) ); - map.put( PRINCIPAL_KEY, value( username ) ); - map.put( CREDENTIALS_KEY, value( password ) ); - if ( realm != null ) - { - map.put( REALM_KEY, value( realm ) ); + Map map = newHashMapWithSize(4); + map.put(SCHEME_KEY, value("basic")); + map.put(PRINCIPAL_KEY, value(username)); + map.put(CREDENTIALS_KEY, value(password)); + if (realm != null) { + map.put(REALM_KEY, value(realm)); } - return new InternalAuthToken( map ); + return new InternalAuthToken(map); } /** @@ -87,14 +82,13 @@ public static AuthToken basic( String username, String password, String realm ) * @throws NullPointerException when token is {@code null} * @see GraphDatabase#driver(String, AuthToken) */ - public static AuthToken bearer( String token ) - { - Objects.requireNonNull( token, "Token can't be null" ); + public static AuthToken bearer(String token) { + Objects.requireNonNull(token, "Token can't be null"); - Map map = newHashMapWithSize( 2 ); - map.put( SCHEME_KEY, value( "bearer" ) ); - map.put( CREDENTIALS_KEY, value( token ) ); - return new InternalAuthToken( map ); + Map map = newHashMapWithSize(2); + map.put(SCHEME_KEY, value("bearer")); + map.put(CREDENTIALS_KEY, value(token)); + return new InternalAuthToken(map); } /** @@ -106,15 +100,14 @@ public static AuthToken bearer( String token ) * @see GraphDatabase#driver(String, AuthToken) * @since 1.3 */ - public static AuthToken kerberos( String base64EncodedTicket ) - { - Objects.requireNonNull( base64EncodedTicket, "Ticket can't be null" ); + public static AuthToken kerberos(String base64EncodedTicket) { + Objects.requireNonNull(base64EncodedTicket, "Ticket can't be null"); - Map map = newHashMapWithSize( 3 ); - map.put( SCHEME_KEY, value( "kerberos" ) ); - map.put( PRINCIPAL_KEY, value( "" ) ); // This empty string is required for backwards compatibility. - map.put( CREDENTIALS_KEY, value( base64EncodedTicket ) ); - return new InternalAuthToken( map ); + Map map = newHashMapWithSize(3); + map.put(SCHEME_KEY, value("kerberos")); + map.put(PRINCIPAL_KEY, value("")); // This empty string is required for backwards compatibility. + map.put(CREDENTIALS_KEY, value(base64EncodedTicket)); + return new InternalAuthToken(map); } /** @@ -127,9 +120,8 @@ public static AuthToken kerberos( String base64EncodedTicket ) * @see GraphDatabase#driver(String, AuthToken) * @throws NullPointerException when either principal, credentials or scheme is {@code null} */ - public static AuthToken custom( String principal, String credentials, String realm, String scheme) - { - return custom( principal, credentials, realm, scheme, null ); + public static AuthToken custom(String principal, String credentials, String realm, String scheme) { + return custom(principal, credentials, realm, scheme, null); } /** @@ -143,25 +135,23 @@ public static AuthToken custom( String principal, String credentials, String rea * @see GraphDatabase#driver(String, AuthToken) * @throws NullPointerException when either principal, credentials or scheme is {@code null} */ - public static AuthToken custom( String principal, String credentials, String realm, String scheme, Map parameters) - { - Objects.requireNonNull( principal, "Principal can't be null" ); - Objects.requireNonNull( credentials, "Credentials can't be null" ); - Objects.requireNonNull( scheme, "Scheme can't be null" ); + public static AuthToken custom( + String principal, String credentials, String realm, String scheme, Map parameters) { + Objects.requireNonNull(principal, "Principal can't be null"); + Objects.requireNonNull(credentials, "Credentials can't be null"); + Objects.requireNonNull(scheme, "Scheme can't be null"); - Map map = newHashMapWithSize( 5 ); - map.put( SCHEME_KEY, value( scheme ) ); - map.put( PRINCIPAL_KEY, value( principal ) ); - map.put( CREDENTIALS_KEY, value( credentials ) ); - if ( realm != null ) - { - map.put( REALM_KEY, value( realm ) ); + Map map = newHashMapWithSize(5); + map.put(SCHEME_KEY, value(scheme)); + map.put(PRINCIPAL_KEY, value(principal)); + map.put(CREDENTIALS_KEY, value(credentials)); + if (realm != null) { + map.put(REALM_KEY, value(realm)); } - if ( parameters != null ) - { - map.put( PARAMETERS_KEY, value( parameters ) ); + if (parameters != null) { + map.put(PARAMETERS_KEY, value(parameters)); } - return new InternalAuthToken( map ); + return new InternalAuthToken(map); } /** @@ -170,8 +160,7 @@ public static AuthToken custom( String principal, String credentials, String rea * @return an authentication token that can be used to connect to Neo4j instances with auth disabled * @see GraphDatabase#driver(String, AuthToken) */ - public static AuthToken none() - { - return new InternalAuthToken( singletonMap( SCHEME_KEY, value( "none" ) ) ); + public static AuthToken none() { + return new InternalAuthToken(singletonMap(SCHEME_KEY, value("none"))); } } diff --git a/driver/src/main/java/org/neo4j/driver/Bookmark.java b/driver/src/main/java/org/neo4j/driver/Bookmark.java index 65c91e39a9..f3774e497c 100644 --- a/driver/src/main/java/org/neo4j/driver/Bookmark.java +++ b/driver/src/main/java/org/neo4j/driver/Bookmark.java @@ -19,7 +19,6 @@ package org.neo4j.driver; import java.util.Set; - import org.neo4j.driver.internal.InternalBookmark; /** @@ -33,8 +32,7 @@ * * To opt out of this mechanism for unrelated units of work, applications can use multiple sessions. */ -public interface Bookmark -{ +public interface Bookmark { /** * Returns a read-only set of bookmark strings that this bookmark instance identifies. * @return a read-only set of bookmark strings that this bookmark instance identifies. @@ -46,9 +44,8 @@ public interface Bookmark * @param values values obtained from a previous bookmark. * @return A bookmark. */ - static Bookmark from( Set values ) - { - return InternalBookmark.parse( values ); + static Bookmark from(Set values) { + return InternalBookmark.parse(values); } /** diff --git a/driver/src/main/java/org/neo4j/driver/Config.java b/driver/src/main/java/org/neo4j/driver/Config.java index bd9e058544..4f8626643e 100644 --- a/driver/src/main/java/org/neo4j/driver/Config.java +++ b/driver/src/main/java/org/neo4j/driver/Config.java @@ -18,6 +18,9 @@ */ package org.neo4j.driver; +import static java.lang.String.format; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; + import java.io.File; import java.io.Serializable; import java.net.InetAddress; @@ -28,7 +31,6 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.logging.Level; - import org.neo4j.driver.internal.RevocationStrategy; import org.neo4j.driver.internal.SecuritySettings; import org.neo4j.driver.internal.async.pool.PoolSettings; @@ -39,9 +41,6 @@ import org.neo4j.driver.util.Experimental; import org.neo4j.driver.util.Immutable; -import static java.lang.String.format; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; - /** * A configuration class to config driver properties. *

@@ -70,14 +69,14 @@ * @since 1.0 */ @Immutable -public class Config implements Serializable -{ +public class Config implements Serializable { private static final long serialVersionUID = -4496545746399601108L; private static final Config EMPTY = builder().build(); /** User defined logging */ private final Logging logging; + private final boolean logLeakedSessions; private final int maxConnectionPoolSize; @@ -101,8 +100,7 @@ public class Config implements Serializable private final String userAgent; private final MetricsAdapter metricsAdapter; - private Config( ConfigBuilder builder ) - { + private Config(ConfigBuilder builder) { this.logging = builder.logging; this.logLeakedSessions = builder.logLeakedSessions; @@ -130,8 +128,7 @@ private Config( ConfigBuilder builder ) * Logging provider * @return the Logging provider to use */ - public Logging logging() - { + public Logging logging() { return logging; } @@ -140,8 +137,7 @@ public Logging logging() * * @return {@code true} if enabled, {@code false} otherwise. */ - public boolean logLeakedSessions() - { + public boolean logLeakedSessions() { return logLeakedSessions; } @@ -151,8 +147,7 @@ public boolean logLeakedSessions() * * @return idle time in milliseconds */ - public long idleTimeBeforeConnectionTest() - { + public long idleTimeBeforeConnectionTest() { return idleTimeBeforeConnectionTest; } @@ -161,42 +156,36 @@ public long idleTimeBeforeConnectionTest() * * @return maximum lifetime in milliseconds */ - public long maxConnectionLifetimeMillis() - { + public long maxConnectionLifetimeMillis() { return maxConnectionLifetimeMillis; } /** * @return the configured connection timeout value in milliseconds. */ - public int connectionTimeoutMillis() - { + public int connectionTimeoutMillis() { return connectionTimeoutMillis; } - public int maxConnectionPoolSize() - { + public int maxConnectionPoolSize() { return maxConnectionPoolSize; } - public long connectionAcquisitionTimeoutMillis() - { + public long connectionAcquisitionTimeoutMillis() { return connectionAcquisitionTimeoutMillis; } /** * @return indicator for encrypted communication. */ - public boolean encrypted() - { + public boolean encrypted() { return securitySettings.encrypted(); } /** * @return the strategy to use to determine the authenticity of an encryption certificate provided by the Neo4j instance we are connecting to. */ - public TrustStrategy trustStrategy() - { + public TrustStrategy trustStrategy() { return securitySettings.trustStrategy(); } @@ -205,8 +194,7 @@ public TrustStrategy trustStrategy() * * @return the resolver to use. */ - public ServerAddressResolver resolver() - { + public ServerAddressResolver resolver() { return resolver; } @@ -215,85 +203,75 @@ public ServerAddressResolver resolver() * * @return a new {@link ConfigBuilder} instance. */ - public static ConfigBuilder builder() - { + public static ConfigBuilder builder() { return new ConfigBuilder(); } /** * @return A config with all default settings */ - public static Config defaultConfig() - { + public static Config defaultConfig() { return EMPTY; } /** * @return the security setting to use when creating connections. */ - SecuritySettings securitySettings() - { + SecuritySettings securitySettings() { return securitySettings; } - RoutingSettings routingSettings() - { - return new RoutingSettings( routingFailureLimit, routingRetryDelayMillis, routingTablePurgeDelayMillis ); + RoutingSettings routingSettings() { + return new RoutingSettings(routingFailureLimit, routingRetryDelayMillis, routingTablePurgeDelayMillis); } - RetrySettings retrySettings() - { + RetrySettings retrySettings() { return retrySettings; } - public long fetchSize() - { + public long fetchSize() { return fetchSize; } - public int eventLoopThreads() - { + public int eventLoopThreads() { return eventLoopThreads; } /** * @return if the metrics is enabled or not on this driver. */ - public boolean isMetricsEnabled() - { + public boolean isMetricsEnabled() { return this.metricsAdapter != MetricsAdapter.DEV_NULL; } - public MetricsAdapter metricsAdapter() - { + public MetricsAdapter metricsAdapter() { return this.metricsAdapter; } /** * @return the user_agent configured for this driver */ - public String userAgent() - { + public String userAgent() { return userAgent; } /** * Used to build new config instances */ - public static class ConfigBuilder - { + public static class ConfigBuilder { private Logging logging = DEV_NULL_LOGGING; private boolean logLeakedSessions; private int maxConnectionPoolSize = PoolSettings.DEFAULT_MAX_CONNECTION_POOL_SIZE; private long idleTimeBeforeConnectionTest = PoolSettings.DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST; private long maxConnectionLifetimeMillis = PoolSettings.DEFAULT_MAX_CONNECTION_LIFETIME; private long connectionAcquisitionTimeoutMillis = PoolSettings.DEFAULT_CONNECTION_ACQUISITION_TIMEOUT; - private String userAgent = format( "neo4j-java/%s", driverVersion() ); - private final SecuritySettings.SecuritySettingsBuilder securitySettingsBuilder = new SecuritySettings.SecuritySettingsBuilder(); + private String userAgent = format("neo4j-java/%s", driverVersion()); + private final SecuritySettings.SecuritySettingsBuilder securitySettingsBuilder = + new SecuritySettings.SecuritySettingsBuilder(); private int routingFailureLimit = RoutingSettings.DEFAULT.maxRoutingFailures(); private long routingRetryDelayMillis = RoutingSettings.DEFAULT.retryTimeoutDelay(); private long routingTablePurgeDelayMillis = RoutingSettings.DEFAULT.routingTablePurgeDelayMs(); - private int connectionTimeoutMillis = (int) TimeUnit.SECONDS.toMillis( 30 ); + private int connectionTimeoutMillis = (int) TimeUnit.SECONDS.toMillis(30); private RetrySettings retrySettings = RetrySettings.DEFAULT; private ServerAddressResolver resolver; private MetricsAdapter metricsAdapter = MetricsAdapter.DEV_NULL; @@ -313,8 +291,7 @@ private ConfigBuilder() {} * @return this builder * @see Logging */ - public ConfigBuilder withLogging( Logging logging ) - { + public ConfigBuilder withLogging(Logging logging) { this.logging = logging; return this; } @@ -334,8 +311,7 @@ public ConfigBuilder withLogging( Logging logging ) * * @return this builder */ - public ConfigBuilder withLeakedSessionsLogging() - { + public ConfigBuilder withLeakedSessionsLogging() { this.logLeakedSessions = true; return this; } @@ -363,9 +339,8 @@ public ConfigBuilder withLeakedSessionsLogging() * @param unit the unit in which the duration is given * @return this builder */ - public ConfigBuilder withConnectionLivenessCheckTimeout( long value, TimeUnit unit ) - { - this.idleTimeBeforeConnectionTest = unit.toMillis( value ); + public ConfigBuilder withConnectionLivenessCheckTimeout(long value, TimeUnit unit) { + this.idleTimeBeforeConnectionTest = unit.toMillis(value); return this; } @@ -389,9 +364,8 @@ public ConfigBuilder withConnectionLivenessCheckTimeout( long value, TimeUnit un * @param unit the unit in which the duration is given * @return this builder */ - public ConfigBuilder withMaxConnectionLifetime( long value, TimeUnit unit ) - { - this.maxConnectionLifetimeMillis = unit.toMillis( value ); + public ConfigBuilder withMaxConnectionLifetime(long value, TimeUnit unit) { + this.maxConnectionLifetimeMillis = unit.toMillis(value); return this; } @@ -411,18 +385,12 @@ public ConfigBuilder withMaxConnectionLifetime( long value, TimeUnit unit ) * @return this builder * @see #withConnectionAcquisitionTimeout(long, TimeUnit) */ - public ConfigBuilder withMaxConnectionPoolSize( int value ) - { - if ( value == 0 ) - { - throw new IllegalArgumentException( "Zero value is not supported" ); - } - else if ( value < 0 ) - { + public ConfigBuilder withMaxConnectionPoolSize(int value) { + if (value == 0) { + throw new IllegalArgumentException("Zero value is not supported"); + } else if (value < 0) { this.maxConnectionPoolSize = Integer.MAX_VALUE; - } - else - { + } else { this.maxConnectionPoolSize = value; } return this; @@ -443,15 +411,11 @@ else if ( value < 0 ) * @return this builder * @see #withMaxConnectionPoolSize(int) */ - public ConfigBuilder withConnectionAcquisitionTimeout( long value, TimeUnit unit ) - { - long valueInMillis = unit.toMillis( value ); - if ( value >= 0 ) - { + public ConfigBuilder withConnectionAcquisitionTimeout(long value, TimeUnit unit) { + long valueInMillis = unit.toMillis(value); + if (value >= 0) { this.connectionAcquisitionTimeoutMillis = valueInMillis; - } - else - { + } else { this.connectionAcquisitionTimeoutMillis = -1; } return this; @@ -461,8 +425,7 @@ public ConfigBuilder withConnectionAcquisitionTimeout( long value, TimeUnit unit * Set to use encrypted traffic. * @return this builder */ - public ConfigBuilder withEncryption() - { + public ConfigBuilder withEncryption() { securitySettingsBuilder.withEncryption(); return this; } @@ -471,8 +434,7 @@ public ConfigBuilder withEncryption() * Set to use unencrypted traffic. * @return this builder */ - public ConfigBuilder withoutEncryption() - { + public ConfigBuilder withoutEncryption() { securitySettingsBuilder.withoutEncryption(); return this; } @@ -491,9 +453,8 @@ public ConfigBuilder withoutEncryption() * @param trustStrategy TLS authentication strategy * @return this builder */ - public ConfigBuilder withTrustStrategy( TrustStrategy trustStrategy ) - { - securitySettingsBuilder.withTrustStrategy( trustStrategy ); + public ConfigBuilder withTrustStrategy(TrustStrategy trustStrategy) { + securitySettingsBuilder.withTrustStrategy(trustStrategy); return this; } @@ -523,12 +484,10 @@ public ConfigBuilder withTrustStrategy( TrustStrategy trustStrategy ) * Method will be removed in the next major release. */ @Deprecated - public ConfigBuilder withRoutingFailureLimit( int routingFailureLimit ) - { - if ( routingFailureLimit < 1 ) - { + public ConfigBuilder withRoutingFailureLimit(int routingFailureLimit) { + if (routingFailureLimit < 1) { throw new IllegalArgumentException( - "The failure limit may not be smaller than 1, but was: " + routingFailureLimit ); + "The failure limit may not be smaller than 1, but was: " + routingFailureLimit); } this.routingFailureLimit = routingFailureLimit; return this; @@ -565,13 +524,11 @@ public ConfigBuilder withRoutingFailureLimit( int routingFailureLimit ) * Method will be removed in the next major release. */ @Deprecated - public ConfigBuilder withRoutingRetryDelay( long delay, TimeUnit unit ) - { - long routingRetryDelayMillis = unit.toMillis( delay ); - if ( routingRetryDelayMillis < 0 ) - { - throw new IllegalArgumentException( String.format( - "The retry delay may not be smaller than 0, but was %d %s.", delay, unit ) ); + public ConfigBuilder withRoutingRetryDelay(long delay, TimeUnit unit) { + long routingRetryDelayMillis = unit.toMillis(delay); + if (routingRetryDelayMillis < 0) { + throw new IllegalArgumentException( + String.format("The retry delay may not be smaller than 0, but was %d %s.", delay, unit)); } this.routingRetryDelayMillis = routingRetryDelayMillis; return this; @@ -594,13 +551,11 @@ public ConfigBuilder withRoutingRetryDelay( long delay, TimeUnit unit ) * the unit in which the duration is given * @return this builder */ - public ConfigBuilder withRoutingTablePurgeDelay( long delay, TimeUnit unit ) - { - long routingTablePurgeDelayMillis = unit.toMillis( delay ); - if ( routingTablePurgeDelayMillis < 0 ) - { - throw new IllegalArgumentException( String.format( - "The routing table purge delay may not be smaller than 0, but was %d %s.", delay, unit ) ); + public ConfigBuilder withRoutingTablePurgeDelay(long delay, TimeUnit unit) { + long routingTablePurgeDelayMillis = unit.toMillis(delay); + if (routingTablePurgeDelayMillis < 0) { + throw new IllegalArgumentException(String.format( + "The routing table purge delay may not be smaller than 0, but was %d %s.", delay, unit)); } this.routingTablePurgeDelayMillis = routingTablePurgeDelayMillis; return this; @@ -621,9 +576,8 @@ public ConfigBuilder withRoutingTablePurgeDelay( long delay, TimeUnit unit ) * @param size the default record fetch size when pulling records in batches using Bolt V4. * @return this builder */ - public ConfigBuilder withFetchSize( long size ) - { - this.fetchSize = FetchSizeUtil.assertValidFetchSize( size ); + public ConfigBuilder withFetchSize(long size) { + this.fetchSize = FetchSizeUtil.assertValidFetchSize(size); return this; } @@ -644,20 +598,17 @@ public ConfigBuilder withFetchSize( long size ) * @throws IllegalArgumentException when given value is negative or does not fit in {@code int} when * converted to milliseconds. */ - public ConfigBuilder withConnectionTimeout( long value, TimeUnit unit ) - { - long connectionTimeoutMillis = unit.toMillis( value ); - if ( connectionTimeoutMillis < 0 ) - { - throw new IllegalArgumentException( String.format( - "The connection timeout may not be smaller than 0, but was %d %s.", value, unit ) ); + public ConfigBuilder withConnectionTimeout(long value, TimeUnit unit) { + long connectionTimeoutMillis = unit.toMillis(value); + if (connectionTimeoutMillis < 0) { + throw new IllegalArgumentException( + String.format("The connection timeout may not be smaller than 0, but was %d %s.", value, unit)); } int connectionTimeoutMillisInt = (int) connectionTimeoutMillis; - if ( connectionTimeoutMillisInt != connectionTimeoutMillis ) - { - throw new IllegalArgumentException( String.format( + if (connectionTimeoutMillisInt != connectionTimeoutMillis) { + throw new IllegalArgumentException(String.format( "The connection timeout must represent int value when converted to milliseconds %d.", - connectionTimeoutMillis ) ); + connectionTimeoutMillis)); } this.connectionTimeoutMillis = connectionTimeoutMillisInt; return this; @@ -677,15 +628,13 @@ public ConfigBuilder withConnectionTimeout( long value, TimeUnit unit ) * @return this builder * @throws IllegalArgumentException when given value is negative */ - public ConfigBuilder withMaxTransactionRetryTime( long value, TimeUnit unit ) - { - long maxRetryTimeMs = unit.toMillis( value ); - if ( maxRetryTimeMs < 0 ) - { - throw new IllegalArgumentException( String.format( - "The max retry time may not be smaller than 0, but was %d %s.", value, unit ) ); + public ConfigBuilder withMaxTransactionRetryTime(long value, TimeUnit unit) { + long maxRetryTimeMs = unit.toMillis(value); + if (maxRetryTimeMs < 0) { + throw new IllegalArgumentException( + String.format("The max retry time may not be smaller than 0, but was %d %s.", value, unit)); } - this.retrySettings = new RetrySettings( maxRetryTimeMs ); + this.retrySettings = new RetrySettings(maxRetryTimeMs); return this; } @@ -702,9 +651,8 @@ public ConfigBuilder withMaxTransactionRetryTime( long value, TimeUnit unit ) * @return this builder. * @throws NullPointerException when the given resolver is {@code null}. */ - public ConfigBuilder withResolver( ServerAddressResolver resolver ) - { - this.resolver = Objects.requireNonNull( resolver, "resolver" ); + public ConfigBuilder withResolver(ServerAddressResolver resolver) { + this.resolver = Objects.requireNonNull(resolver, "resolver"); return this; } @@ -713,29 +661,23 @@ public ConfigBuilder withResolver( ServerAddressResolver resolver ) * * @return this builder. */ - public ConfigBuilder withDriverMetrics() - { - return withMetricsEnabled( true ); + public ConfigBuilder withDriverMetrics() { + return withMetricsEnabled(true); } /** * Disable driver metrics. When disabled, driver metrics cannot be accessed via {@link Driver#metrics()}. * @return this builder. */ - public ConfigBuilder withoutDriverMetrics() - { - return withMetricsEnabled( false ); + public ConfigBuilder withoutDriverMetrics() { + return withMetricsEnabled(false); } - private ConfigBuilder withMetricsEnabled( boolean enabled ) - { - if ( !enabled ) - { - withMetricsAdapter( MetricsAdapter.DEV_NULL ); - } - else if ( this.metricsAdapter == null || this.metricsAdapter == MetricsAdapter.DEV_NULL ) - { - withMetricsAdapter( MetricsAdapter.DEFAULT ); + private ConfigBuilder withMetricsEnabled(boolean enabled) { + if (!enabled) { + withMetricsAdapter(MetricsAdapter.DEV_NULL); + } else if (this.metricsAdapter == null || this.metricsAdapter == MetricsAdapter.DEV_NULL) { + withMetricsAdapter(MetricsAdapter.DEFAULT); } return this; } @@ -751,9 +693,8 @@ else if ( this.metricsAdapter == null || this.metricsAdapter == MetricsAdapter.D * @return this builder. */ @Experimental - public ConfigBuilder withMetricsAdapter( MetricsAdapter metricsAdapter ) - { - this.metricsAdapter = Objects.requireNonNull( metricsAdapter, "metricsAdapter" ); + public ConfigBuilder withMetricsAdapter(MetricsAdapter metricsAdapter) { + this.metricsAdapter = Objects.requireNonNull(metricsAdapter, "metricsAdapter"); return this; } @@ -764,11 +705,10 @@ public ConfigBuilder withMetricsAdapter( MetricsAdapter metricsAdapter ) * @return this builder. * @throws IllegalArgumentException if the value of the size is set to a number that is less than 1. */ - public ConfigBuilder withEventLoopThreads( int size ) - { - if ( size < 1 ) - { - throw new IllegalArgumentException( String.format( "The event loop thread may not be smaller than 1, but was %d.", size ) ); + public ConfigBuilder withEventLoopThreads(int size) { + if (size < 1) { + throw new IllegalArgumentException( + String.format("The event loop thread may not be smaller than 1, but was %d.", size)); } this.eventLoopThreads = size; return this; @@ -779,11 +719,9 @@ public ConfigBuilder withEventLoopThreads( int size ) * @param userAgent the string to configure user_agent. * @return this builder. */ - public ConfigBuilder withUserAgent( String userAgent ) - { - if ( userAgent == null || userAgent.isEmpty() ) - { - throw new IllegalArgumentException( "The user_agent string must not be empty" ); + public ConfigBuilder withUserAgent(String userAgent) { + if (userAgent == null || userAgent.isEmpty()) { + throw new IllegalArgumentException("The user_agent string must not be empty"); } this.userAgent = userAgent; return this; @@ -792,14 +730,12 @@ public ConfigBuilder withUserAgent( String userAgent ) /** * Extracts the driver version from the driver jar MANIFEST.MF file. */ - private static String driverVersion() - { + private static String driverVersion() { // "Session" is arbitrary - the only thing that matters is that the class we use here is in the // 'org.neo4j.driver' package, because that is where the jar manifest specifies the version. // This is done as part of the build, adding a MANIFEST.MF file to the generated jarfile. Package pkg = Session.class.getPackage(); - if ( pkg != null && pkg.getImplementationVersion() != null ) - { + if (pkg != null && pkg.getImplementationVersion() != null) { return pkg.getImplementationVersion(); } @@ -813,24 +749,21 @@ private static String driverVersion() * * @return a new {@link Config} instance. */ - public Config build() - { - return new Config( this ); + public Config build() { + return new Config(this); } } /** * Control how the driver determines if it can trust the encryption certificates provided by the Neo4j instance it is connected to. */ - public static class TrustStrategy implements Serializable - { + public static class TrustStrategy implements Serializable { private static final long serialVersionUID = -1631888096243987740L; /** * The trust strategy that the driver supports */ - public enum Strategy - { + public enum Strategy { TRUST_ALL_CERTIFICATES, TRUST_CUSTOM_CA_SIGNED_CERTIFICATES, TRUST_SYSTEM_CA_SIGNED_CERTIFICATES @@ -841,16 +774,14 @@ public enum Strategy private boolean hostnameVerificationEnabled = true; private RevocationStrategy revocationStrategy = RevocationStrategy.NO_CHECKS; - private TrustStrategy( Strategy strategy ) - { - this( strategy, Collections.emptyList() ); + private TrustStrategy(Strategy strategy) { + this(strategy, Collections.emptyList()); } - private TrustStrategy( Strategy strategy, List certFiles ) - { - Objects.requireNonNull( certFiles, "certFiles can't be null" ); + private TrustStrategy(Strategy strategy, List certFiles) { + Objects.requireNonNull(certFiles, "certFiles can't be null"); this.strategy = strategy; - this.certFiles = Collections.unmodifiableList( new ArrayList<>( certFiles ) ); + this.certFiles = Collections.unmodifiableList(new ArrayList<>(certFiles)); } /** @@ -858,8 +789,7 @@ private TrustStrategy( Strategy strategy, List certFiles ) * * @return the strategy we should use */ - public Strategy strategy() - { + public Strategy strategy() { return strategy; } @@ -870,9 +800,8 @@ public Strategy strategy() * @deprecated superseded by {@link TrustStrategy#certFiles()} */ @Deprecated - public File certFile() - { - return certFiles.isEmpty() ? null : certFiles.get( 0 ); + public File certFile() { + return certFiles.isEmpty() ? null : certFiles.get(0); } /** @@ -880,8 +809,7 @@ public File certFile() * * @return configured certificate files or empty list if trust strategy does not require certificates. */ - public List certFiles() - { + public List certFiles() { return certFiles; } @@ -890,8 +818,7 @@ public List certFiles() * * @return {@code true} if hostname verification has been enabled via {@link #withHostnameVerification()}, {@code false} otherwise. */ - public boolean isHostnameVerificationEnabled() - { + public boolean isHostnameVerificationEnabled() { return hostnameVerificationEnabled; } @@ -900,8 +827,7 @@ public boolean isHostnameVerificationEnabled() * * @return the current trust strategy. */ - public TrustStrategy withHostnameVerification() - { + public TrustStrategy withHostnameVerification() { hostnameVerificationEnabled = true; return this; } @@ -911,8 +837,7 @@ public TrustStrategy withHostnameVerification() * * @return the current trust strategy. */ - public TrustStrategy withoutHostnameVerification() - { + public TrustStrategy withoutHostnameVerification() { hostnameVerificationEnabled = false; return this; } @@ -927,14 +852,12 @@ public TrustStrategy withoutHostnameVerification() * @param certFiles the trusted certificate files, it must not be {@code null} or empty * @return an authentication config */ - public static TrustStrategy trustCustomCertificateSignedBy( File... certFiles ) - { - Objects.requireNonNull( certFiles, "certFiles can't be null" ); - if ( certFiles.length == 0 ) - { - throw new IllegalArgumentException( "certFiles can't be empty" ); + public static TrustStrategy trustCustomCertificateSignedBy(File... certFiles) { + Objects.requireNonNull(certFiles, "certFiles can't be null"); + if (certFiles.length == 0) { + throw new IllegalArgumentException("certFiles can't be empty"); } - return new TrustStrategy( Strategy.TRUST_CUSTOM_CA_SIGNED_CERTIFICATES, Arrays.asList( certFiles ) ); + return new TrustStrategy(Strategy.TRUST_CUSTOM_CA_SIGNED_CERTIFICATES, Arrays.asList(certFiles)); } /** @@ -942,9 +865,8 @@ public static TrustStrategy trustCustomCertificateSignedBy( File... certFiles ) * * @return an authentication config */ - public static TrustStrategy trustSystemCertificates() - { - return new TrustStrategy( Strategy.TRUST_SYSTEM_CA_SIGNED_CERTIFICATES ); + public static TrustStrategy trustSystemCertificates() { + return new TrustStrategy(Strategy.TRUST_SYSTEM_CA_SIGNED_CERTIFICATES); } /** @@ -953,17 +875,15 @@ public static TrustStrategy trustSystemCertificates() * @return an authentication config * @since 1.1 */ - public static TrustStrategy trustAllCertificates() - { - return new TrustStrategy( Strategy.TRUST_ALL_CERTIFICATES ); + public static TrustStrategy trustAllCertificates() { + return new TrustStrategy(Strategy.TRUST_ALL_CERTIFICATES); } /** * The revocation strategy used for verifying certificates. * @return this {@link TrustStrategy}'s revocation strategy */ - public RevocationStrategy revocationStrategy() - { + public RevocationStrategy revocationStrategy() { return revocationStrategy; } @@ -972,8 +892,7 @@ public RevocationStrategy revocationStrategy() * option that is configured by default. * @return the current trust strategy */ - public TrustStrategy withoutCertificateRevocationChecks() - { + public TrustStrategy withoutCertificateRevocationChecks() { this.revocationStrategy = RevocationStrategy.NO_CHECKS; return this; } @@ -985,8 +904,7 @@ public TrustStrategy withoutCertificateRevocationChecks() * OCSP stapling. * @return the current trust strategy */ - public TrustStrategy withVerifyIfPresentRevocationChecks() - { + public TrustStrategy withVerifyIfPresentRevocationChecks() { this.revocationStrategy = RevocationStrategy.VERIFY_IF_PRESENT; return this; } @@ -1000,8 +918,7 @@ public TrustStrategy withVerifyIfPresentRevocationChecks() * the certificate's configured OCSP responder URL. * @return the current trust strategy */ - public TrustStrategy withStrictRevocationChecks() - { + public TrustStrategy withStrictRevocationChecks() { this.revocationStrategy = RevocationStrategy.STRICT; return this; } diff --git a/driver/src/main/java/org/neo4j/driver/ConnectionPoolMetrics.java b/driver/src/main/java/org/neo4j/driver/ConnectionPoolMetrics.java index 3c9c55115a..d371f61ca4 100644 --- a/driver/src/main/java/org/neo4j/driver/ConnectionPoolMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/ConnectionPoolMetrics.java @@ -19,7 +19,6 @@ package org.neo4j.driver; import java.util.concurrent.TimeUnit; - import org.neo4j.driver.util.Experimental; /** @@ -27,8 +26,7 @@ * The pool metrics is uniquely identified using {@link ConnectionPoolMetrics#id()}. */ @Experimental -public interface ConnectionPoolMetrics -{ +public interface ConnectionPoolMetrics { /** * A unique id that identifies this pool metrics. * diff --git a/driver/src/main/java/org/neo4j/driver/Driver.java b/driver/src/main/java/org/neo4j/driver/Driver.java index b5f1d48840..0861ed5c03 100644 --- a/driver/src/main/java/org/neo4j/driver/Driver.java +++ b/driver/src/main/java/org/neo4j/driver/Driver.java @@ -19,7 +19,6 @@ package org.neo4j.driver; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.reactive.RxSession; @@ -62,8 +61,7 @@ * * @since 1.0 (Modified and Added {@link AsyncSession} and {@link RxSession} since 2.0) */ -public interface Driver extends AutoCloseable -{ +public interface Driver extends AutoCloseable { /** * Return a flag to indicate whether or not encryption is used for this driver. * @@ -87,7 +85,7 @@ public interface Driver extends AutoCloseable * @return a new {@link Session} object. * @see SessionConfig */ - Session session( SessionConfig sessionConfig ); + Session session(SessionConfig sessionConfig); /** * Create a new general purpose {@link RxSession} with default {@link SessionConfig session configuration}. @@ -106,7 +104,7 @@ public interface Driver extends AutoCloseable * @param sessionConfig used to customize the session. * @return a new {@link RxSession} object. */ - RxSession rxSession( SessionConfig sessionConfig ); + RxSession rxSession(SessionConfig sessionConfig); /** * Create a new general purpose {@link AsyncSession} with default {@link SessionConfig session configuration}. @@ -126,7 +124,7 @@ public interface Driver extends AutoCloseable * @param sessionConfig used to customize the session. * @return a new {@link AsyncSession} object. */ - AsyncSession asyncSession( SessionConfig sessionConfig ); + AsyncSession asyncSession(SessionConfig sessionConfig); /** * Close all the resources assigned to this driver, including open connections and IO threads. diff --git a/driver/src/main/java/org/neo4j/driver/GraphDatabase.java b/driver/src/main/java/org/neo4j/driver/GraphDatabase.java index 2ab1a6a7b3..bf6cdd672b 100644 --- a/driver/src/main/java/org/neo4j/driver/GraphDatabase.java +++ b/driver/src/main/java/org/neo4j/driver/GraphDatabase.java @@ -18,8 +18,9 @@ */ package org.neo4j.driver; -import java.net.URI; +import static org.neo4j.driver.internal.Scheme.NEO4J_URI_SCHEME; +import java.net.URI; import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.DriverFactory; import org.neo4j.driver.internal.SecuritySettings; @@ -27,24 +28,20 @@ import org.neo4j.driver.internal.retry.RetrySettings; import org.neo4j.driver.internal.security.SecurityPlan; -import static org.neo4j.driver.internal.Scheme.NEO4J_URI_SCHEME; - /** * Creates {@link Driver drivers}, optionally letting you {@link #driver(URI, Config)} to configure them. * @see Driver * @since 1.0 */ -public class GraphDatabase -{ +public class GraphDatabase { /** * Return a driver for a Neo4j instance with the default configuration settings * * @param uri the URL to a Neo4j instance * @return a new driver to the database instance specified by the URL */ - public static Driver driver( String uri ) - { - return driver( uri, Config.defaultConfig() ); + public static Driver driver(String uri) { + return driver(uri, Config.defaultConfig()); } /** @@ -53,9 +50,8 @@ public static Driver driver( String uri ) * @param uri the URL to a Neo4j instance * @return a new driver to the database instance specified by the URL */ - public static Driver driver( URI uri ) - { - return driver( uri, Config.defaultConfig() ); + public static Driver driver(URI uri) { + return driver(uri, Config.defaultConfig()); } /** @@ -65,9 +61,8 @@ public static Driver driver( URI uri ) * @param config user defined configuration * @return a new driver to the database instance specified by the URL */ - public static Driver driver( URI uri, Config config ) - { - return driver( uri, AuthTokens.none(), config ); + public static Driver driver(URI uri, Config config) { + return driver(uri, AuthTokens.none(), config); } /** @@ -77,9 +72,8 @@ public static Driver driver( URI uri, Config config ) * @param config user defined configuration * @return a new driver to the database instance specified by the URL */ - public static Driver driver( String uri, Config config ) - { - return driver( URI.create( uri ), config ); + public static Driver driver(String uri, Config config) { + return driver(URI.create(uri), config); } /** @@ -89,9 +83,8 @@ public static Driver driver( String uri, Config config ) * @param authToken authentication to use, see {@link AuthTokens} * @return a new driver to the database instance specified by the URL */ - public static Driver driver( String uri, AuthToken authToken ) - { - return driver( uri, authToken, Config.defaultConfig() ); + public static Driver driver(String uri, AuthToken authToken) { + return driver(uri, authToken, Config.defaultConfig()); } /** @@ -101,9 +94,8 @@ public static Driver driver( String uri, AuthToken authToken ) * @param authToken authentication to use, see {@link AuthTokens} * @return a new driver to the database instance specified by the URL */ - public static Driver driver( URI uri, AuthToken authToken ) - { - return driver( uri, authToken, Config.defaultConfig() ); + public static Driver driver(URI uri, AuthToken authToken) { + return driver(uri, authToken, Config.defaultConfig()); } /** @@ -114,9 +106,8 @@ public static Driver driver( URI uri, AuthToken authToken ) * @param config user defined configuration * @return a new driver to the database instance specified by the URL */ - public static Driver driver( String uri, AuthToken authToken, Config config ) - { - return driver( URI.create( uri ), authToken, config ); + public static Driver driver(String uri, AuthToken authToken, Config config) { + return driver(URI.create(uri), authToken, config); } /** @@ -127,19 +118,17 @@ public static Driver driver( String uri, AuthToken authToken, Config config ) * @param config user defined configuration * @return a new driver to the database instance specified by the URL */ - public static Driver driver( URI uri, AuthToken authToken, Config config ) - { - return driver( uri, authToken, config, new DriverFactory() ); + public static Driver driver(URI uri, AuthToken authToken, Config config) { + return driver(uri, authToken, config, new DriverFactory()); } - static Driver driver( URI uri, AuthToken authToken, Config config, DriverFactory driverFactory ) - { - config = getOrDefault( config ); + static Driver driver(URI uri, AuthToken authToken, Config config, DriverFactory driverFactory) { + config = getOrDefault(config); RoutingSettings routingSettings = config.routingSettings(); RetrySettings retrySettings = config.retrySettings(); SecuritySettings securitySettings = config.securitySettings(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( uri.getScheme() ); - return driverFactory.newInstance( uri, authToken, routingSettings, retrySettings, config, securityPlan ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(uri.getScheme()); + return driverFactory.newInstance(uri, authToken, routingSettings, retrySettings, config, securityPlan); } /** @@ -153,72 +142,56 @@ static Driver driver( URI uri, AuthToken authToken, Config config, DriverFactory * @param config user defined configuration * @return a new driver instance */ - public static Driver routingDriver( Iterable routingUris, AuthToken authToken, Config config ) - { - return routingDriver( routingUris, authToken, config, new DriverFactory() ); + public static Driver routingDriver(Iterable routingUris, AuthToken authToken, Config config) { + return routingDriver(routingUris, authToken, config, new DriverFactory()); } - static Driver routingDriver( Iterable routingUris, AuthToken authToken, Config config, DriverFactory driverFactory ) - { - assertRoutingUris( routingUris ); - Logger log = createLogger( config ); + static Driver routingDriver( + Iterable routingUris, AuthToken authToken, Config config, DriverFactory driverFactory) { + assertRoutingUris(routingUris); + Logger log = createLogger(config); - for ( URI uri : routingUris ) - { - final Driver driver = driver( uri, authToken, config, driverFactory ); - try - { + for (URI uri : routingUris) { + final Driver driver = driver(uri, authToken, config, driverFactory); + try { driver.verifyConnectivity(); return driver; - } - catch ( ServiceUnavailableException e ) - { - log.warn( "Unable to create routing driver for URI: " + uri, e ); - closeDriver( driver, uri, log ); - } - catch ( Throwable e ) - { + } catch (ServiceUnavailableException e) { + log.warn("Unable to create routing driver for URI: " + uri, e); + closeDriver(driver, uri, log); + } catch (Throwable e) { // for any other errors, we first close the driver and then rethrow the original error out. - closeDriver( driver, uri, log ); + closeDriver(driver, uri, log); throw e; } } - throw new ServiceUnavailableException( "Failed to discover an available server" ); + throw new ServiceUnavailableException("Failed to discover an available server"); } - private static void closeDriver( Driver driver, URI uri, Logger log ) - { - try - { + private static void closeDriver(Driver driver, URI uri, Logger log) { + try { driver.close(); - } - catch ( Throwable closeError ) - { - log.warn( "Unable to close driver towards URI: " + uri, closeError ); + } catch (Throwable closeError) { + log.warn("Unable to close driver towards URI: " + uri, closeError); } } - private static void assertRoutingUris( Iterable uris ) - { - for ( URI uri : uris ) - { - if ( !NEO4J_URI_SCHEME.equals( uri.getScheme() ) ) - { + private static void assertRoutingUris(Iterable uris) { + for (URI uri : uris) { + if (!NEO4J_URI_SCHEME.equals(uri.getScheme())) { throw new IllegalArgumentException( - "Illegal URI scheme, expected '" + NEO4J_URI_SCHEME + "' in '" + uri + "'" ); + "Illegal URI scheme, expected '" + NEO4J_URI_SCHEME + "' in '" + uri + "'"); } } } - private static Logger createLogger( Config config ) - { - Logging logging = getOrDefault( config ).logging(); - return logging.getLog( GraphDatabase.class ); + private static Logger createLogger(Config config) { + Logging logging = getOrDefault(config).logging(); + return logging.getLog(GraphDatabase.class); } - private static Config getOrDefault( Config config ) - { + private static Config getOrDefault(Config config) { return config != null ? config : Config.defaultConfig(); } } diff --git a/driver/src/main/java/org/neo4j/driver/Logger.java b/driver/src/main/java/org/neo4j/driver/Logger.java index d30138d289..e22ee5facb 100644 --- a/driver/src/main/java/org/neo4j/driver/Logger.java +++ b/driver/src/main/java/org/neo4j/driver/Logger.java @@ -26,8 +26,7 @@ * Thus all supplied message templates will contain "%s" as parameter placeholders. This is different from all SLF4J-compatible logging frameworks * where parameter placeholder is "{}". Implementations of this interface should adapt placeholders from "%s" to "{}", if required. */ -public interface Logger -{ +public interface Logger { /** * Logs errors from this driver. *

@@ -41,7 +40,7 @@ public interface Logger * @param message the error message. * @param cause the cause of the error. */ - void error( String message, Throwable cause ); + void error(String message, Throwable cause); /** * Logs information from the driver. @@ -55,7 +54,7 @@ public interface Logger * @param message the information message template. Can contain {@link String#format(String, Object...)}-style placeholders, like "%s". * @param params parameters used in the information message. */ - void info( String message, Object... params ); + void info(String message, Object... params); /** * Logs warnings that happened when using the driver. @@ -69,7 +68,7 @@ public interface Logger * @param message the warning message template. Can contain {@link String#format(String, Object...)}-style placeholders, like "%s". * @param params parameters used in the warning message. */ - void warn( String message, Object... params ); + void warn(String message, Object... params); /** * Logs warnings that happened during using the driver @@ -84,7 +83,7 @@ public interface Logger * @param message the warning message * @param cause the cause of the warning */ - void warn( String message, Throwable cause ); + void warn(String message, Throwable cause); /** * Logs bolt messages sent and received by this driver. @@ -101,7 +100,7 @@ public interface Logger * @param message the debug message template. Can contain {@link String#format(String, Object...)}-style placeholders, like "%s". * @param params parameters used in generating the bolt message */ - void debug( String message, Object... params ); + void debug(String message, Object... params); /** * Logs debug message with throwable. @@ -109,7 +108,7 @@ public interface Logger * @param message the message to log * @param throwable the throwable to include into the log entry */ - void debug( String message, Throwable throwable ); + void debug(String message, Throwable throwable); /** * Logs binary sent and received by this driver. @@ -128,7 +127,7 @@ public interface Logger * @param message the trace message template. Can contain {@link String#format(String, Object...)}-style placeholders, like "%s". * @param params parameters used in generating the hex message */ - void trace( String message, Object... params ); + void trace(String message, Object... params); /** * Return true if the trace logging level is enabled. diff --git a/driver/src/main/java/org/neo4j/driver/Logging.java b/driver/src/main/java/org/neo4j/driver/Logging.java index aa2bfd5f08..44b3cadc06 100644 --- a/driver/src/main/java/org/neo4j/driver/Logging.java +++ b/driver/src/main/java/org/neo4j/driver/Logging.java @@ -18,15 +18,14 @@ */ package org.neo4j.driver; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; + import java.util.logging.ConsoleHandler; import java.util.logging.Level; - import org.neo4j.driver.internal.logging.ConsoleLogging; import org.neo4j.driver.internal.logging.JULogging; import org.neo4j.driver.internal.logging.Slf4jLogging; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; - /** * Accessor for {@link Logger} instances. Configured once for a driver instance using {@link Config.ConfigBuilder#withLogging(Logging)} builder method. * Users are expected to either implement this interface or use one of the existing implementations (available via static methods in this interface): @@ -85,18 +84,16 @@ * @see Logger * @see Config.ConfigBuilder#withLogging(Logging) */ -public interface Logging -{ +public interface Logging { /** * Obtain a {@link Logger} instance by class, its name will be the fully qualified name of the class. * * @param clazz class whose name should be used as the {@link Logger} name. * @return {@link Logger} instance */ - default Logger getLog( Class clazz ) - { + default Logger getLog(Class clazz) { String canonicalName = clazz.getCanonicalName(); - return getLog( canonicalName != null ? canonicalName : clazz.getName() ); + return getLog(canonicalName != null ? canonicalName : clazz.getName()); } /** @@ -105,7 +102,7 @@ default Logger getLog( Class clazz ) * @param name name of a {@link Logger} * @return {@link Logger} instance */ - Logger getLog( String name ); + Logger getLog(String name); /** * Create logging implementation that uses SLF4J. @@ -113,11 +110,9 @@ default Logger getLog( Class clazz ) * @return new logging implementation. * @throws IllegalStateException if SLF4J is not available. */ - static Logging slf4j() - { + static Logging slf4j() { RuntimeException unavailabilityError = Slf4jLogging.checkAvailability(); - if ( unavailabilityError != null ) - { + if (unavailabilityError != null) { throw unavailabilityError; } return new Slf4jLogging(); @@ -129,9 +124,8 @@ static Logging slf4j() * @param level the log level. * @return new logging implementation. */ - static Logging javaUtilLogging( Level level ) - { - return new JULogging( level ); + static Logging javaUtilLogging(Level level) { + return new JULogging(level); } /** @@ -140,9 +134,8 @@ static Logging javaUtilLogging( Level level ) * @param level the log level. * @return new logging implementation. */ - static Logging console( Level level ) - { - return new ConsoleLogging( level ); + static Logging console(Level level) { + return new ConsoleLogging(level); } /** @@ -150,8 +143,7 @@ static Logging console( Level level ) * * @return new logging implementation. */ - static Logging none() - { + static Logging none() { return DEV_NULL_LOGGING; } } diff --git a/driver/src/main/java/org/neo4j/driver/Metrics.java b/driver/src/main/java/org/neo4j/driver/Metrics.java index 5449f9172c..c60294a8dd 100644 --- a/driver/src/main/java/org/neo4j/driver/Metrics.java +++ b/driver/src/main/java/org/neo4j/driver/Metrics.java @@ -19,15 +19,13 @@ package org.neo4j.driver; import java.util.Collection; - import org.neo4j.driver.util.Experimental; /** * Provides driver internal metrics. */ @Experimental -public interface Metrics -{ +public interface Metrics { /** * Connection pool metrics records metrics of connection pools that are currently in use. * As the connection pools are dynamically added and removed while the server topology changes, the metrics collection changes over time. diff --git a/driver/src/main/java/org/neo4j/driver/MetricsAdapter.java b/driver/src/main/java/org/neo4j/driver/MetricsAdapter.java index e78e93ba0a..fe3c09de00 100644 --- a/driver/src/main/java/org/neo4j/driver/MetricsAdapter.java +++ b/driver/src/main/java/org/neo4j/driver/MetricsAdapter.java @@ -21,8 +21,7 @@ /** * Defines which metrics consumer to use: Should metrics be consumed and exposed via driver's default consumer or provided with one of the external facades. */ -public enum MetricsAdapter -{ +public enum MetricsAdapter { /** * Disables metrics. */ diff --git a/driver/src/main/java/org/neo4j/driver/Query.java b/driver/src/main/java/org/neo4j/driver/Query.java index d6ae3080b0..915ff63d63 100644 --- a/driver/src/main/java/org/neo4j/driver/Query.java +++ b/driver/src/main/java/org/neo4j/driver/Query.java @@ -18,18 +18,17 @@ */ package org.neo4j.driver; -import java.util.Map; +import static java.lang.String.format; +import static org.neo4j.driver.Values.ofValue; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.Iterables.newHashMapWithSize; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.util.Map; import org.neo4j.driver.internal.value.MapValue; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.util.Immutable; -import static java.lang.String.format; -import static org.neo4j.driver.internal.util.Iterables.newHashMapWithSize; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; -import static org.neo4j.driver.Values.ofValue; -import static org.neo4j.driver.Values.value; - /** * The components of a Cypher query, containing the query text and parameter map. * @@ -41,8 +40,7 @@ * @since 1.0 */ @Immutable -public class Query -{ +public class Query { private final String text; private final Value parameters; @@ -51,20 +49,16 @@ public class Query * @param text the query text * @param parameters the parameter map */ - public Query(String text, Value parameters ) - { - this.text = validateQueryText( text ); - if( parameters == null ) - { + public Query(String text, Value parameters) { + this.text = validateQueryText(text); + if (parameters == null) { this.parameters = Values.EmptyMap; - } - else if ( parameters instanceof MapValue ) - { + } else if (parameters instanceof MapValue) { this.parameters = parameters; - } - else - { - throw new IllegalArgumentException( "The parameters should be provided as Map type. Unsupported parameters type: " + parameters.type().name() ); + } else { + throw new IllegalArgumentException( + "The parameters should be provided as Map type. Unsupported parameters type: " + + parameters.type().name()); } } @@ -73,33 +67,29 @@ else if ( parameters instanceof MapValue ) * @param text the query text * @param parameters the parameter map */ - public Query(String text, Map parameters ) - { - this( text, Values.value( parameters ) ); + public Query(String text, Map parameters) { + this(text, Values.value(parameters)); } /** * Create a new query. * @param text the query text */ - public Query(String text ) - { - this( text, Values.EmptyMap ); + public Query(String text) { + this(text, Values.EmptyMap); } /** * @return the query text */ - public String text() - { + public String text() { return text; } /** * @return the parameter map */ - public Value parameters() - { + public Value parameters() { return parameters; } @@ -107,27 +97,24 @@ public Value parameters() * @param newText the new query text * @return a new Query object with updated text */ - public Query withText(String newText ) - { - return new Query( newText, parameters ); + public Query withText(String newText) { + return new Query(newText, parameters); } /** * @param newParameters the new parameter map * @return a new Query object with updated parameters */ - public Query withParameters(Value newParameters ) - { - return new Query( text, newParameters ); + public Query withParameters(Value newParameters) { + return new Query(text, newParameters); } /** * @param newParameters the new parameter map * @return a new Query object with updated parameters */ - public Query withParameters(Map newParameters ) - { - return new Query( text, newParameters ); + public Query withParameters(Map newParameters) { + return new Query(text, newParameters); } /** @@ -141,67 +128,52 @@ public Query withParameters(Map newParameters ) * @param updates describing how to update the parameters * @return a new query with updated parameters */ - public Query withUpdatedParameters(Value updates ) - { - if ( updates == null || updates.isEmpty() ) - { + public Query withUpdatedParameters(Value updates) { + if (updates == null || updates.isEmpty()) { return this; - } - else - { - Map newParameters = newHashMapWithSize( Math.max( parameters.size(), updates.size() ) ); - newParameters.putAll( parameters.asMap( ofValue() ) ); - for ( Map.Entry entry : updates.asMap( ofValue() ).entrySet() ) - { + } else { + Map newParameters = newHashMapWithSize(Math.max(parameters.size(), updates.size())); + newParameters.putAll(parameters.asMap(ofValue())); + for (Map.Entry entry : updates.asMap(ofValue()).entrySet()) { Value value = entry.getValue(); - if ( value.isNull() ) - { - newParameters.remove( entry.getKey() ); - } - else - { - newParameters.put( entry.getKey(), value ); + if (value.isNull()) { + newParameters.remove(entry.getKey()); + } else { + newParameters.put(entry.getKey(), value); } } - return withParameters( value(newParameters) ); + return withParameters(value(newParameters)); } } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } Query query = (Query) o; - return text.equals( query.text ) && parameters.equals( query.parameters ); - + return text.equals(query.text) && parameters.equals(query.parameters); } @Override - public int hashCode() - { + public int hashCode() { int result = text.hashCode(); result = 31 * result + parameters.hashCode(); return result; } @Override - public String toString() - { - return format( "Query{text='%s', parameters=%s}", text, parameters ); + public String toString() { + return format("Query{text='%s', parameters=%s}", text, parameters); } - private static String validateQueryText(String query ) - { - checkArgument( query != null, "Cypher query text should not be null" ); - checkArgument( !query.isEmpty(), "Cypher query text should not be an empty string" ); + private static String validateQueryText(String query) { + checkArgument(query != null, "Cypher query text should not be null"); + checkArgument(!query.isEmpty(), "Cypher query text should not be an empty string"); return query; } } diff --git a/driver/src/main/java/org/neo4j/driver/QueryRunner.java b/driver/src/main/java/org/neo4j/driver/QueryRunner.java index a27f767107..7d3b8a5d94 100644 --- a/driver/src/main/java/org/neo4j/driver/QueryRunner.java +++ b/driver/src/main/java/org/neo4j/driver/QueryRunner.java @@ -59,8 +59,7 @@ * @see Transaction * @since 1.0 */ -public interface QueryRunner extends AutoCloseable -{ +public interface QueryRunner extends AutoCloseable { /** * Run a query and return a result stream. *

@@ -89,7 +88,7 @@ public interface QueryRunner extends AutoCloseable * @param parameters input parameters, should be a map Value, see {@link Values#parameters(Object...)}. * @return a stream of result values and associated metadata */ - Result run(String query, Value parameters ); + Result run(String query, Value parameters); /** * Run a query and return a result stream. @@ -119,7 +118,7 @@ public interface QueryRunner extends AutoCloseable * @param parameters input data for the query * @return a stream of result values and associated metadata */ - Result run(String query, Map parameters ); + Result run(String query, Map parameters); /** * Run a query and return a result stream. @@ -136,7 +135,7 @@ public interface QueryRunner extends AutoCloseable * @param parameters input data for the query * @return a stream of result values and associated metadata */ - Result run(String query, Record parameters ); + Result run(String query, Record parameters); /** * Run a query and return a result stream. @@ -144,7 +143,7 @@ public interface QueryRunner extends AutoCloseable * @param query text of a Neo4j query * @return a stream of result values and associated metadata */ - Result run(String query ); + Result run(String query); /** * Run a query and return a result stream. diff --git a/driver/src/main/java/org/neo4j/driver/Record.java b/driver/src/main/java/org/neo4j/driver/Record.java index 204c766a8c..252f6b1ae9 100644 --- a/driver/src/main/java/org/neo4j/driver/Record.java +++ b/driver/src/main/java/org/neo4j/driver/Record.java @@ -19,7 +19,6 @@ package org.neo4j.driver; import java.util.List; - import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.NoSuchRecordException; import org.neo4j.driver.types.MapAccessorWithDefaultValue; @@ -39,8 +38,7 @@ * @since 1.0 */ @Immutable -public interface Record extends MapAccessorWithDefaultValue -{ +public interface Record extends MapAccessorWithDefaultValue { /** * Retrieve the keys of the underlying map * @@ -64,7 +62,7 @@ public interface Record extends MapAccessorWithDefaultValue * @param key the give key * @return the index of the field as used by {@link #get(int)} */ - int index( String key ); + int index(String key); /** * Retrieve the value at the given field index @@ -73,7 +71,7 @@ public interface Record extends MapAccessorWithDefaultValue * @return the value or a {@link org.neo4j.driver.internal.value.NullValue} if the index is out of bounds * @throws ClientException if record has not been initialized */ - Value get( int index ); + Value get(int index); /** * Retrieve all record fields diff --git a/driver/src/main/java/org/neo4j/driver/Records.java b/driver/src/main/java/org/neo4j/driver/Records.java index 13b339b22d..583429f363 100644 --- a/driver/src/main/java/org/neo4j/driver/Records.java +++ b/driver/src/main/java/org/neo4j/driver/Records.java @@ -26,37 +26,29 @@ * @see Result#list() * @since 1.0 */ -public abstract class Records -{ - public static Function column( int index ) - { - return column( index, Values.ofValue() ); +public abstract class Records { + public static Function column(int index) { + return column(index, Values.ofValue()); } - public static Function column( String key ) - { - return column( key, Values.ofValue() ); + public static Function column(String key) { + return column(key, Values.ofValue()); } - public static Function column( final int index, final Function mapFunction ) - { - return new Function() - { + public static Function column(final int index, final Function mapFunction) { + return new Function() { @Override - public T apply( Record record ) - { - return mapFunction.apply( record.get( index ) ); + public T apply(Record record) { + return mapFunction.apply(record.get(index)); } }; } - public static Function column( final String key, final Function mapFunction ) - { - return new Function() - { + + public static Function column(final String key, final Function mapFunction) { + return new Function() { @Override - public T apply( Record recordAccessor ) - { - return mapFunction.apply( recordAccessor.get( key ) ); + public T apply(Record recordAccessor) { + return mapFunction.apply(recordAccessor.get(key)); } }; } diff --git a/driver/src/main/java/org/neo4j/driver/Result.java b/driver/src/main/java/org/neo4j/driver/Result.java index 2b85d1303f..10a1aa8ff5 100644 --- a/driver/src/main/java/org/neo4j/driver/Result.java +++ b/driver/src/main/java/org/neo4j/driver/Result.java @@ -22,12 +22,10 @@ import java.util.List; import java.util.function.Function; import java.util.stream.Stream; - import org.neo4j.driver.exceptions.NoSuchRecordException; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.util.Resource; - /** * The result of running a Cypher query, conceptually a stream of {@link Record records}. * @@ -53,8 +51,7 @@ * * @since 1.0 */ -public interface Result extends Iterator -{ +public interface Result extends Iterator { /** * Retrieve the keys of the records this result contains. * @@ -66,7 +63,8 @@ public interface Result extends Iterator * Test if there is another record we can navigate to in this result. * @return true if {@link #next()} will return another record */ - @Override boolean hasNext(); + @Override + boolean hasNext(); /** * Navigate to and retrieve the next {@link Record} in this result. @@ -74,7 +72,8 @@ public interface Result extends Iterator * @throws NoSuchRecordException if there is no record left in the stream * @return the next record */ - @Override Record next(); + @Override + Record next(); /** * Return the first record in the result, failing if there is not exactly @@ -136,7 +135,7 @@ public interface Result extends Iterator * @param the type of result list elements * @return list of all mapped remaining immutable records */ - List list( Function mapFunction ); + List list(Function mapFunction); /** * Return the result summary. diff --git a/driver/src/main/java/org/neo4j/driver/Session.java b/driver/src/main/java/org/neo4j/driver/Session.java index 8d7dd72d51..8ab1d68aaa 100644 --- a/driver/src/main/java/org/neo4j/driver/Session.java +++ b/driver/src/main/java/org/neo4j/driver/Session.java @@ -19,7 +19,6 @@ package org.neo4j.driver; import java.util.Map; - import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.util.Resource; @@ -52,8 +51,7 @@ * * @since 1.0 (Removed async API to {@link AsyncSession} in 4.0) */ -public interface Session extends Resource, QueryRunner -{ +public interface Session extends Resource, QueryRunner { /** * Begin a new unmanaged {@linkplain Transaction transaction}. At * most one transaction may exist in a session at any point in time. To @@ -73,7 +71,7 @@ public interface Session extends Resource, QueryRunner * @param config configuration for the new transaction. * @return a new {@link Transaction} */ - Transaction beginTransaction( TransactionConfig config ); + Transaction beginTransaction(TransactionConfig config); /** * Execute a unit of work in a managed {@link AccessMode#READ read} transaction. @@ -88,7 +86,7 @@ public interface Session extends Resource, QueryRunner * @param the return type of the given unit of work. * @return a result as returned by the given unit of work. */ - T readTransaction( TransactionWork work ); + T readTransaction(TransactionWork work); /** * Execute a unit of work in a managed {@link AccessMode#READ read} transaction @@ -105,7 +103,7 @@ public interface Session extends Resource, QueryRunner * @param the return type of the given unit of work. * @return a result as returned by the given unit of work. */ - T readTransaction( TransactionWork work, TransactionConfig config ); + T readTransaction(TransactionWork work, TransactionConfig config); /** * Execute a unit of work in a managed {@link AccessMode#WRITE write} transaction. @@ -120,7 +118,7 @@ public interface Session extends Resource, QueryRunner * @param the return type of the given unit of work. * @return a result as returned by the given unit of work. */ - T writeTransaction( TransactionWork work ); + T writeTransaction(TransactionWork work); /** * Execute a unit of work in a managed {@link AccessMode#WRITE write} transaction @@ -137,7 +135,7 @@ public interface Session extends Resource, QueryRunner * @param the return type of the given unit of work. * @return a result as returned by the given unit of work. */ - T writeTransaction( TransactionWork work, TransactionConfig config ); + T writeTransaction(TransactionWork work, TransactionConfig config); /** * Run a query in a managed auto-commit transaction with the specified @@ -147,7 +145,7 @@ public interface Session extends Resource, QueryRunner * @param config configuration for the new transaction. * @return a stream of result values and associated metadata. */ - Result run(String query, TransactionConfig config ); + Result run(String query, TransactionConfig config); /** * Run a query with parameters in a managed auto-commit transaction with the @@ -185,7 +183,7 @@ public interface Session extends Resource, QueryRunner * @param config configuration for the new transaction. * @return a stream of result values and associated metadata. */ - Result run(String query, Map parameters, TransactionConfig config ); + Result run(String query, Map parameters, TransactionConfig config); /** * Run a query in a managed auto-commit transaction with the specified @@ -210,7 +208,7 @@ public interface Session extends Resource, QueryRunner * @param config configuration for the new transaction. * @return a stream of result values and associated metadata. */ - Result run(Query query, TransactionConfig config ); + Result run(Query query, TransactionConfig config); /** * Return the bookmark received following the last completed diff --git a/driver/src/main/java/org/neo4j/driver/SessionConfig.java b/driver/src/main/java/org/neo4j/driver/SessionConfig.java index 4286ad28ef..a33d19a2eb 100644 --- a/driver/src/main/java/org/neo4j/driver/SessionConfig.java +++ b/driver/src/main/java/org/neo4j/driver/SessionConfig.java @@ -18,24 +18,21 @@ */ package org.neo4j.driver; -import org.reactivestreams.Subscription; +import static java.util.Objects.requireNonNull; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.assertValidFetchSize; import java.io.Serializable; import java.util.Arrays; import java.util.Objects; import java.util.Optional; - import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.reactive.RxSession; - -import static java.util.Objects.requireNonNull; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.assertValidFetchSize; +import org.reactivestreams.Subscription; /** * The session configurations used to configure a session. */ -public class SessionConfig implements Serializable -{ +public class SessionConfig implements Serializable { private static final long serialVersionUID = 5773462156979050657L; private static final SessionConfig EMPTY = builder().build(); @@ -46,8 +43,7 @@ public class SessionConfig implements Serializable private final Long fetchSize; private final String impersonatedUser; - private SessionConfig( Builder builder ) - { + private SessionConfig(Builder builder) { this.bookmarks = builder.bookmarks; this.defaultAccessMode = builder.defaultAccessMode; this.database = builder.database; @@ -60,8 +56,7 @@ private SessionConfig( Builder builder ) * * @return a session configuration builder. */ - public static Builder builder() - { + public static Builder builder() { return new Builder(); } @@ -70,8 +65,7 @@ public static Builder builder() * * @return a session config for a general purpose session. */ - public static SessionConfig defaultConfig() - { + public static SessionConfig defaultConfig() { return EMPTY; } @@ -80,9 +74,8 @@ public static SessionConfig defaultConfig() * @param database the database the session binds to. * @return a session config for a session for the specified database. */ - public static SessionConfig forDatabase( String database ) - { - return new Builder().withDatabase( database ).build(); + public static SessionConfig forDatabase(String database) { + return new Builder().withDatabase(database).build(); } /** @@ -93,8 +86,7 @@ public static SessionConfig forDatabase( String database ) * * @return the initial bookmarks. */ - public Iterable bookmarks() - { + public Iterable bookmarks() { return bookmarks; } @@ -104,8 +96,7 @@ public Iterable bookmarks() * * @return the access mode. */ - public AccessMode defaultAccessMode() - { + public AccessMode defaultAccessMode() { return defaultAccessMode; } @@ -114,9 +105,8 @@ public AccessMode defaultAccessMode() * * @return the nullable database name where the session is going to connect to. */ - public Optional database() - { - return Optional.ofNullable( database ); + public Optional database() { + return Optional.ofNullable(database); } /** @@ -124,9 +114,8 @@ public Optional database() * * @return an optional value of fetch size. */ - public Optional fetchSize() - { - return Optional.ofNullable( fetchSize ); + public Optional fetchSize() { + return Optional.ofNullable(fetchSize); } /** @@ -134,54 +123,49 @@ public Optional fetchSize() * * @return an optional value of the impersonated user. */ - public Optional impersonatedUser() - { - return Optional.ofNullable( impersonatedUser ); + public Optional impersonatedUser() { + return Optional.ofNullable(impersonatedUser); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } SessionConfig that = (SessionConfig) o; - return Objects.equals( bookmarks, that.bookmarks ) && defaultAccessMode == that.defaultAccessMode && Objects.equals( database, that.database ) - && Objects.equals( fetchSize, that.fetchSize ) && Objects.equals( impersonatedUser, that.impersonatedUser ); + return Objects.equals(bookmarks, that.bookmarks) + && defaultAccessMode == that.defaultAccessMode + && Objects.equals(database, that.database) + && Objects.equals(fetchSize, that.fetchSize) + && Objects.equals(impersonatedUser, that.impersonatedUser); } @Override - public int hashCode() - { - return Objects.hash( bookmarks, defaultAccessMode, database, impersonatedUser ); + public int hashCode() { + return Objects.hash(bookmarks, defaultAccessMode, database, impersonatedUser); } @Override - public String toString() - { - return "SessionParameters{" + "bookmarks=" + bookmarks + ", defaultAccessMode=" + defaultAccessMode + ", database='" + database + '\'' + - ", fetchSize=" + fetchSize + "impersonatedUser=" + impersonatedUser + '}'; + public String toString() { + return "SessionParameters{" + "bookmarks=" + bookmarks + ", defaultAccessMode=" + defaultAccessMode + + ", database='" + database + '\'' + ", fetchSize=" + fetchSize + "impersonatedUser=" + impersonatedUser + + '}'; } /** * Builder used to configure {@link SessionConfig} which will be used to create a session. */ - public static class Builder - { + public static class Builder { private Long fetchSize = null; private Iterable bookmarks = null; private AccessMode defaultAccessMode = AccessMode.WRITE; private String database = null; private String impersonatedUser = null; - private Builder() - { - } + private Builder() {} /** * Set the initial bookmarks to be used in a session. @@ -196,15 +180,11 @@ private Builder() * are permitted, and indicate that the bookmarks do not exist or are unknown. * @return this builder. */ - public Builder withBookmarks( Bookmark... bookmarks ) - { - if ( bookmarks == null ) - { + public Builder withBookmarks(Bookmark... bookmarks) { + if (bookmarks == null) { this.bookmarks = null; - } - else - { - this.bookmarks = Arrays.asList( bookmarks ); + } else { + this.bookmarks = Arrays.asList(bookmarks); } return this; } @@ -220,8 +200,7 @@ public Builder withBookmarks( Bookmark... bookmarks ) * are permitted, and indicate that the bookmarks do not exist or are unknown. * @return this builder */ - public Builder withBookmarks( Iterable bookmarks ) - { + public Builder withBookmarks(Iterable bookmarks) { this.bookmarks = bookmarks; return this; } @@ -234,8 +213,7 @@ public Builder withBookmarks( Iterable bookmarks ) * @param mode access mode. * @return this builder. */ - public Builder withDefaultAccessMode( AccessMode mode ) - { + public Builder withDefaultAccessMode(AccessMode mode) { this.defaultAccessMode = mode; return this; } @@ -252,13 +230,11 @@ public Builder withDefaultAccessMode( AccessMode mode ) * @param database the database the session going to connect to. Provided value should not be {@code null}. * @return this builder. */ - public Builder withDatabase( String database ) - { - requireNonNull( database, "Database name should not be null." ); - if ( database.isEmpty() ) - { + public Builder withDatabase(String database) { + requireNonNull(database, "Database name should not be null."); + if (database.isEmpty()) { // Empty string is an illegal database name. Fail fast on client. - throw new IllegalArgumentException( String.format( "Illegal database name '%s'.", database ) ); + throw new IllegalArgumentException(String.format("Illegal database name '%s'.", database)); } this.database = database; return this; @@ -279,9 +255,8 @@ public Builder withDatabase( String database ) * @param size the default record fetch size when pulling records in batches using Bolt V4. * @return this builder */ - public Builder withFetchSize( long size ) - { - this.fetchSize = assertValidFetchSize( size ); + public Builder withFetchSize(long size) { + this.fetchSize = assertValidFetchSize(size); return this; } @@ -298,21 +273,18 @@ public Builder withFetchSize( long size ) * @param impersonatedUser the user to impersonate. Provided value should not be {@code null}. * @return this builder */ - public Builder withImpersonatedUser( String impersonatedUser ) - { - requireNonNull( impersonatedUser, "Impersonated user should not be null." ); - if ( impersonatedUser.isEmpty() ) - { + public Builder withImpersonatedUser(String impersonatedUser) { + requireNonNull(impersonatedUser, "Impersonated user should not be null."); + if (impersonatedUser.isEmpty()) { // Empty string is an illegal user. Fail fast on client. - throw new IllegalArgumentException( String.format( "Illegal impersonated user '%s'.", impersonatedUser ) ); + throw new IllegalArgumentException(String.format("Illegal impersonated user '%s'.", impersonatedUser)); } this.impersonatedUser = impersonatedUser; return this; } - public SessionConfig build() - { - return new SessionConfig( this ); + public SessionConfig build() { + return new SessionConfig(this); } } } diff --git a/driver/src/main/java/org/neo4j/driver/Transaction.java b/driver/src/main/java/org/neo4j/driver/Transaction.java index cef25e18fd..68844e432c 100644 --- a/driver/src/main/java/org/neo4j/driver/Transaction.java +++ b/driver/src/main/java/org/neo4j/driver/Transaction.java @@ -42,8 +42,7 @@ * @see QueryRunner * @since 1.0 */ -public interface Transaction extends Resource, QueryRunner -{ +public interface Transaction extends Resource, QueryRunner { /** * Commit this current transaction. * When this method returns, all outstanding queries in the transaction are guaranteed to diff --git a/driver/src/main/java/org/neo4j/driver/TransactionConfig.java b/driver/src/main/java/org/neo4j/driver/TransactionConfig.java index fee9943fb3..df0ec569c4 100644 --- a/driver/src/main/java/org/neo4j/driver/TransactionConfig.java +++ b/driver/src/main/java/org/neo4j/driver/TransactionConfig.java @@ -18,21 +18,20 @@ */ package org.neo4j.driver; +import static java.util.Collections.emptyMap; +import static java.util.Collections.unmodifiableMap; +import static java.util.Objects.requireNonNull; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; + import java.io.Serializable; import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.Objects; - import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.AsyncTransactionWork; import org.neo4j.driver.internal.util.Extract; -import static java.util.Collections.emptyMap; -import static java.util.Collections.unmodifiableMap; -import static java.util.Objects.requireNonNull; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - /** * Configuration object containing settings for transactions. * Instances are immutable and can be reused for multiple transactions. @@ -63,20 +62,18 @@ * * @see Session */ -public class TransactionConfig implements Serializable -{ +public class TransactionConfig implements Serializable { private static final long serialVersionUID = -7954949878657177280L; private static final TransactionConfig EMPTY = builder().build(); private final Duration timeout; - private final Map metadata; + private final Map metadata; // Values are not serializable, hence, we keep a transient volatile map of them around private transient volatile Map convertedMetadata; - private TransactionConfig( Builder builder ) - { + private TransactionConfig(Builder builder) { this.timeout = builder.timeout; this.metadata = builder.metadata; } @@ -86,8 +83,7 @@ private TransactionConfig( Builder builder ) * * @return an empty configuration object. */ - public static TransactionConfig empty() - { + public static TransactionConfig empty() { return EMPTY; } @@ -96,8 +92,7 @@ public static TransactionConfig empty() * * @return new builder. */ - public static Builder builder() - { + public static Builder builder() { return new Builder(); } @@ -106,8 +101,7 @@ public static Builder builder() * * @return timeout or {@code null} when it is not configured. */ - public Duration timeout() - { + public Duration timeout() { return timeout; } @@ -116,17 +110,13 @@ public Duration timeout() * * @return metadata or empty map when it is not configured. */ - public Map metadata() - { - Map result = this.convertedMetadata; - if ( result == null ) - { - synchronized ( this ) - { + public Map metadata() { + Map result = this.convertedMetadata; + if (result == null) { + synchronized (this) { result = this.convertedMetadata; - if ( result == null ) - { - this.convertedMetadata = unmodifiableMap( Extract.mapOfValues( this.metadata ) ); + if (result == null) { + this.convertedMetadata = unmodifiableMap(Extract.mapOfValues(this.metadata)); result = this.convertedMetadata; } } @@ -139,53 +129,40 @@ public Map metadata() * * @return {@code true} when no values are configured, {@code false otherwise}. */ - public boolean isEmpty() - { + public boolean isEmpty() { return timeout == null && (metadata == null || metadata.isEmpty()); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } TransactionConfig that = (TransactionConfig) o; - return Objects.equals( timeout, that.timeout ) && - Objects.equals( metadata, that.metadata ); + return Objects.equals(timeout, that.timeout) && Objects.equals(metadata, that.metadata); } @Override - public int hashCode() - { - return Objects.hash( timeout, metadata ); + public int hashCode() { + return Objects.hash(timeout, metadata); } @Override - public String toString() - { - return "TransactionConfig{" + - "timeout=" + timeout + - ", metadata=" + metadata + - '}'; + public String toString() { + return "TransactionConfig{" + "timeout=" + timeout + ", metadata=" + metadata + '}'; } /** * Builder used to construct {@link TransactionConfig transaction configuration} objects. */ - public static class Builder - { + public static class Builder { private Duration timeout; - private Map metadata = emptyMap(); + private Map metadata = emptyMap(); - private Builder() - { - } + private Builder() {} /** * Set the transaction timeout. Transactions that execute longer than the configured timeout will be terminated by the database. @@ -198,11 +175,10 @@ private Builder() * @param timeout the timeout. * @return this builder. */ - public Builder withTimeout( Duration timeout ) - { - requireNonNull( timeout, "Transaction timeout should not be null" ); - checkArgument( !timeout.isZero(), "Transaction timeout should not be zero" ); - checkArgument( !timeout.isNegative(), "Transaction timeout should not be negative" ); + public Builder withTimeout(Duration timeout) { + requireNonNull(timeout, "Transaction timeout should not be null"); + checkArgument(!timeout.isZero(), "Transaction timeout should not be zero"); + checkArgument(!timeout.isNegative(), "Transaction timeout should not be negative"); this.timeout = timeout; return this; @@ -219,11 +195,11 @@ public Builder withTimeout( Duration timeout ) * @param metadata the metadata. * @return this builder. */ - public Builder withMetadata( Map metadata ) - { - requireNonNull( metadata, "Transaction metadata should not be null" ); - metadata.values().forEach( Extract::assertParameter ); // Just assert valid parameters but don't create a value map yet - this.metadata = new HashMap<>( metadata ); // Create a defensive copy + public Builder withMetadata(Map metadata) { + requireNonNull(metadata, "Transaction metadata should not be null"); + metadata.values() + .forEach(Extract::assertParameter); // Just assert valid parameters but don't create a value map yet + this.metadata = new HashMap<>(metadata); // Create a defensive copy return this; } @@ -232,9 +208,8 @@ public Builder withMetadata( Map metadata ) * * @return new transaction configuration object. */ - public TransactionConfig build() - { - return new TransactionConfig( this ); + public TransactionConfig build() { + return new TransactionConfig(this); } } } diff --git a/driver/src/main/java/org/neo4j/driver/TransactionWork.java b/driver/src/main/java/org/neo4j/driver/TransactionWork.java index f78b0a7cc7..eaf324a0fe 100644 --- a/driver/src/main/java/org/neo4j/driver/TransactionWork.java +++ b/driver/src/main/java/org/neo4j/driver/TransactionWork.java @@ -25,13 +25,12 @@ * * @param the return type of this work. */ -public interface TransactionWork -{ +public interface TransactionWork { /** * Executes all given operations against the same transaction. * * @param tx the transaction to use. * @return some result object or {@code null} if none. */ - T execute( Transaction tx ); + T execute(Transaction tx); } diff --git a/driver/src/main/java/org/neo4j/driver/Value.java b/driver/src/main/java/org/neo4j/driver/Value.java index ba39bbdb04..1c6113f0d1 100644 --- a/driver/src/main/java/org/neo4j/driver/Value.java +++ b/driver/src/main/java/org/neo4j/driver/Value.java @@ -26,11 +26,11 @@ import java.time.ZonedDateTime; import java.util.List; import java.util.Map; - -import org.neo4j.driver.internal.value.NullValue; +import java.util.function.Function; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.value.LossyCoercion; import org.neo4j.driver.exceptions.value.Uncoercible; +import org.neo4j.driver.internal.value.NullValue; import org.neo4j.driver.types.Entity; import org.neo4j.driver.types.IsoDuration; import org.neo4j.driver.types.MapAccessor; @@ -42,7 +42,6 @@ import org.neo4j.driver.types.Type; import org.neo4j.driver.types.TypeSystem; import org.neo4j.driver.util.Experimental; -import java.util.function.Function; import org.neo4j.driver.util.Immutable; /** @@ -96,8 +95,7 @@ * @since 1.0 */ @Immutable -public interface Value extends MapAccessor, MapAccessorWithDefaultValue -{ +public interface Value extends MapAccessor, MapAccessorWithDefaultValue { /** * If the underlying value is a collection type, return the number of values in the collection. *

@@ -138,7 +136,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @return the value or a {@link org.neo4j.driver.internal.value.NullValue} if the index is out of bounds * @throws ClientException if record has not been initialized */ - Value get( int index ); + Value get(int index); /** @return The type of this value as defined in the Neo4j type system */ @Experimental @@ -151,7 +149,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @return type.isTypeOf( this ) */ @Experimental - boolean hasType( Type type ); + boolean hasType(Type type); /** * @return {@code true} if the value is a Boolean value and has the value True. @@ -210,7 +208,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @param The return type * @return The value after applying the given mapping function or the default value if the value is {@link NullValue}. */ - T computeOrDefault( Function mapper, T defaultValue ); + T computeOrDefault(Function mapper, T defaultValue); /** * @return the value as a Java boolean, if possible. @@ -223,7 +221,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @return the value as a Java boolean, if possible. * @throws Uncoercible if value types are incompatible. */ - boolean asBoolean( boolean defaultValue ); + boolean asBoolean(boolean defaultValue); /** * @return the value as a Java byte array, if possible. @@ -236,7 +234,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @return the value as a Java byte array, if possible. * @throws Uncoercible if value types are incompatible. */ - byte[] asByteArray( byte[] defaultValue ); + byte[] asByteArray(byte[] defaultValue); /** * @return the value as a Java String, if possible. @@ -249,7 +247,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @return the value as a Java String, if possible * @throws Uncoercible if value types are incompatible. */ - String asString( String defaultValue ); + String asString(String defaultValue); /** * @return the value as a Java Number, if possible. @@ -273,7 +271,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @throws LossyCoercion if it is not possible to convert the value without loosing precision. * @throws Uncoercible if value types are incompatible. */ - long asLong( long defaultValue ); + long asLong(long defaultValue); /** * Returns a Java int if no precision is lost in the conversion. @@ -291,7 +289,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @throws LossyCoercion if it is not possible to convert the value without loosing precision. * @throws Uncoercible if value types are incompatible. */ - int asInt( int defaultValue ); + int asInt(int defaultValue); /** * Returns a Java double if no precision is lost in the conversion. @@ -309,7 +307,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @throws LossyCoercion if it is not possible to convert the value without loosing precision. * @throws Uncoercible if value types are incompatible. */ - double asDouble( double defaultValue ); + double asDouble(double defaultValue); /** * Returns a Java float if no precision is lost in the conversion. @@ -327,7 +325,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @throws LossyCoercion if it is not possible to convert the value without loosing precision. * @throws Uncoercible if value types are incompatible. */ - float asFloat( float defaultValue ); + float asFloat(float defaultValue); /** * If the underlying type can be viewed as a list, returns a java list of @@ -338,7 +336,6 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue */ List asList(); - /** * If the underlying type can be viewed as a list, returns a java list of * values, where each value has been converted using {@link #asObject()}. @@ -347,7 +344,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a Java list of values, if possible */ - List asList( List defaultValue ); + List asList(List defaultValue); /** * @param mapFunction a function to map from Value to T. See {@link Values} for some predefined functions, such @@ -356,7 +353,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @see Values for a long list of built-in conversion functions * @return the value as a list of T obtained by mapping from the list elements, if possible */ - List asList( Function mapFunction ); + List asList(Function mapFunction); /** * @param mapFunction a function to map from Value to T. See {@link Values} for some predefined functions, such @@ -366,7 +363,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @see Values for a long list of built-in conversion functions * @return the value as a list of T obtained by mapping from the list elements, if possible */ - List asList( Function mapFunction, List defaultValue ); + List asList(Function mapFunction, List defaultValue); /** * @return the value as a {@link Entity}, if possible. @@ -445,56 +442,56 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @return the value as a {@link LocalDate}, if possible. * @throws Uncoercible if value types are incompatible. */ - LocalDate asLocalDate( LocalDate defaultValue ); + LocalDate asLocalDate(LocalDate defaultValue); /** * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a {@link OffsetTime}, if possible. * @throws Uncoercible if value types are incompatible. */ - OffsetTime asOffsetTime( OffsetTime defaultValue ); + OffsetTime asOffsetTime(OffsetTime defaultValue); /** * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a {@link LocalTime}, if possible. * @throws Uncoercible if value types are incompatible. */ - LocalTime asLocalTime( LocalTime defaultValue ); + LocalTime asLocalTime(LocalTime defaultValue); /** * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a {@link LocalDateTime}, if possible. * @throws Uncoercible if value types are incompatible. */ - LocalDateTime asLocalDateTime( LocalDateTime defaultValue ); + LocalDateTime asLocalDateTime(LocalDateTime defaultValue); /** * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a {@link OffsetDateTime}, if possible. * @throws Uncoercible if value types are incompatible. */ - OffsetDateTime asOffsetDateTime( OffsetDateTime defaultValue ); + OffsetDateTime asOffsetDateTime(OffsetDateTime defaultValue); /** * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a {@link ZonedDateTime}, if possible. * @throws Uncoercible if value types are incompatible. */ - ZonedDateTime asZonedDateTime( ZonedDateTime defaultValue ); + ZonedDateTime asZonedDateTime(ZonedDateTime defaultValue); /** * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a {@link IsoDuration}, if possible. * @throws Uncoercible if value types are incompatible. */ - IsoDuration asIsoDuration( IsoDuration defaultValue ); + IsoDuration asIsoDuration(IsoDuration defaultValue); /** * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a {@link Point}, if possible. * @throws Uncoercible if value types are incompatible. */ - Point asPoint( Point defaultValue ); + Point asPoint(Point defaultValue); /** * Return as a map of string keys and values converted using @@ -505,7 +502,7 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @param defaultValue default to this value if the value is a {@link NullValue} * @return the value as a Java map */ - Map asMap( Map defaultValue ); + Map asMap(Map defaultValue); /** * @param mapFunction a function to map from Value to T. See {@link Values} for some predefined functions, such @@ -515,10 +512,10 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue * @see Values for a long list of built-in conversion functions * @return the value as a map from string keys to values of type T obtained from mapping he original map values, if possible */ - Map asMap( Function mapFunction, Map defaultValue ); + Map asMap(Function mapFunction, Map defaultValue); @Override - boolean equals( Object other ); + boolean equals(Object other); @Override int hashCode(); diff --git a/driver/src/main/java/org/neo4j/driver/Values.java b/driver/src/main/java/org/neo4j/driver/Values.java index bad07fa4ca..9c6b9d0699 100644 --- a/driver/src/main/java/org/neo4j/driver/Values.java +++ b/driver/src/main/java/org/neo4j/driver/Values.java @@ -18,6 +18,9 @@ */ package org.neo4j.driver; +import static org.neo4j.driver.internal.util.Extract.assertParameter; +import static org.neo4j.driver.internal.util.Iterables.newHashMapWithSize; + import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; @@ -34,8 +37,9 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Stream; - +import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.AsValue; import org.neo4j.driver.internal.InternalIsoDuration; import org.neo4j.driver.internal.InternalPoint2D; @@ -55,7 +59,6 @@ import org.neo4j.driver.internal.value.PointValue; import org.neo4j.driver.internal.value.StringValue; import org.neo4j.driver.internal.value.TimeValue; -import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.types.Entity; import org.neo4j.driver.types.IsoDuration; import org.neo4j.driver.types.MapAccessor; @@ -64,10 +67,6 @@ import org.neo4j.driver.types.Point; import org.neo4j.driver.types.Relationship; import org.neo4j.driver.types.TypeSystem; -import java.util.function.Function; - -import static org.neo4j.driver.internal.util.Extract.assertParameter; -import static org.neo4j.driver.internal.util.Iterables.newHashMapWithSize; /** * Utility for wrapping regular Java types and exposing them as {@link Value} @@ -79,301 +78,325 @@ * * @since 1.0 */ -public abstract class Values -{ - public static final Value EmptyMap = value( Collections.emptyMap() ); +public abstract class Values { + public static final Value EmptyMap = value(Collections.emptyMap()); public static final Value NULL = NullValue.NULL; - private Values() - { + private Values() { throw new UnsupportedOperationException(); } - @SuppressWarnings( "unchecked" ) - public static Value value( Object value ) - { - if ( value == null ) { return NullValue.NULL; } - - if ( value instanceof AsValue ) { return ((AsValue) value).asValue(); } - if ( value instanceof Boolean ) { return value( (boolean) value ); } - if ( value instanceof String ) { return value( (String) value ); } - if ( value instanceof Character ) { return value( (char) value ); } - if ( value instanceof Long ) { return value( (long) value ); } - if ( value instanceof Short ) { return value( (short) value ); } - if ( value instanceof Byte ) { return value( (byte) value ); } - if ( value instanceof Integer ) { return value( (int) value ); } - if ( value instanceof Double ) { return value( (double) value ); } - if ( value instanceof Float ) { return value( (float) value ); } - if ( value instanceof LocalDate ) { return value( (LocalDate) value ); } - if ( value instanceof OffsetTime ) { return value( (OffsetTime) value ); } - if ( value instanceof LocalTime ) { return value( (LocalTime) value ); } - if ( value instanceof LocalDateTime ) { return value( (LocalDateTime) value ); } - if ( value instanceof OffsetDateTime ) { return value( (OffsetDateTime) value ); } - if ( value instanceof ZonedDateTime ) { return value( (ZonedDateTime) value ); } - if ( value instanceof IsoDuration ) { return value( (IsoDuration) value ); } - if ( value instanceof Period ) { return value( (Period) value ); } - if ( value instanceof Duration ) { return value( (Duration) value ); } - if ( value instanceof Point ) { return value( (Point) value ); } - - if ( value instanceof List ) { return value( (List) value ); } - if ( value instanceof Map ) { return value( (Map) value ); } - if ( value instanceof Iterable ) { return value( (Iterable) value ); } - if ( value instanceof Iterator ) { return value( (Iterator) value ); } - if ( value instanceof Stream ) { return value( (Stream) value ); } - - if ( value instanceof char[] ) { return value( (char[]) value ); } - if ( value instanceof byte[] ) { return value( (byte[]) value ); } - if ( value instanceof boolean[] ) { return value( (boolean[]) value ); } - if ( value instanceof String[] ) { return value( (String[]) value ); } - if ( value instanceof long[] ) { return value( (long[]) value ); } - if ( value instanceof int[] ) { return value( (int[]) value ); } - if ( value instanceof short[] ) { return value( (short[]) value ); } - if ( value instanceof double[] ) { return value( (double[]) value ); } - if ( value instanceof float[] ) { return value( (float[]) value ); } - if ( value instanceof Value[] ) { return value( (Value[]) value ); } - if ( value instanceof Object[] ) { return value( Arrays.asList( (Object[]) value ) ); } - - throw new ClientException( "Unable to convert " + value.getClass().getName() + " to Neo4j Value." ); - } - - public static Value[] values( final Object... input ) - { + @SuppressWarnings("unchecked") + public static Value value(Object value) { + if (value == null) { + return NullValue.NULL; + } + + if (value instanceof AsValue) { + return ((AsValue) value).asValue(); + } + if (value instanceof Boolean) { + return value((boolean) value); + } + if (value instanceof String) { + return value((String) value); + } + if (value instanceof Character) { + return value((char) value); + } + if (value instanceof Long) { + return value((long) value); + } + if (value instanceof Short) { + return value((short) value); + } + if (value instanceof Byte) { + return value((byte) value); + } + if (value instanceof Integer) { + return value((int) value); + } + if (value instanceof Double) { + return value((double) value); + } + if (value instanceof Float) { + return value((float) value); + } + if (value instanceof LocalDate) { + return value((LocalDate) value); + } + if (value instanceof OffsetTime) { + return value((OffsetTime) value); + } + if (value instanceof LocalTime) { + return value((LocalTime) value); + } + if (value instanceof LocalDateTime) { + return value((LocalDateTime) value); + } + if (value instanceof OffsetDateTime) { + return value((OffsetDateTime) value); + } + if (value instanceof ZonedDateTime) { + return value((ZonedDateTime) value); + } + if (value instanceof IsoDuration) { + return value((IsoDuration) value); + } + if (value instanceof Period) { + return value((Period) value); + } + if (value instanceof Duration) { + return value((Duration) value); + } + if (value instanceof Point) { + return value((Point) value); + } + + if (value instanceof List) { + return value((List) value); + } + if (value instanceof Map) { + return value((Map) value); + } + if (value instanceof Iterable) { + return value((Iterable) value); + } + if (value instanceof Iterator) { + return value((Iterator) value); + } + if (value instanceof Stream) { + return value((Stream) value); + } + + if (value instanceof char[]) { + return value((char[]) value); + } + if (value instanceof byte[]) { + return value((byte[]) value); + } + if (value instanceof boolean[]) { + return value((boolean[]) value); + } + if (value instanceof String[]) { + return value((String[]) value); + } + if (value instanceof long[]) { + return value((long[]) value); + } + if (value instanceof int[]) { + return value((int[]) value); + } + if (value instanceof short[]) { + return value((short[]) value); + } + if (value instanceof double[]) { + return value((double[]) value); + } + if (value instanceof float[]) { + return value((float[]) value); + } + if (value instanceof Value[]) { + return value((Value[]) value); + } + if (value instanceof Object[]) { + return value(Arrays.asList((Object[]) value)); + } + + throw new ClientException("Unable to convert " + value.getClass().getName() + " to Neo4j Value."); + } + + public static Value[] values(final Object... input) { Value[] values = new Value[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = value( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = value(input[i]); } return values; } - public static Value value( Value... input ) - { + public static Value value(Value... input) { int size = input.length; Value[] values = new Value[size]; - System.arraycopy( input, 0, values, 0, size ); - return new ListValue( values ); + System.arraycopy(input, 0, values, 0, size); + return new ListValue(values); } - public static BytesValue value( byte... input ) - { - return new BytesValue( input ); + public static BytesValue value(byte... input) { + return new BytesValue(input); } - public static Value value( String... input ) - { + public static Value value(String... input) { StringValue[] values = new StringValue[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = new StringValue( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = new StringValue(input[i]); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( boolean... input ) - { + public static Value value(boolean... input) { Value[] values = new Value[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = value( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = value(input[i]); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( char... input ) - { + public static Value value(char... input) { Value[] values = new Value[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = value( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = value(input[i]); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( long... input ) - { + public static Value value(long... input) { Value[] values = new Value[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = value( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = value(input[i]); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( short... input ) - { + public static Value value(short... input) { Value[] values = new Value[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = value( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = value(input[i]); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( int... input ) - { + public static Value value(int... input) { Value[] values = new Value[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = value( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = value(input[i]); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( double... input ) - { + public static Value value(double... input) { Value[] values = new Value[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = value( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = value(input[i]); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( float... input ) - { + public static Value value(float... input) { Value[] values = new Value[input.length]; - for ( int i = 0; i < input.length; i++ ) - { - values[i] = value( input[i] ); + for (int i = 0; i < input.length; i++) { + values[i] = value(input[i]); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( List vals ) - { + public static Value value(List vals) { Value[] values = new Value[vals.size()]; int i = 0; - for ( Object val : vals ) - { - values[i++] = value( val ); + for (Object val : vals) { + values[i++] = value(val); } - return new ListValue( values ); + return new ListValue(values); } - public static Value value( Iterable val ) - { - return value( val.iterator() ); + public static Value value(Iterable val) { + return value(val.iterator()); } - public static Value value( Iterator val ) - { + public static Value value(Iterator val) { List values = new ArrayList<>(); - while ( val.hasNext() ) - { - values.add( value( val.next() ) ); + while (val.hasNext()) { + values.add(value(val.next())); } - return new ListValue( values.toArray( new Value[0] ) ); + return new ListValue(values.toArray(new Value[0])); } - public static Value value( Stream stream ) - { - Value[] values = stream.map( Values::value ).toArray( Value[]::new ); - return new ListValue( values ); + public static Value value(Stream stream) { + Value[] values = stream.map(Values::value).toArray(Value[]::new); + return new ListValue(values); } - public static Value value( final char val ) - { - return new StringValue( String.valueOf( val ) ); + public static Value value(final char val) { + return new StringValue(String.valueOf(val)); } - public static Value value( final String val ) - { - return new StringValue( val ); + public static Value value(final String val) { + return new StringValue(val); } - public static Value value( final long val ) - { - return new IntegerValue( val ); + public static Value value(final long val) { + return new IntegerValue(val); } - public static Value value( final int val ) - { - return new IntegerValue( val ); + public static Value value(final int val) { + return new IntegerValue(val); } - public static Value value( final double val ) - { - return new FloatValue( val ); + public static Value value(final double val) { + return new FloatValue(val); } - public static Value value( final boolean val ) - { - return BooleanValue.fromBoolean( val ); + public static Value value(final boolean val) { + return BooleanValue.fromBoolean(val); } - public static Value value( final Map val ) - { - Map asValues = newHashMapWithSize( val.size() ); - for ( Map.Entry entry : val.entrySet() ) - { - asValues.put( entry.getKey(), value( entry.getValue() ) ); + public static Value value(final Map val) { + Map asValues = newHashMapWithSize(val.size()); + for (Map.Entry entry : val.entrySet()) { + asValues.put(entry.getKey(), value(entry.getValue())); } - return new MapValue( asValues ); + return new MapValue(asValues); } - public static Value value( LocalDate localDate ) - { - return new DateValue( localDate ); + public static Value value(LocalDate localDate) { + return new DateValue(localDate); } - public static Value value( OffsetTime offsetTime ) - { - return new TimeValue( offsetTime ); + public static Value value(OffsetTime offsetTime) { + return new TimeValue(offsetTime); } - public static Value value( LocalTime localTime ) - { - return new LocalTimeValue( localTime ); + public static Value value(LocalTime localTime) { + return new LocalTimeValue(localTime); } - public static Value value( LocalDateTime localDateTime ) - { - return new LocalDateTimeValue( localDateTime ); + public static Value value(LocalDateTime localDateTime) { + return new LocalDateTimeValue(localDateTime); } - public static Value value( OffsetDateTime offsetDateTime ) - { - return new DateTimeValue( offsetDateTime.toZonedDateTime() ); + public static Value value(OffsetDateTime offsetDateTime) { + return new DateTimeValue(offsetDateTime.toZonedDateTime()); } - public static Value value( ZonedDateTime zonedDateTime ) - { - return new DateTimeValue( zonedDateTime ); + public static Value value(ZonedDateTime zonedDateTime) { + return new DateTimeValue(zonedDateTime); } - public static Value value( Period period ) - { - return value( new InternalIsoDuration( period ) ); + public static Value value(Period period) { + return value(new InternalIsoDuration(period)); } - public static Value value( Duration duration ) - { - return value( new InternalIsoDuration( duration ) ); + public static Value value(Duration duration) { + return value(new InternalIsoDuration(duration)); } - public static Value isoDuration( long months, long days, long seconds, int nanoseconds ) - { - return value( new InternalIsoDuration( months, days, seconds, nanoseconds ) ); + public static Value isoDuration(long months, long days, long seconds, int nanoseconds) { + return value(new InternalIsoDuration(months, days, seconds, nanoseconds)); } - private static Value value( IsoDuration duration ) - { - return new DurationValue( duration ); + private static Value value(IsoDuration duration) { + return new DurationValue(duration); } - public static Value point( int srid, double x, double y ) - { - return value( new InternalPoint2D( srid, x, y ) ); + public static Value point(int srid, double x, double y) { + return value(new InternalPoint2D(srid, x, y)); } - private static Value value( Point point ) - { - return new PointValue( point ); + private static Value value(Point point) { + return new PointValue(point); } - public static Value point( int srid, double x, double y, double z ) - { - return value( new InternalPoint3D( srid, x, y, z ) ); + public static Value point(int srid, double x, double y, double z) { + return value(new InternalPoint3D(srid, x, y, z)); } /** @@ -396,23 +419,20 @@ public static Value point( int srid, double x, double y, double z ) * @return Map containing all parameters specified * @see QueryRunner#run(String, Value) */ - public static Value parameters( Object... keysAndValues ) - { - if ( keysAndValues.length % 2 != 0 ) - { - throw new ClientException( "Parameters function requires an even number " + - "of arguments, " + - "alternating key and value. Arguments were: " + - Arrays.toString( keysAndValues ) + "." ); - } - HashMap map = newHashMapWithSize( keysAndValues.length / 2 ); - for ( int i = 0; i < keysAndValues.length; i += 2 ) - { + public static Value parameters(Object... keysAndValues) { + if (keysAndValues.length % 2 != 0) { + throw new ClientException("Parameters function requires an even number " + "of arguments, " + + "alternating key and value. Arguments were: " + + Arrays.toString(keysAndValues) + + "."); + } + HashMap map = newHashMapWithSize(keysAndValues.length / 2); + for (int i = 0; i < keysAndValues.length; i += 2) { Object value = keysAndValues[i + 1]; - assertParameter( value ); - map.put( keysAndValues[i].toString(), value( value ) ); + assertParameter(value); + map.put(keysAndValues[i].toString(), value(value)); } - return value( map ); + return value(map); } /** @@ -420,8 +440,7 @@ public static Value parameters( Object... keysAndValues ) * * @return a function that returns the value passed into it - the identity function */ - public static Function ofValue() - { + public static Function ofValue() { return val -> val; } @@ -430,8 +449,7 @@ public static Function ofValue() * * @return a function that returns {@link Value#asObject()} of a {@link Value} */ - public static Function ofObject() - { + public static Function ofObject() { return Value::asObject; } @@ -440,8 +458,7 @@ public static Function ofObject() * * @return a function that returns {@link Value#asNumber()} of a {@link Value} */ - public static Function ofNumber() - { + public static Function ofNumber() { return Value::asNumber; } @@ -454,8 +471,7 @@ public static Function ofNumber() * * @return a function that returns {@link Value#asString()} of a {@link Value} */ - public static Function ofString() - { + public static Function ofString() { return Value::asString; } @@ -472,8 +488,7 @@ public static Function ofString() * * @return a function that returns {@link Value#toString()} of a {@link Value} */ - public static Function ofToString() - { + public static Function ofToString() { return Value::toString; } @@ -482,8 +497,7 @@ public static Function ofToString() * * @return a function that returns {@link Value#asInt()} of a {@link Value} */ - public static Function ofInteger() - { + public static Function ofInteger() { return Value::asInt; } @@ -492,8 +506,7 @@ public static Function ofInteger() * * @return a function that returns {@link Value#asLong()} of a {@link Value} */ - public static Function ofLong() - { + public static Function ofLong() { return Value::asLong; } @@ -502,8 +515,7 @@ public static Function ofLong() * * @return a function that returns {@link Value#asFloat()} of a {@link Value} */ - public static Function ofFloat() - { + public static Function ofFloat() { return Value::asFloat; } @@ -512,8 +524,7 @@ public static Function ofFloat() * * @return a function that returns {@link Value#asDouble()} of a {@link Value} */ - public static Function ofDouble() - { + public static Function ofDouble() { return Value::asDouble; } @@ -522,8 +533,7 @@ public static Function ofDouble() * * @return a function that returns {@link Value#asBoolean()} of a {@link Value} */ - public static Function ofBoolean() - { + public static Function ofBoolean() { return Value::asBoolean; } @@ -532,8 +542,7 @@ public static Function ofBoolean() * * @return a function that returns {@link Value#asMap()} of a {@link Value} */ - public static Function> ofMap() - { + public static Function> ofMap() { return MapAccessor::asMap; } @@ -545,9 +554,8 @@ public static Function> ofMap() * @param the type of values in the returned map * @return a function that returns {@link Value#asMap(Function)} of a {@link Value} */ - public static Function> ofMap( final Function valueConverter ) - { - return val -> val.asMap( valueConverter ); + public static Function> ofMap(final Function valueConverter) { + return val -> val.asMap(valueConverter); } /** @@ -555,8 +563,7 @@ public static Function> ofMap( final Function v * * @return a function that returns {@link Value#asEntity()} of a {@link Value} */ - public static Function ofEntity() - { + public static Function ofEntity() { return Value::asEntity; } @@ -565,8 +572,7 @@ public static Function ofEntity() * * @return a function that returns the id an entity {@link Value} */ - public static Function ofEntityId() - { + public static Function ofEntityId() { return val -> val.asEntity().id(); } @@ -575,8 +581,7 @@ public static Function ofEntityId() * * @return a function that returns {@link Value#asNode()} of a {@link Value} */ - public static Function ofNode() - { + public static Function ofNode() { return Value::asNode; } @@ -585,8 +590,7 @@ public static Function ofNode() * * @return a function that returns {@link Value#asRelationship()} of a {@link Value} */ - public static Function ofRelationship() - { + public static Function ofRelationship() { return Value::asRelationship; } @@ -595,8 +599,7 @@ public static Function ofRelationship() * * @return a function that returns {@link Value#asPath()} of a {@link Value} */ - public static Function ofPath() - { + public static Function ofPath() { return Value::asPath; } @@ -605,8 +608,7 @@ public static Function ofPath() * * @return a function that returns {@link Value#asLocalDate()} of a {@link Value} */ - public static Function ofLocalDate() - { + public static Function ofLocalDate() { return Value::asLocalDate; } @@ -615,8 +617,7 @@ public static Function ofLocalDate() * * @return a function that returns {@link Value#asOffsetTime()} of a {@link Value} */ - public static Function ofOffsetTime() - { + public static Function ofOffsetTime() { return Value::asOffsetTime; } @@ -625,8 +626,7 @@ public static Function ofOffsetTime() * * @return a function that returns {@link Value#asLocalTime()} of a {@link Value} */ - public static Function ofLocalTime() - { + public static Function ofLocalTime() { return Value::asLocalTime; } @@ -635,8 +635,7 @@ public static Function ofLocalTime() * * @return a function that returns {@link Value#asLocalDateTime()} of a {@link Value} */ - public static Function ofLocalDateTime() - { + public static Function ofLocalDateTime() { return Value::asLocalDateTime; } @@ -645,8 +644,7 @@ public static Function ofLocalDateTime() * * @return a function that returns {@link Value#asOffsetDateTime()} of a {@link Value} */ - public static Function ofOffsetDateTime() - { + public static Function ofOffsetDateTime() { return Value::asOffsetDateTime; } @@ -655,8 +653,7 @@ public static Function ofOffsetDateTime() * * @return a function that returns {@link Value#asZonedDateTime()} of a {@link Value} */ - public static Function ofZonedDateTime() - { + public static Function ofZonedDateTime() { return Value::asZonedDateTime; } @@ -665,8 +662,7 @@ public static Function ofZonedDateTime() * * @return a function that returns {@link Value#asIsoDuration()} of a {@link Value} */ - public static Function ofIsoDuration() - { + public static Function ofIsoDuration() { return Value::asIsoDuration; } @@ -675,8 +671,7 @@ public static Function ofIsoDuration() * * @return a function that returns {@link Value#asPoint()} of a {@link Value} */ - public static Function ofPoint() - { + public static Function ofPoint() { return Value::asPoint; } @@ -685,8 +680,7 @@ public static Function ofPoint() * * @return a function that returns {@link Value#asList()} of a {@link Value} */ - public static Function> ofList() - { + public static Function> ofList() { return Value::asList; } @@ -697,8 +691,7 @@ public static Function> ofList() * @param the type of values inside the list * @return a function that returns {@link Value#asList(Function)} of a {@link Value} */ - public static Function> ofList( final Function innerMap ) - { - return value -> value.asList( innerMap ); + public static Function> ofList(final Function innerMap) { + return value -> value.asList(innerMap); } } diff --git a/driver/src/main/java/org/neo4j/driver/async/AsyncQueryRunner.java b/driver/src/main/java/org/neo4j/driver/async/AsyncQueryRunner.java index c4bcb996fb..a7bae2cae6 100644 --- a/driver/src/main/java/org/neo4j/driver/async/AsyncQueryRunner.java +++ b/driver/src/main/java/org/neo4j/driver/async/AsyncQueryRunner.java @@ -23,7 +23,6 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.Executor; import java.util.function.Function; - import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -80,8 +79,7 @@ * @see AsyncTransaction * @since 4.0 */ -public interface AsyncQueryRunner -{ +public interface AsyncQueryRunner { /** * Run a query asynchronously and return a {@link CompletionStage} with a * result cursor. @@ -114,7 +112,7 @@ public interface AsyncQueryRunner * @return new {@link CompletionStage} that gets completed with a result cursor when query execution is successful. * Stage can be completed exceptionally when error happens, e.g. connection can't be acquired from the pool. */ - CompletionStage runAsync(String query, Value parameters ); + CompletionStage runAsync(String query, Value parameters); /** * Run a query asynchronously and return a {@link CompletionStage} with a @@ -148,7 +146,7 @@ public interface AsyncQueryRunner * @return new {@link CompletionStage} that gets completed with a result cursor when query execution is successful. * Stage can be completed exceptionally when error happens, e.g. connection can't be acquired from the pool. */ - CompletionStage runAsync(String query, Map parameters ); + CompletionStage runAsync(String query, Map parameters); /** * Run a query asynchronously and return a {@link CompletionStage} with a @@ -170,7 +168,7 @@ public interface AsyncQueryRunner * @return new {@link CompletionStage} that gets completed with a result cursor when query execution is successful. * Stage can be completed exceptionally when error happens, e.g. connection can't be acquired from the pool. */ - CompletionStage runAsync(String query, Record parameters ); + CompletionStage runAsync(String query, Record parameters); /** * Run a query asynchronously and return a {@link CompletionStage} with a @@ -183,7 +181,7 @@ public interface AsyncQueryRunner * @return new {@link CompletionStage} that gets completed with a result cursor when query execution is successful. * Stage can be completed exceptionally when error happens, e.g. connection can't be acquired from the pool. */ - CompletionStage runAsync(String query ); + CompletionStage runAsync(String query); /** * Run a query asynchronously and return a {@link CompletionStage} with a diff --git a/driver/src/main/java/org/neo4j/driver/async/AsyncSession.java b/driver/src/main/java/org/neo4j/driver/async/AsyncSession.java index a925612066..3f8124780b 100644 --- a/driver/src/main/java/org/neo4j/driver/async/AsyncSession.java +++ b/driver/src/main/java/org/neo4j/driver/async/AsyncSession.java @@ -23,13 +23,12 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.Executor; import java.util.function.Function; - import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; import org.neo4j.driver.Transaction; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.Values; -import org.neo4j.driver.Bookmark; /** * Provides a context of work for database interactions. @@ -69,8 +68,7 @@ * * @since 4.0 */ -public interface AsyncSession extends AsyncQueryRunner -{ +public interface AsyncSession extends AsyncQueryRunner { /** * Begin a new unmanaged {@linkplain Transaction transaction}. At * most one transaction may exist in a session at any point in time. To @@ -111,7 +109,7 @@ public interface AsyncSession extends AsyncQueryRunner * @param config configuration for the new transaction. * @return a {@link CompletionStage completion stage} that represents the asynchronous begin of a transaction. */ - CompletionStage beginTransactionAsync( TransactionConfig config ); + CompletionStage beginTransactionAsync(TransactionConfig config); /** * Execute given unit of asynchronous work in a {@link AccessMode#READ read} asynchronous transaction. @@ -134,7 +132,7 @@ public interface AsyncSession extends AsyncQueryRunner * @return a {@link CompletionStage completion stage} completed with the same result as returned by the given * unit of work. Stage can be completed exceptionally if given work or commit fails. */ - CompletionStage readTransactionAsync( AsyncTransactionWork> work ); + CompletionStage readTransactionAsync(AsyncTransactionWork> work); /** * Execute given unit of asynchronous work in a {@link AccessMode#READ read} asynchronous transaction with @@ -159,7 +157,8 @@ public interface AsyncSession extends AsyncQueryRunner * @return a {@link CompletionStage completion stage} completed with the same result as returned by the given * unit of work. Stage can be completed exceptionally if given work or commit fails. */ - CompletionStage readTransactionAsync( AsyncTransactionWork> work, TransactionConfig config ); + CompletionStage readTransactionAsync( + AsyncTransactionWork> work, TransactionConfig config); /** * Execute given unit of asynchronous work in a {@link AccessMode#WRITE write} asynchronous transaction. @@ -182,7 +181,7 @@ public interface AsyncSession extends AsyncQueryRunner * @return a {@link CompletionStage completion stage} completed with the same result as returned by the given * unit of work. Stage can be completed exceptionally if given work or commit fails. */ - CompletionStage writeTransactionAsync( AsyncTransactionWork> work ); + CompletionStage writeTransactionAsync(AsyncTransactionWork> work); /** * Execute given unit of asynchronous work in a {@link AccessMode#WRITE write} asynchronous transaction with @@ -207,7 +206,8 @@ public interface AsyncSession extends AsyncQueryRunner * @return a {@link CompletionStage completion stage} completed with the same result as returned by the given * unit of work. Stage can be completed exceptionally if given work or commit fails. */ - CompletionStage writeTransactionAsync( AsyncTransactionWork> work, TransactionConfig config ); + CompletionStage writeTransactionAsync( + AsyncTransactionWork> work, TransactionConfig config); /** * Run a query asynchronously in an auto-commit transaction with the specified {@link TransactionConfig configuration} and return a @@ -221,7 +221,7 @@ public interface AsyncSession extends AsyncQueryRunner * @return new {@link CompletionStage} that gets completed with a result cursor when query execution is successful. * Stage can be completed exceptionally when error happens, e.g. connection can't be acquired from the pool. */ - CompletionStage runAsync( String query, TransactionConfig config ); + CompletionStage runAsync(String query, TransactionConfig config); /** * Run a query asynchronously in an auto-commit transaction with the specified {@link TransactionConfig configuration} and return a @@ -264,7 +264,7 @@ public interface AsyncSession extends AsyncQueryRunner * @return new {@link CompletionStage} that gets completed with a result cursor when query execution is successful. * Stage can be completed exceptionally when error happens, e.g. connection can't be acquired from the pool. */ - CompletionStage runAsync( String query, Map parameters, TransactionConfig config ); + CompletionStage runAsync(String query, Map parameters, TransactionConfig config); /** * Run a query asynchronously in an auto-commit transaction with the specified {@link TransactionConfig configuration} and return a @@ -292,7 +292,7 @@ public interface AsyncSession extends AsyncQueryRunner * @return new {@link CompletionStage} that gets completed with a result cursor when query execution is successful. * Stage can be completed exceptionally when error happens, e.g. connection can't be acquired from the pool. */ - CompletionStage runAsync( Query query, TransactionConfig config ); + CompletionStage runAsync(Query query, TransactionConfig config); /** * Return the bookmark received following the last completed diff --git a/driver/src/main/java/org/neo4j/driver/async/AsyncTransaction.java b/driver/src/main/java/org/neo4j/driver/async/AsyncTransaction.java index 7a0f333403..a10310e4bd 100644 --- a/driver/src/main/java/org/neo4j/driver/async/AsyncTransaction.java +++ b/driver/src/main/java/org/neo4j/driver/async/AsyncTransaction.java @@ -22,7 +22,6 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.Executor; import java.util.function.Function; - import org.neo4j.driver.Query; import org.neo4j.driver.QueryRunner; import org.neo4j.driver.Session; @@ -55,8 +54,7 @@ * @see QueryRunner * @since 4.0 */ -public interface AsyncTransaction extends AsyncQueryRunner -{ +public interface AsyncTransaction extends AsyncQueryRunner { /** * Commit this transaction in asynchronous fashion. This operation is typically executed as part of the * {@link CompletionStage} chain that starts with a transaction. diff --git a/driver/src/main/java/org/neo4j/driver/async/AsyncTransactionWork.java b/driver/src/main/java/org/neo4j/driver/async/AsyncTransactionWork.java index fc9a29cb91..59069b4dc6 100644 --- a/driver/src/main/java/org/neo4j/driver/async/AsyncTransactionWork.java +++ b/driver/src/main/java/org/neo4j/driver/async/AsyncTransactionWork.java @@ -26,13 +26,12 @@ * @param the return type of this work. * @since 4.0 */ -public interface AsyncTransactionWork -{ +public interface AsyncTransactionWork { /** * Executes all given operations against the same transaction. * * @param tx the transaction to use. * @return some result object or {@code null} if none. */ - T execute( AsyncTransaction tx ); + T execute(AsyncTransaction tx); } diff --git a/driver/src/main/java/org/neo4j/driver/async/ResultCursor.java b/driver/src/main/java/org/neo4j/driver/async/ResultCursor.java index 8129cf231c..de07d4af21 100644 --- a/driver/src/main/java/org/neo4j/driver/async/ResultCursor.java +++ b/driver/src/main/java/org/neo4j/driver/async/ResultCursor.java @@ -24,7 +24,6 @@ import java.util.concurrent.Executor; import java.util.function.Consumer; import java.util.function.Function; - import org.neo4j.driver.Record; import org.neo4j.driver.Records; import org.neo4j.driver.Result; @@ -61,8 +60,7 @@ * * @since 1.5 */ -public interface ResultCursor -{ +public interface ResultCursor { /** * Retrieve the keys of the records this result cursor contains. * @@ -117,7 +115,7 @@ public interface ResultCursor * @return a {@link CompletionStage} completed with a summary for the whole query result. Stage can also be * completed exceptionally if query execution or provided function fails. */ - CompletionStage forEachAsync( Consumer action ); + CompletionStage forEachAsync(Consumer action); /** * Asynchronously retrieve and store the entire result stream. @@ -153,5 +151,5 @@ public interface ResultCursor * @return a {@link CompletionStage} completed with a list of all remaining immutable records. Stage can also be * completed exceptionally if query execution or provided function fails. */ - CompletionStage> listAsync( Function mapFunction ); + CompletionStage> listAsync(Function mapFunction); } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/AuthenticationException.java b/driver/src/main/java/org/neo4j/driver/exceptions/AuthenticationException.java index a25a851816..6be2924da6 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/AuthenticationException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/AuthenticationException.java @@ -25,10 +25,8 @@ * * @since 1.1 */ -public class AuthenticationException extends SecurityException -{ - public AuthenticationException( String code, String message ) - { - super( code, message ); +public class AuthenticationException extends SecurityException { + public AuthenticationException(String code, String message) { + super(code, message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/AuthorizationExpiredException.java b/driver/src/main/java/org/neo4j/driver/exceptions/AuthorizationExpiredException.java index 451ec7667d..65a562be4e 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/AuthorizationExpiredException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/AuthorizationExpiredException.java @@ -23,12 +23,11 @@ *

* Error code: Neo.ClientError.Security.AuthorizationExpired */ -public class AuthorizationExpiredException extends SecurityException -{ - public static final String DESCRIPTION = "Authorization information kept on the server has expired, this connection is no longer valid."; +public class AuthorizationExpiredException extends SecurityException { + public static final String DESCRIPTION = + "Authorization information kept on the server has expired, this connection is no longer valid."; - public AuthorizationExpiredException( String code, String message ) - { - super( code, message ); + public AuthorizationExpiredException(String code, String message) { + super(code, message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/ClientException.java b/driver/src/main/java/org/neo4j/driver/exceptions/ClientException.java index eeebc89a90..9fb1a21069 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/ClientException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/ClientException.java @@ -23,20 +23,16 @@ * The error code provided can be used to determine further detail for the problem. * @since 1.0 */ -public class ClientException extends Neo4jException -{ - public ClientException( String message ) - { - super( message ); +public class ClientException extends Neo4jException { + public ClientException(String message) { + super(message); } - public ClientException( String message, Throwable cause ) - { - super( message, cause ); + public ClientException(String message, Throwable cause) { + super(message, cause); } - public ClientException( String code, String message ) - { - super( code, message ); + public ClientException(String code, String message) { + super(code, message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/ConnectionReadTimeoutException.java b/driver/src/main/java/org/neo4j/driver/exceptions/ConnectionReadTimeoutException.java index 4ed5a66383..3d8d3ad4b0 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/ConnectionReadTimeoutException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/ConnectionReadTimeoutException.java @@ -23,13 +23,11 @@ * hint. The server might provide this value to clients to let them know when a given connection may be considered broken if client does not get any * communication from the server within the specified timeout period. This results in the server being removed from the routing table. */ -public class ConnectionReadTimeoutException extends ServiceUnavailableException -{ +public class ConnectionReadTimeoutException extends ServiceUnavailableException { public static final ConnectionReadTimeoutException INSTANCE = new ConnectionReadTimeoutException( - "Connection read timed out due to it taking longer than the server-supplied timeout value via configuration hint." ); + "Connection read timed out due to it taking longer than the server-supplied timeout value via configuration hint."); - public ConnectionReadTimeoutException( String message ) - { - super( message ); + public ConnectionReadTimeoutException(String message) { + super(message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/DatabaseException.java b/driver/src/main/java/org/neo4j/driver/exceptions/DatabaseException.java index 4388edfbb3..6af8227a17 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/DatabaseException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/DatabaseException.java @@ -23,10 +23,8 @@ * The error code provided can be used to determine further detail for the problem. * @since 1.0 */ -public class DatabaseException extends Neo4jException -{ - public DatabaseException( String code, String message ) - { - super( code, message ); +public class DatabaseException extends Neo4jException { + public DatabaseException(String code, String message) { + super(code, message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/DiscoveryException.java b/driver/src/main/java/org/neo4j/driver/exceptions/DiscoveryException.java index d71663190e..7f72b2c07b 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/DiscoveryException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/DiscoveryException.java @@ -26,10 +26,8 @@ * * If you see this error in your logs, it is safe to ignore if your cluster is temporarily changing structure during that time. */ -public class DiscoveryException extends Neo4jException -{ - public DiscoveryException( String message, Throwable cause ) - { - super( message, cause ); +public class DiscoveryException extends Neo4jException { + public DiscoveryException(String message, Throwable cause) { + super(message, cause); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/FatalDiscoveryException.java b/driver/src/main/java/org/neo4j/driver/exceptions/FatalDiscoveryException.java index 8edb89d25c..a24d49df71 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/FatalDiscoveryException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/FatalDiscoveryException.java @@ -23,15 +23,12 @@ * This exception should not be retried. * @since 4.0 */ -public class FatalDiscoveryException extends ClientException -{ - public FatalDiscoveryException( String message ) - { - super( message ); +public class FatalDiscoveryException extends ClientException { + public FatalDiscoveryException(String message) { + super(message); } - public FatalDiscoveryException( String code, String message ) - { - super( code, message ); + public FatalDiscoveryException(String code, String message) { + super(code, message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/Neo4jException.java b/driver/src/main/java/org/neo4j/driver/exceptions/Neo4jException.java index 34c2937c52..1cffc7b304 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/Neo4jException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/Neo4jException.java @@ -23,30 +23,25 @@ * * @since 1.0 */ -public abstract class Neo4jException extends RuntimeException -{ +public abstract class Neo4jException extends RuntimeException { private static final long serialVersionUID = -80579062276712566L; private final String code; - public Neo4jException( String message ) - { - this( "N/A", message ); + public Neo4jException(String message) { + this("N/A", message); } - public Neo4jException( String message, Throwable cause ) - { - this( "N/A", message, cause ); + public Neo4jException(String message, Throwable cause) { + this("N/A", message, cause); } - public Neo4jException( String code, String message ) - { - this( code, message, null ); + public Neo4jException(String code, String message) { + this(code, message, null); } - public Neo4jException( String code, String message, Throwable cause ) - { - super( message, cause ); + public Neo4jException(String code, String message, Throwable cause) { + super(message, cause); this.code = code; } @@ -57,8 +52,7 @@ public Neo4jException( String code, String message, Throwable cause ) * @return the Neo4j Status Code for this exception, or 'N/A' if none is available */ @Deprecated - public String neo4jErrorCode() - { + public String neo4jErrorCode() { return code; } @@ -68,9 +62,7 @@ public String neo4jErrorCode() * * @return textual code, such as "Neo.ClientError.Procedure.ProcedureNotFound" */ - public String code() - { + public String code() { return code; } - } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/NoSuchRecordException.java b/driver/src/main/java/org/neo4j/driver/exceptions/NoSuchRecordException.java index 8719b8c2ed..c466a8377d 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/NoSuchRecordException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/NoSuchRecordException.java @@ -27,12 +27,10 @@ * * @since 1.0 */ -public class NoSuchRecordException extends NoSuchElementException -{ +public class NoSuchRecordException extends NoSuchElementException { private static final long serialVersionUID = 9091962868264042491L; - public NoSuchRecordException( String message ) - { - super( message ); + public NoSuchRecordException(String message) { + super(message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/ProtocolException.java b/driver/src/main/java/org/neo4j/driver/exceptions/ProtocolException.java index d67f9a7fe7..cbd6f1f5d5 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/ProtocolException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/ProtocolException.java @@ -22,17 +22,14 @@ * A signal that the contract for client-server communication has broken down. * The user should contact support and cannot resolve this his or herself. */ -public class ProtocolException extends Neo4jException -{ +public class ProtocolException extends Neo4jException { private static final String CODE = "Protocol violation: "; - public ProtocolException( String message ) - { - super( CODE + message ); + public ProtocolException(String message) { + super(CODE + message); } - public ProtocolException( String message, Throwable e ) - { - super( CODE + message, e ); + public ProtocolException(String message, Throwable e) { + super(CODE + message, e); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/ResultConsumedException.java b/driver/src/main/java/org/neo4j/driver/exceptions/ResultConsumedException.java index 227bb9acc2..707002a9cb 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/ResultConsumedException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/ResultConsumedException.java @@ -25,10 +25,8 @@ * the resources have already been consumed or * the {@link QueryRunner} where the resources are created has already been closed. */ -public class ResultConsumedException extends ClientException -{ - public ResultConsumedException( String message ) - { - super( message ); +public class ResultConsumedException extends ClientException { + public ResultConsumedException(String message) { + super(message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/SecurityException.java b/driver/src/main/java/org/neo4j/driver/exceptions/SecurityException.java index 667116c87f..cd77ff5845 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/SecurityException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/SecurityException.java @@ -24,15 +24,12 @@ * Restart of server/driver/cluster might be required to recover from this error. * @since 1.1 */ -public class SecurityException extends ClientException -{ - public SecurityException( String code, String message ) - { - super( code, message ); +public class SecurityException extends ClientException { + public SecurityException(String code, String message) { + super(code, message); } - public SecurityException( String message, Throwable t ) - { - super( message, t ); + public SecurityException(String message, Throwable t) { + super(message, t); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/ServiceUnavailableException.java b/driver/src/main/java/org/neo4j/driver/exceptions/ServiceUnavailableException.java index d4329835c0..49d2bf218f 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/ServiceUnavailableException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/ServiceUnavailableException.java @@ -22,15 +22,12 @@ * An ServiceUnavailableException indicates that the driver cannot communicate with the cluster. * @since 1.1 */ -public class ServiceUnavailableException extends Neo4jException -{ - public ServiceUnavailableException( String message ) - { - super( message ); +public class ServiceUnavailableException extends Neo4jException { + public ServiceUnavailableException(String message) { + super(message); } - public ServiceUnavailableException( String message, Throwable throwable ) - { - super( message, throwable); + public ServiceUnavailableException(String message, Throwable throwable) { + super(message, throwable); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/SessionExpiredException.java b/driver/src/main/java/org/neo4j/driver/exceptions/SessionExpiredException.java index 8bbd010866..c5c8e0023f 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/SessionExpiredException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/SessionExpiredException.java @@ -24,15 +24,12 @@ * and all actions taken on the expired session must be replayed. * @since 1.1 */ -public class SessionExpiredException extends Neo4jException -{ - public SessionExpiredException( String message) - { - super( message ); +public class SessionExpiredException extends Neo4jException { + public SessionExpiredException(String message) { + super(message); } - public SessionExpiredException( String message, Throwable throwable ) - { - super( message, throwable ); + public SessionExpiredException(String message, Throwable throwable) { + super(message, throwable); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/TokenExpiredException.java b/driver/src/main/java/org/neo4j/driver/exceptions/TokenExpiredException.java index 11ed162d84..4c6c47a75a 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/TokenExpiredException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/TokenExpiredException.java @@ -25,10 +25,8 @@ *

* Error code: Neo.ClientError.Security.TokenExpired */ -public class TokenExpiredException extends SecurityException -{ - public TokenExpiredException( String code, String message ) - { - super( code, message ); +public class TokenExpiredException extends SecurityException { + public TokenExpiredException(String code, String message) { + super(code, message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/TransactionNestingException.java b/driver/src/main/java/org/neo4j/driver/exceptions/TransactionNestingException.java index 16917a9550..88bcf43b87 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/TransactionNestingException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/TransactionNestingException.java @@ -21,10 +21,8 @@ /** * This exception indicates a user is nesting new transaction with an on-going transaction (unmanaged and/or auto-commit). */ -public class TransactionNestingException extends ClientException -{ - public TransactionNestingException( String message ) - { - super( message ); +public class TransactionNestingException extends ClientException { + public TransactionNestingException(String message) { + super(message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/TransientException.java b/driver/src/main/java/org/neo4j/driver/exceptions/TransientException.java index 37631dd11a..886ee9170f 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/TransientException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/TransientException.java @@ -23,10 +23,8 @@ * The error code provided can be used to determine further detail for the problem. * @since 1.0 */ -public class TransientException extends Neo4jException -{ - public TransientException( String code, String message ) - { - super( code, message ); +public class TransientException extends Neo4jException { + public TransientException(String code, String message) { + super(code, message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/UntrustedServerException.java b/driver/src/main/java/org/neo4j/driver/exceptions/UntrustedServerException.java index 8a72bfc4fd..d62d292b2e 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/UntrustedServerException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/UntrustedServerException.java @@ -21,10 +21,8 @@ /** * Thrown if the remote server cannot be verified as Neo4j. */ -public class UntrustedServerException extends RuntimeException -{ - public UntrustedServerException(String message) - { +public class UntrustedServerException extends RuntimeException { + public UntrustedServerException(String message) { super(message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/value/LossyCoercion.java b/driver/src/main/java/org/neo4j/driver/exceptions/value/LossyCoercion.java index ea049c98fd..bb52c7a7c9 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/value/LossyCoercion.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/value/LossyCoercion.java @@ -24,13 +24,10 @@ * A LossyCoercion exception indicates that the conversion cannot be achieved without losing precision. * @since 1.0 */ -public class LossyCoercion extends ValueException -{ +public class LossyCoercion extends ValueException { private static final long serialVersionUID = -6259981390929065201L; - public LossyCoercion( String sourceTypeName, String destinationTypeName ) - { - super( format( "Cannot coerce %s to %s without losing precision", sourceTypeName, destinationTypeName ) ); + public LossyCoercion(String sourceTypeName, String destinationTypeName) { + super(format("Cannot coerce %s to %s without losing precision", sourceTypeName, destinationTypeName)); } - } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/value/NotMultiValued.java b/driver/src/main/java/org/neo4j/driver/exceptions/value/NotMultiValued.java index a7a44d8482..458c282376 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/value/NotMultiValued.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/value/NotMultiValued.java @@ -23,13 +23,10 @@ * or array. * @since 1.0 */ -public class NotMultiValued extends ValueException -{ +public class NotMultiValued extends ValueException { private static final long serialVersionUID = -7380569883011364090L; - public NotMultiValued( String message ) - { - super( message ); + public NotMultiValued(String message) { + super(message); } - } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/value/Uncoercible.java b/driver/src/main/java/org/neo4j/driver/exceptions/value/Uncoercible.java index b5c3276e00..74c1228372 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/value/Uncoercible.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/value/Uncoercible.java @@ -24,13 +24,10 @@ * A Uncoercible exception indicates that the conversion cannot be achieved. * @since 1.0 */ -public class Uncoercible extends ValueException -{ +public class Uncoercible extends ValueException { private static final long serialVersionUID = -6259981390929065201L; - public Uncoercible( String sourceTypeName, String destinationTypeName ) - { - super( format( "Cannot coerce %s to %s", sourceTypeName, destinationTypeName ) ); + public Uncoercible(String sourceTypeName, String destinationTypeName) { + super(format("Cannot coerce %s to %s", sourceTypeName, destinationTypeName)); } - } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/value/Unsizable.java b/driver/src/main/java/org/neo4j/driver/exceptions/value/Unsizable.java index 9a6ff582c5..915c5c169f 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/value/Unsizable.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/value/Unsizable.java @@ -22,12 +22,10 @@ * An Unsizable exception indicates that the value does not have a size. * @since 1.0 */ -public class Unsizable extends ValueException -{ +public class Unsizable extends ValueException { private static final long serialVersionUID = 741487155344252339L; - public Unsizable( String message ) - { - super( message ); + public Unsizable(String message) { + super(message); } } diff --git a/driver/src/main/java/org/neo4j/driver/exceptions/value/ValueException.java b/driver/src/main/java/org/neo4j/driver/exceptions/value/ValueException.java index e702fe94bb..37b029de88 100644 --- a/driver/src/main/java/org/neo4j/driver/exceptions/value/ValueException.java +++ b/driver/src/main/java/org/neo4j/driver/exceptions/value/ValueException.java @@ -24,12 +24,10 @@ * A ValueException indicates that the client has carried out an operation on values incorrectly. * @since 1.0 */ -public class ValueException extends ClientException -{ +public class ValueException extends ClientException { private static final long serialVersionUID = -1269336313727174998L; - public ValueException( String message ) - { - super( message ); + public ValueException(String message) { + super(message); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/AbstractQueryRunner.java b/driver/src/main/java/org/neo4j/driver/internal/AbstractQueryRunner.java index 26d8c3b0d8..5d2f8d265b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/AbstractQueryRunner.java +++ b/driver/src/main/java/org/neo4j/driver/internal/AbstractQueryRunner.java @@ -19,53 +19,44 @@ package org.neo4j.driver.internal; import java.util.Map; - -import org.neo4j.driver.Record; import org.neo4j.driver.Query; -import org.neo4j.driver.Result; import org.neo4j.driver.QueryRunner; +import org.neo4j.driver.Record; +import org.neo4j.driver.Result; import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.util.Extract; import org.neo4j.driver.internal.value.MapValue; -public abstract class AbstractQueryRunner implements QueryRunner -{ +public abstract class AbstractQueryRunner implements QueryRunner { @Override - public final Result run(String query, Value parameters ) - { - return run( new Query( query, parameters ) ); + public final Result run(String query, Value parameters) { + return run(new Query(query, parameters)); } @Override - public final Result run(String query, Map parameters) - { - return run(query, parameters(parameters) ); + public final Result run(String query, Map parameters) { + return run(query, parameters(parameters)); } @Override - public final Result run(String query, Record parameters) - { - return run(query, parameters(parameters) ); + public final Result run(String query, Record parameters) { + return run(query, parameters(parameters)); } @Override - public final Result run(String query) - { - return run(query, Values.EmptyMap ); + public final Result run(String query) { + return run(query, Values.EmptyMap); } - public static Value parameters( Record record ) - { - return record == null ? Values.EmptyMap : parameters( record.asMap() ); + public static Value parameters(Record record) { + return record == null ? Values.EmptyMap : parameters(record.asMap()); } - public static Value parameters( Map map ) - { - if ( map == null || map.isEmpty() ) - { + public static Value parameters(Map map) { + if (map == null || map.isEmpty()) { return Values.EmptyMap; } - return new MapValue( Extract.mapOfValues( map ) ); + return new MapValue(Extract.mapOfValues(map)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/AsValue.java b/driver/src/main/java/org/neo4j/driver/internal/AsValue.java index ac79193984..77d7973fb5 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/AsValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/AsValue.java @@ -20,8 +20,7 @@ import org.neo4j.driver.Value; -public interface AsValue -{ +public interface AsValue { /** * Retrieve a value representation of this * diff --git a/driver/src/main/java/org/neo4j/driver/internal/BoltServerAddress.java b/driver/src/main/java/org/neo4j/driver/internal/BoltServerAddress.java index eacd6b2a39..5da9bfb60e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/BoltServerAddress.java +++ b/driver/src/main/java/org/neo4j/driver/internal/BoltServerAddress.java @@ -18,100 +18,87 @@ */ package org.neo4j.driver.internal; +import static java.util.Objects.requireNonNull; + import java.net.URI; import java.util.Objects; import java.util.stream.Stream; - import org.neo4j.driver.net.ServerAddress; -import static java.util.Objects.requireNonNull; - /** * Holds a host and port pair that denotes a Bolt server address. */ -public class BoltServerAddress implements ServerAddress -{ +public class BoltServerAddress implements ServerAddress { public static final int DEFAULT_PORT = 7687; - public static final BoltServerAddress LOCAL_DEFAULT = new BoltServerAddress( "localhost", DEFAULT_PORT ); + public static final BoltServerAddress LOCAL_DEFAULT = new BoltServerAddress("localhost", DEFAULT_PORT); protected final String host; // Host or IP address. - private final String connectionHost; // Either is equal to the host or is explicitly provided on creation and is expected to be a resolved IP address. + private final String + connectionHost; // Either is equal to the host or is explicitly provided on creation and is expected to be a + // resolved IP address. protected final int port; private final String stringValue; - public BoltServerAddress( String address ) - { - this( uriFrom( address ) ); + public BoltServerAddress(String address) { + this(uriFrom(address)); } - public BoltServerAddress( URI uri ) - { - this( hostFrom( uri ), portFrom( uri ) ); + public BoltServerAddress(URI uri) { + this(hostFrom(uri), portFrom(uri)); } - public BoltServerAddress( String host, int port ) - { - this( host, host, port ); + public BoltServerAddress(String host, int port) { + this(host, host, port); } - public BoltServerAddress( String host, String connectionHost, int port ) - { - this.host = requireNonNull( host, "host" ); - this.connectionHost = requireNonNull( connectionHost, "connectionHost" ); - this.port = requireValidPort( port ); - this.stringValue = host.equals( connectionHost ) - ? String.format( "%s:%d", host, port ) - : String.format( "%s(%s):%d", host, connectionHost, port ); + public BoltServerAddress(String host, String connectionHost, int port) { + this.host = requireNonNull(host, "host"); + this.connectionHost = requireNonNull(connectionHost, "connectionHost"); + this.port = requireValidPort(port); + this.stringValue = host.equals(connectionHost) + ? String.format("%s:%d", host, port) + : String.format("%s(%s):%d", host, connectionHost, port); } - public static BoltServerAddress from( ServerAddress address ) - { + public static BoltServerAddress from(ServerAddress address) { return address instanceof BoltServerAddress - ? (BoltServerAddress) address - : new BoltServerAddress( address.host(), address.port() ); + ? (BoltServerAddress) address + : new BoltServerAddress(address.host(), address.port()); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } BoltServerAddress address = (BoltServerAddress) o; - return port == address.port && host.equals( address.host ) && connectionHost.equals( address.connectionHost ); + return port == address.port && host.equals(address.host) && connectionHost.equals(address.connectionHost); } @Override - public int hashCode() - { - return Objects.hash( host, connectionHost, port ); + public int hashCode() { + return Objects.hash(host, connectionHost, port); } @Override - public String toString() - { + public String toString() { return stringValue; } @Override - public String host() - { + public String host() { return host; } @Override - public int port() - { + public int port() { return port; } - public String connectionHost() - { + public String connectionHost() { return connectionHost; } @@ -122,63 +109,50 @@ public String connectionHost() * * @return stream of unicast addresses. */ - public Stream unicastStream() - { - return Stream.of( this ); + public Stream unicastStream() { + return Stream.of(this); } - private static String hostFrom( URI uri ) - { + private static String hostFrom(URI uri) { String host = uri.getHost(); - if ( host == null ) - { - throw invalidAddressFormat( uri ); + if (host == null) { + throw invalidAddressFormat(uri); } return host; } - private static int portFrom( URI uri ) - { + private static int portFrom(URI uri) { int port = uri.getPort(); return port == -1 ? DEFAULT_PORT : port; } - private static URI uriFrom( String address ) - { + private static URI uriFrom(String address) { String scheme; String hostPort; - String[] schemeSplit = address.split( "://" ); - if ( schemeSplit.length == 1 ) - { + String[] schemeSplit = address.split("://"); + if (schemeSplit.length == 1) { // URI can't parse addresses without scheme, prepend fake "bolt://" to reuse the parsing facility scheme = "bolt://"; - hostPort = hostPortFrom( schemeSplit[0] ); - } - else if ( schemeSplit.length == 2 ) - { + hostPort = hostPortFrom(schemeSplit[0]); + } else if (schemeSplit.length == 2) { scheme = schemeSplit[0] + "://"; - hostPort = hostPortFrom( schemeSplit[1] ); - } - else - { - throw invalidAddressFormat( address ); + hostPort = hostPortFrom(schemeSplit[1]); + } else { + throw invalidAddressFormat(address); } - return URI.create( scheme + hostPort ); + return URI.create(scheme + hostPort); } - private static String hostPortFrom( String address ) - { - if ( address.startsWith( "[" ) ) - { + private static String hostPortFrom(String address) { + if (address.startsWith("[")) { // expected to be an IPv6 address like [::1] or [::1]:7687 return address; } - boolean containsSingleColon = address.indexOf( ":" ) == address.lastIndexOf( ":" ); - if ( containsSingleColon ) - { + boolean containsSingleColon = address.indexOf(":") == address.lastIndexOf(":"); + if (containsSingleColon) { // expected to be an IPv4 address with or without port like 127.0.0.1 or 127.0.0.1:7687 return address; } @@ -188,22 +162,18 @@ private static String hostPortFrom( String address ) return "[" + address + "]"; } - private static RuntimeException invalidAddressFormat( URI uri ) - { - return invalidAddressFormat( uri.toString() ); + private static RuntimeException invalidAddressFormat(URI uri) { + return invalidAddressFormat(uri.toString()); } - private static RuntimeException invalidAddressFormat( String address ) - { - return new IllegalArgumentException( "Invalid address format `" + address + "`" ); + private static RuntimeException invalidAddressFormat(String address) { + return new IllegalArgumentException("Invalid address format `" + address + "`"); } - private static int requireValidPort( int port ) - { - if ( port >= 0 && port <= 65_535 ) - { + private static int requireValidPort(int port) { + if (port >= 0 && port <= 65_535) { return port; } - throw new IllegalArgumentException( "Illegal port: " + port ); + throw new IllegalArgumentException("Illegal port: " + port); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/BookmarkHolder.java b/driver/src/main/java/org/neo4j/driver/internal/BookmarkHolder.java index d048d0948f..4e1663e3a2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/BookmarkHolder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/BookmarkHolder.java @@ -20,23 +20,18 @@ import org.neo4j.driver.Bookmark; -public interface BookmarkHolder -{ +public interface BookmarkHolder { Bookmark getBookmark(); - void setBookmark( Bookmark bookmark ); + void setBookmark(Bookmark bookmark); - BookmarkHolder NO_OP = new BookmarkHolder() - { + BookmarkHolder NO_OP = new BookmarkHolder() { @Override - public Bookmark getBookmark() - { + public Bookmark getBookmark() { return InternalBookmark.empty(); } @Override - public void setBookmark( Bookmark bookmark ) - { - } + public void setBookmark(Bookmark bookmark) {} }; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/ConnectionSettings.java b/driver/src/main/java/org/neo4j/driver/internal/ConnectionSettings.java index f9d0ab43fa..f6560eb610 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/ConnectionSettings.java +++ b/driver/src/main/java/org/neo4j/driver/internal/ConnectionSettings.java @@ -24,31 +24,26 @@ * The connection settings are used whenever a new connection is * established to a server, specifically as part of the INIT request. */ -public class ConnectionSettings -{ +public class ConnectionSettings { private final AuthToken authToken; private final String userAgent; private final int connectTimeoutMillis; - public ConnectionSettings( AuthToken authToken, String userAgent, int connectTimeoutMillis ) - { + public ConnectionSettings(AuthToken authToken, String userAgent, int connectTimeoutMillis) { this.authToken = authToken; this.userAgent = userAgent; this.connectTimeoutMillis = connectTimeoutMillis; } - public AuthToken authToken() - { + public AuthToken authToken() { return authToken; } - public String userAgent() - { + public String userAgent() { return userAgent; } - public int connectTimeoutMillis() - { + public int connectTimeoutMillis() { return connectTimeoutMillis; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/DatabaseName.java b/driver/src/main/java/org/neo4j/driver/internal/DatabaseName.java index 980977d5b1..86bac13551 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DatabaseName.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DatabaseName.java @@ -20,8 +20,7 @@ import java.util.Optional; -public interface DatabaseName -{ +public interface DatabaseName { Optional databaseName(); String description(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/DatabaseNameUtil.java b/driver/src/main/java/org/neo4j/driver/internal/DatabaseNameUtil.java index be09c7c94f..6098711ed3 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DatabaseNameUtil.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DatabaseNameUtil.java @@ -21,47 +21,37 @@ import java.util.Objects; import java.util.Optional; -public final class DatabaseNameUtil -{ +public final class DatabaseNameUtil { static final String DEFAULT_DATABASE_NAME = null; public static final String SYSTEM_DATABASE_NAME = "system"; - private static final DatabaseName DEFAULT_DATABASE = new DatabaseName() - { + private static final DatabaseName DEFAULT_DATABASE = new DatabaseName() { @Override - public Optional databaseName() - { + public Optional databaseName() { return Optional.empty(); } @Override - public String description() - { + public String description() { return ""; } }; - private static final DatabaseName SYSTEM_DATABASE = new InternalDatabaseName( SYSTEM_DATABASE_NAME ); + private static final DatabaseName SYSTEM_DATABASE = new InternalDatabaseName(SYSTEM_DATABASE_NAME); - public static DatabaseName defaultDatabase() - { + public static DatabaseName defaultDatabase() { return DEFAULT_DATABASE; } - public static DatabaseName systemDatabase() - { + public static DatabaseName systemDatabase() { return SYSTEM_DATABASE; } - public static DatabaseName database( String name ) - { - if ( Objects.equals( name, DEFAULT_DATABASE_NAME ) ) - { + public static DatabaseName database(String name) { + if (Objects.equals(name, DEFAULT_DATABASE_NAME)) { return defaultDatabase(); - } - else if ( Objects.equals( name, SYSTEM_DATABASE_NAME ) ) - { + } else if (Objects.equals(name, SYSTEM_DATABASE_NAME)) { return systemDatabase(); } - return new InternalDatabaseName( name ); + return new InternalDatabaseName(name); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/DefaultBookmarkHolder.java b/driver/src/main/java/org/neo4j/driver/internal/DefaultBookmarkHolder.java index 61f333bc32..501568347e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DefaultBookmarkHolder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DefaultBookmarkHolder.java @@ -23,31 +23,25 @@ /** * @since 2.0 */ -public class DefaultBookmarkHolder implements BookmarkHolder -{ +public class DefaultBookmarkHolder implements BookmarkHolder { private volatile Bookmark bookmark; - public DefaultBookmarkHolder() - { - this( InternalBookmark.empty() ); + public DefaultBookmarkHolder() { + this(InternalBookmark.empty()); } - public DefaultBookmarkHolder( Bookmark bookmark ) - { + public DefaultBookmarkHolder(Bookmark bookmark) { this.bookmark = bookmark; } @Override - public Bookmark getBookmark() - { + public Bookmark getBookmark() { return bookmark; } @Override - public void setBookmark( Bookmark bookmark ) - { - if ( bookmark != null && !bookmark.isEmpty() ) - { + public void setBookmark(Bookmark bookmark) { + if (bookmark != null && !bookmark.isEmpty()) { this.bookmark = bookmark; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/DefaultDomainNameResolver.java b/driver/src/main/java/org/neo4j/driver/internal/DefaultDomainNameResolver.java index fc94c3d51d..78e2aaeb9b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DefaultDomainNameResolver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DefaultDomainNameResolver.java @@ -21,22 +21,17 @@ import java.net.InetAddress; import java.net.UnknownHostException; -public class DefaultDomainNameResolver implements DomainNameResolver -{ +public class DefaultDomainNameResolver implements DomainNameResolver { private static final DefaultDomainNameResolver INSTANCE = new DefaultDomainNameResolver(); - public static DefaultDomainNameResolver getInstance() - { + public static DefaultDomainNameResolver getInstance() { return INSTANCE; } - private DefaultDomainNameResolver() - { - } + private DefaultDomainNameResolver() {} @Override - public InetAddress[] resolve( String name ) throws UnknownHostException - { - return InetAddress.getAllByName( name ); + public InetAddress[] resolve(String name) throws UnknownHostException { + return InetAddress.getAllByName(name); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/DirectConnectionProvider.java b/driver/src/main/java/org/neo4j/driver/internal/DirectConnectionProvider.java index 7c6f614fc9..a336e10100 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DirectConnectionProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DirectConnectionProvider.java @@ -18,9 +18,11 @@ */ package org.neo4j.driver.internal; +import static org.neo4j.driver.internal.async.ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER; +import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsMultiDatabase; + import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.internal.async.ConnectionContext; import org.neo4j.driver.internal.async.connection.DirectConnection; import org.neo4j.driver.internal.spi.Connection; @@ -28,57 +30,49 @@ import org.neo4j.driver.internal.spi.ConnectionProvider; import org.neo4j.driver.internal.util.Futures; -import static org.neo4j.driver.internal.async.ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER; -import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsMultiDatabase; - /** * Simple {@link ConnectionProvider connection provider} that obtains connections form the given pool only for the given address. */ -public class DirectConnectionProvider implements ConnectionProvider -{ +public class DirectConnectionProvider implements ConnectionProvider { private final BoltServerAddress address; private final ConnectionPool connectionPool; - DirectConnectionProvider( BoltServerAddress address, ConnectionPool connectionPool ) - { + DirectConnectionProvider(BoltServerAddress address, ConnectionPool connectionPool) { this.address = address; this.connectionPool = connectionPool; } @Override - public CompletionStage acquireConnection( ConnectionContext context ) - { + public CompletionStage acquireConnection(ConnectionContext context) { CompletableFuture databaseNameFuture = context.databaseNameFuture(); - databaseNameFuture.complete( DatabaseNameUtil.defaultDatabase() ); - return acquireConnection().thenApply( - connection -> new DirectConnection( connection, - Futures.joinNowOrElseThrow( databaseNameFuture, PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER ), - context.mode(), context.impersonatedUser() ) ); + databaseNameFuture.complete(DatabaseNameUtil.defaultDatabase()); + return acquireConnection() + .thenApply(connection -> new DirectConnection( + connection, + Futures.joinNowOrElseThrow(databaseNameFuture, PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER), + context.mode(), + context.impersonatedUser())); } @Override - public CompletionStage verifyConnectivity() - { - return acquireConnection().thenCompose( Connection::release ); + public CompletionStage verifyConnectivity() { + return acquireConnection().thenCompose(Connection::release); } @Override - public CompletionStage close() - { + public CompletionStage close() { return connectionPool.close(); } @Override - public CompletionStage supportsMultiDb() - { - return acquireConnection().thenCompose( conn -> { - boolean supportsMultiDatabase = supportsMultiDatabase( conn ); - return conn.release().thenApply( ignored -> supportsMultiDatabase ); - } ); + public CompletionStage supportsMultiDb() { + return acquireConnection().thenCompose(conn -> { + boolean supportsMultiDatabase = supportsMultiDatabase(conn); + return conn.release().thenApply(ignored -> supportsMultiDatabase); + }); } - public BoltServerAddress getAddress() - { + public BoltServerAddress getAddress() { return address; } @@ -86,8 +80,7 @@ public BoltServerAddress getAddress() * Used only for grabbing a connection with the server after hello message. * This connection cannot be directly used for running any queries as it is missing necessary connection context */ - private CompletionStage acquireConnection() - { - return connectionPool.acquire( address ); + private CompletionStage acquireConnection() { + return connectionPool.acquire(address); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/DomainNameResolver.java b/driver/src/main/java/org/neo4j/driver/internal/DomainNameResolver.java index 94d6f613b2..46ca954e4d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DomainNameResolver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DomainNameResolver.java @@ -25,8 +25,7 @@ * A resolver function used by the driver to resolve domain names. */ @FunctionalInterface -public interface DomainNameResolver -{ +public interface DomainNameResolver { /** * Resolve the given domain name to a set of addresses. * @@ -34,5 +33,5 @@ public interface DomainNameResolver * @return the resolved addresses. * @throws UnknownHostException must be thrown if the given name can not be resolved to at least one address. */ - InetAddress[] resolve( String name ) throws UnknownHostException; + InetAddress[] resolve(String name) throws UnknownHostException; } 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 63035a0f8e..2e9dc95c1a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java @@ -18,13 +18,15 @@ */ package org.neo4j.driver.internal; +import static org.neo4j.driver.internal.Scheme.isRoutingScheme; +import static org.neo4j.driver.internal.cluster.IdentityResolver.IDENTITY_RESOLVER; +import static org.neo4j.driver.internal.util.ErrorUtil.addSuppressed; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.EventLoopGroup; import io.netty.util.concurrent.EventExecutorGroup; import io.netty.util.internal.logging.InternalLoggerFactory; - import java.net.URI; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; @@ -57,113 +59,153 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.net.ServerAddressResolver; -import static org.neo4j.driver.internal.Scheme.isRoutingScheme; -import static org.neo4j.driver.internal.cluster.IdentityResolver.IDENTITY_RESOLVER; -import static org.neo4j.driver.internal.util.ErrorUtil.addSuppressed; - -public class DriverFactory -{ - public static final String NO_ROUTING_CONTEXT_ERROR_MESSAGE = "Routing parameters are not supported with scheme 'bolt'. Given URI: "; +public class DriverFactory { + public static final String NO_ROUTING_CONTEXT_ERROR_MESSAGE = + "Routing parameters are not supported with scheme 'bolt'. Given URI: "; - public final Driver newInstance( URI uri, AuthToken authToken, RoutingSettings routingSettings, - RetrySettings retrySettings, Config config, SecurityPlan securityPlan ) - { - return newInstance( uri, authToken, routingSettings, retrySettings, config, null, securityPlan ); + public final Driver newInstance( + URI uri, + AuthToken authToken, + RoutingSettings routingSettings, + RetrySettings retrySettings, + Config config, + SecurityPlan securityPlan) { + return newInstance(uri, authToken, routingSettings, retrySettings, config, null, securityPlan); } - public final Driver newInstance( URI uri, AuthToken authToken, RoutingSettings routingSettings, - RetrySettings retrySettings, Config config, EventLoopGroup eventLoopGroup, SecurityPlan securityPlan ) - { + public final Driver newInstance( + URI uri, + AuthToken authToken, + RoutingSettings routingSettings, + RetrySettings retrySettings, + Config config, + EventLoopGroup eventLoopGroup, + SecurityPlan securityPlan) { Bootstrap bootstrap; boolean ownsEventLoopGroup; - if ( eventLoopGroup == null ) - { - bootstrap = createBootstrap( config.eventLoopThreads() ); + if (eventLoopGroup == null) { + bootstrap = createBootstrap(config.eventLoopThreads()); ownsEventLoopGroup = true; - } - else - { - bootstrap = createBootstrap( eventLoopGroup ); + } else { + bootstrap = createBootstrap(eventLoopGroup); ownsEventLoopGroup = false; } authToken = authToken == null ? AuthTokens.none() : authToken; - BoltServerAddress address = new BoltServerAddress( uri ); - RoutingSettings newRoutingSettings = routingSettings.withRoutingContext( new RoutingContext( uri ) ); + BoltServerAddress address = new BoltServerAddress(uri); + RoutingSettings newRoutingSettings = routingSettings.withRoutingContext(new RoutingContext(uri)); - InternalLoggerFactory.setDefaultFactory( new NettyLogging( config.logging() ) ); + InternalLoggerFactory.setDefaultFactory(new NettyLogging(config.logging())); EventExecutorGroup eventExecutorGroup = bootstrap.config().group(); - RetryLogic retryLogic = createRetryLogic( retrySettings, eventExecutorGroup, config.logging() ); + RetryLogic retryLogic = createRetryLogic(retrySettings, eventExecutorGroup, config.logging()); - MetricsProvider metricsProvider = getOrCreateMetricsProvider( config, createClock() ); - ConnectionPool connectionPool = createConnectionPool( authToken, securityPlan, bootstrap, metricsProvider, config, - ownsEventLoopGroup, newRoutingSettings.routingContext() ); + MetricsProvider metricsProvider = getOrCreateMetricsProvider(config, createClock()); + ConnectionPool connectionPool = createConnectionPool( + authToken, + securityPlan, + bootstrap, + metricsProvider, + config, + ownsEventLoopGroup, + newRoutingSettings.routingContext()); - return createDriver( uri, securityPlan, address, connectionPool, eventExecutorGroup, newRoutingSettings, retryLogic, metricsProvider, config ); + return createDriver( + uri, + securityPlan, + address, + connectionPool, + eventExecutorGroup, + newRoutingSettings, + retryLogic, + metricsProvider, + config); } - protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, - MetricsProvider metricsProvider, Config config, boolean ownsEventLoopGroup, RoutingContext routingContext ) - { + protected ConnectionPool createConnectionPool( + AuthToken authToken, + SecurityPlan securityPlan, + Bootstrap bootstrap, + MetricsProvider metricsProvider, + Config config, + boolean ownsEventLoopGroup, + RoutingContext routingContext) { Clock clock = createClock(); - ConnectionSettings settings = new ConnectionSettings( authToken, config.userAgent(), config.connectionTimeoutMillis() ); - ChannelConnector connector = createConnector( settings, securityPlan, config, clock, routingContext ); - PoolSettings poolSettings = new PoolSettings( config.maxConnectionPoolSize(), - config.connectionAcquisitionTimeoutMillis(), config.maxConnectionLifetimeMillis(), - config.idleTimeBeforeConnectionTest() - ); - return new ConnectionPoolImpl( connector, bootstrap, poolSettings, metricsProvider.metricsListener(), config.logging(), clock, ownsEventLoopGroup ); + ConnectionSettings settings = + new ConnectionSettings(authToken, config.userAgent(), config.connectionTimeoutMillis()); + ChannelConnector connector = createConnector(settings, securityPlan, config, clock, routingContext); + PoolSettings poolSettings = new PoolSettings( + config.maxConnectionPoolSize(), + config.connectionAcquisitionTimeoutMillis(), + config.maxConnectionLifetimeMillis(), + config.idleTimeBeforeConnectionTest()); + return new ConnectionPoolImpl( + connector, + bootstrap, + poolSettings, + metricsProvider.metricsListener(), + config.logging(), + clock, + ownsEventLoopGroup); } - protected static MetricsProvider getOrCreateMetricsProvider( Config config, Clock clock ) - { + protected static MetricsProvider getOrCreateMetricsProvider(Config config, Clock clock) { MetricsAdapter metricsAdapter = config.metricsAdapter(); // This can actually only happen when someone mocks the config - if ( metricsAdapter == null ) - { + if (metricsAdapter == null) { metricsAdapter = config.isMetricsEnabled() ? MetricsAdapter.DEFAULT : MetricsAdapter.DEV_NULL; } - switch ( metricsAdapter ) - { - case DEV_NULL: - return DevNullMetricsProvider.INSTANCE; - case DEFAULT: - return new InternalMetricsProvider( clock, config.logging() ); - case MICROMETER: - return MicrometerMetricsProvider.forGlobalRegistry(); + switch (metricsAdapter) { + case DEV_NULL: + return DevNullMetricsProvider.INSTANCE; + case DEFAULT: + return new InternalMetricsProvider(clock, config.logging()); + case MICROMETER: + return MicrometerMetricsProvider.forGlobalRegistry(); } - throw new IllegalStateException( "Unknown or unsupported MetricsAdapter: " + metricsAdapter ); + throw new IllegalStateException("Unknown or unsupported MetricsAdapter: " + metricsAdapter); } - protected ChannelConnector createConnector( ConnectionSettings settings, SecurityPlan securityPlan, - Config config, Clock clock, RoutingContext routingContext ) - { - return new ChannelConnectorImpl( settings, securityPlan, config.logging(), clock, routingContext, getDomainNameResolver() ); + protected ChannelConnector createConnector( + ConnectionSettings settings, + SecurityPlan securityPlan, + Config config, + Clock clock, + RoutingContext routingContext) { + return new ChannelConnectorImpl( + settings, securityPlan, config.logging(), clock, routingContext, getDomainNameResolver()); } - private InternalDriver createDriver( URI uri, SecurityPlan securityPlan, BoltServerAddress address, ConnectionPool connectionPool, - EventExecutorGroup eventExecutorGroup, RoutingSettings routingSettings, RetryLogic retryLogic, - MetricsProvider metricsProvider, Config config ) - { - try - { + private InternalDriver createDriver( + URI uri, + SecurityPlan securityPlan, + BoltServerAddress address, + ConnectionPool connectionPool, + EventExecutorGroup eventExecutorGroup, + RoutingSettings routingSettings, + RetryLogic retryLogic, + MetricsProvider metricsProvider, + Config config) { + try { String scheme = uri.getScheme().toLowerCase(); - if ( isRoutingScheme( scheme ) ) - { - return createRoutingDriver( securityPlan, address, connectionPool, eventExecutorGroup, routingSettings, retryLogic, metricsProvider, config ); - } - else - { - assertNoRoutingContext( uri, routingSettings ); - return createDirectDriver( securityPlan, address, connectionPool, retryLogic, metricsProvider, config ); + if (isRoutingScheme(scheme)) { + return createRoutingDriver( + securityPlan, + address, + connectionPool, + eventExecutorGroup, + routingSettings, + retryLogic, + metricsProvider, + config); + } else { + assertNoRoutingContext(uri, routingSettings); + return createDirectDriver(securityPlan, address, connectionPool, retryLogic, metricsProvider, config); } - } - catch ( Throwable driverError ) - { + } catch (Throwable driverError) { // we need to close the connection pool if driver creation threw exception - closeConnectionPoolAndSuppressError( connectionPool, driverError ); + closeConnectionPoolAndSuppressError(connectionPool, driverError); throw driverError; } } @@ -173,14 +215,18 @@ private InternalDriver createDriver( URI uri, SecurityPlan securityPlan, BoltSer *

* This method is protected only for testing */ - protected InternalDriver createDirectDriver( SecurityPlan securityPlan, BoltServerAddress address, ConnectionPool connectionPool, RetryLogic retryLogic, - MetricsProvider metricsProvider, Config config ) - { - ConnectionProvider connectionProvider = new DirectConnectionProvider( address, connectionPool ); - SessionFactory sessionFactory = createSessionFactory( connectionProvider, retryLogic, config ); - InternalDriver driver = createDriver( securityPlan, sessionFactory, metricsProvider, config ); - Logger log = config.logging().getLog( getClass() ); - log.info( "Direct driver instance %s created for server address %s", driver.hashCode(), address ); + protected InternalDriver createDirectDriver( + SecurityPlan securityPlan, + BoltServerAddress address, + ConnectionPool connectionPool, + RetryLogic retryLogic, + MetricsProvider metricsProvider, + Config config) { + ConnectionProvider connectionProvider = new DirectConnectionProvider(address, connectionPool); + SessionFactory sessionFactory = createSessionFactory(connectionProvider, retryLogic, config); + InternalDriver driver = createDriver(securityPlan, sessionFactory, metricsProvider, config); + Logger log = config.logging().getLog(getClass()); + log.info("Direct driver instance %s created for server address %s", driver.hashCode(), address); return driver; } @@ -189,15 +235,21 @@ protected InternalDriver createDirectDriver( SecurityPlan securityPlan, BoltServ *

* This method is protected only for testing */ - protected InternalDriver createRoutingDriver( SecurityPlan securityPlan, BoltServerAddress address, ConnectionPool connectionPool, - EventExecutorGroup eventExecutorGroup, RoutingSettings routingSettings, RetryLogic retryLogic, MetricsProvider metricsProvider, Config config ) - { - ConnectionProvider connectionProvider = createLoadBalancer( address, connectionPool, eventExecutorGroup, - config, routingSettings ); - SessionFactory sessionFactory = createSessionFactory( connectionProvider, retryLogic, config ); - InternalDriver driver = createDriver( securityPlan, sessionFactory, metricsProvider, config ); - Logger log = config.logging().getLog( getClass() ); - log.info( "Routing driver instance %s created for server address %s", driver.hashCode(), address ); + protected InternalDriver createRoutingDriver( + SecurityPlan securityPlan, + BoltServerAddress address, + ConnectionPool connectionPool, + EventExecutorGroup eventExecutorGroup, + RoutingSettings routingSettings, + RetryLogic retryLogic, + MetricsProvider metricsProvider, + Config config) { + ConnectionProvider connectionProvider = + createLoadBalancer(address, connectionPool, eventExecutorGroup, config, routingSettings); + SessionFactory sessionFactory = createSessionFactory(connectionProvider, retryLogic, config); + InternalDriver driver = createDriver(securityPlan, sessionFactory, metricsProvider, config); + Logger log = config.logging().getLog(getClass()); + log.info("Routing driver instance %s created for server address %s", driver.hashCode(), address); return driver; } @@ -206,9 +258,9 @@ protected InternalDriver createRoutingDriver( SecurityPlan securityPlan, BoltSer *

* This method is protected only for testing */ - protected InternalDriver createDriver( SecurityPlan securityPlan, SessionFactory sessionFactory, MetricsProvider metricsProvider, Config config ) - { - return new InternalDriver( securityPlan, sessionFactory, metricsProvider, config.logging() ); + protected InternalDriver createDriver( + SecurityPlan securityPlan, SessionFactory sessionFactory, MetricsProvider metricsProvider, Config config) { + return new InternalDriver(securityPlan, sessionFactory, metricsProvider, config.logging()); } /** @@ -216,14 +268,26 @@ protected InternalDriver createDriver( SecurityPlan securityPlan, SessionFactory *

* This method is protected only for testing */ - protected LoadBalancer createLoadBalancer( BoltServerAddress address, ConnectionPool connectionPool, - EventExecutorGroup eventExecutorGroup, Config config, RoutingSettings routingSettings ) - { - LoadBalancingStrategy loadBalancingStrategy = new LeastConnectedLoadBalancingStrategy( connectionPool, config.logging() ); - ServerAddressResolver resolver = createResolver( config ); - LoadBalancer loadBalancer = new LoadBalancer( address, routingSettings, connectionPool, eventExecutorGroup, createClock(), - config.logging(), loadBalancingStrategy, resolver, getDomainNameResolver() ); - handleNewLoadBalancer( loadBalancer ); + protected LoadBalancer createLoadBalancer( + BoltServerAddress address, + ConnectionPool connectionPool, + EventExecutorGroup eventExecutorGroup, + Config config, + RoutingSettings routingSettings) { + LoadBalancingStrategy loadBalancingStrategy = + new LeastConnectedLoadBalancingStrategy(connectionPool, config.logging()); + ServerAddressResolver resolver = createResolver(config); + LoadBalancer loadBalancer = new LoadBalancer( + address, + routingSettings, + connectionPool, + eventExecutorGroup, + createClock(), + config.logging(), + loadBalancingStrategy, + resolver, + getDomainNameResolver()); + handleNewLoadBalancer(loadBalancer); return loadBalancer; } @@ -234,12 +298,9 @@ protected LoadBalancer createLoadBalancer( BoltServerAddress address, Connection * * @param loadBalancer the new load balancer instance. */ - protected void handleNewLoadBalancer( LoadBalancer loadBalancer ) - { - } + protected void handleNewLoadBalancer(LoadBalancer loadBalancer) {} - private static ServerAddressResolver createResolver( Config config ) - { + private static ServerAddressResolver createResolver(Config config) { ServerAddressResolver configuredResolver = config.resolver(); return configuredResolver != null ? configuredResolver : IDENTITY_RESOLVER; } @@ -249,8 +310,7 @@ private static ServerAddressResolver createResolver( Config config ) *

* This method is protected only for testing */ - protected Clock createClock() - { + protected Clock createClock() { return Clock.SYSTEM; } @@ -259,10 +319,9 @@ protected Clock createClock() *

* This method is protected only for testing */ - protected SessionFactory createSessionFactory( ConnectionProvider connectionProvider, RetryLogic retryLogic, - Config config ) - { - return new SessionFactoryImpl( connectionProvider, retryLogic, config ); + protected SessionFactory createSessionFactory( + ConnectionProvider connectionProvider, RetryLogic retryLogic, Config config) { + return new SessionFactoryImpl(connectionProvider, retryLogic, config); } /** @@ -270,10 +329,9 @@ protected SessionFactory createSessionFactory( ConnectionProvider connectionProv *

* This method is protected only for testing */ - protected RetryLogic createRetryLogic( RetrySettings settings, EventExecutorGroup eventExecutorGroup, - Logging logging ) - { - return new ExponentialBackoffRetryLogic( settings, eventExecutorGroup, createClock(), logging ); + protected RetryLogic createRetryLogic( + RetrySettings settings, EventExecutorGroup eventExecutorGroup, Logging logging) { + return new ExponentialBackoffRetryLogic(settings, eventExecutorGroup, createClock(), logging); } /** @@ -281,9 +339,8 @@ protected RetryLogic createRetryLogic( RetrySettings settings, EventExecutorGrou *

* This method is protected only for testing */ - protected Bootstrap createBootstrap( int size ) - { - return BootstrapFactory.newBootstrap( size ); + protected Bootstrap createBootstrap(int size) { + return BootstrapFactory.newBootstrap(size); } /** @@ -291,9 +348,8 @@ protected Bootstrap createBootstrap( int size ) *

* This method is protected only for testing */ - protected Bootstrap createBootstrap( EventLoopGroup eventLoopGroup ) - { - return BootstrapFactory.newBootstrap( eventLoopGroup ); + protected Bootstrap createBootstrap(EventLoopGroup eventLoopGroup) { + return BootstrapFactory.newBootstrap(eventLoopGroup); } /** @@ -303,29 +359,22 @@ protected Bootstrap createBootstrap( EventLoopGroup eventLoopGroup ) * * @return the instance of {@link DomainNameResolver}. */ - protected DomainNameResolver getDomainNameResolver() - { + protected DomainNameResolver getDomainNameResolver() { return DefaultDomainNameResolver.getInstance(); } - private static void assertNoRoutingContext( URI uri, RoutingSettings routingSettings ) - { + private static void assertNoRoutingContext(URI uri, RoutingSettings routingSettings) { RoutingContext routingContext = routingSettings.routingContext(); - if ( routingContext.isDefined() ) - { - throw new IllegalArgumentException( NO_ROUTING_CONTEXT_ERROR_MESSAGE + "'" + uri + "'" ); + if (routingContext.isDefined()) { + throw new IllegalArgumentException(NO_ROUTING_CONTEXT_ERROR_MESSAGE + "'" + uri + "'"); } } - private static void closeConnectionPoolAndSuppressError( ConnectionPool connectionPool, Throwable mainError ) - { - try - { - Futures.blockingGet( connectionPool.close() ); - } - catch ( Throwable closeError ) - { - addSuppressed( mainError, closeError ); + private static void closeConnectionPoolAndSuppressError(ConnectionPool connectionPool, Throwable mainError) { + try { + Futures.blockingGet(connectionPool.close()); + } catch (Throwable closeError) { + addSuppressed(mainError, closeError); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/FailableCursor.java b/driver/src/main/java/org/neo4j/driver/internal/FailableCursor.java index 883ffe862e..4d55777283 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/FailableCursor.java +++ b/driver/src/main/java/org/neo4j/driver/internal/FailableCursor.java @@ -20,8 +20,7 @@ import java.util.concurrent.CompletionStage; -public interface FailableCursor -{ +public interface FailableCursor { /** * Discarding all unconsumed records and returning failure if there is any pull errors. */ diff --git a/driver/src/main/java/org/neo4j/driver/internal/ImpersonationUtil.java b/driver/src/main/java/org/neo4j/driver/internal/ImpersonationUtil.java index 0a944c7001..4aa0d67b6d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/ImpersonationUtil.java +++ b/driver/src/main/java/org/neo4j/driver/internal/ImpersonationUtil.java @@ -23,24 +23,20 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.ServerVersion; -public class ImpersonationUtil -{ +public class ImpersonationUtil { public static final String IMPERSONATION_UNSUPPORTED_ERROR_MESSAGE = - "Detected connection that does not support impersonation, please make sure to have all servers running 4.4 version or above and communicating" + - " over Bolt version 4.4 or above when using impersonation feature"; + "Detected connection that does not support impersonation, please make sure to have all servers running 4.4 version or above and communicating" + + " over Bolt version 4.4 or above when using impersonation feature"; - public static Connection ensureImpersonationSupport( Connection connection, String impersonatedUser ) - { - if ( impersonatedUser != null && !supportsImpersonation( connection ) ) - { - throw new ClientException( IMPERSONATION_UNSUPPORTED_ERROR_MESSAGE ); + public static Connection ensureImpersonationSupport(Connection connection, String impersonatedUser) { + if (impersonatedUser != null && !supportsImpersonation(connection)) { + throw new ClientException(IMPERSONATION_UNSUPPORTED_ERROR_MESSAGE); } return connection; } - private static boolean supportsImpersonation( Connection connection ) - { - return connection.serverVersion().greaterThanOrEqual( ServerVersion.v4_4_0 ) && - connection.protocol().version().compareTo( BoltProtocolV44.VERSION ) >= 0; + private static boolean supportsImpersonation(Connection connection) { + return connection.serverVersion().greaterThanOrEqual(ServerVersion.v4_4_0) + && connection.protocol().version().compareTo(BoltProtocolV44.VERSION) >= 0; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalBookmark.java b/driver/src/main/java/org/neo4j/driver/internal/InternalBookmark.java index c4ac5cbab7..c6c229fa5c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalBookmark.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalBookmark.java @@ -18,69 +18,56 @@ */ package org.neo4j.driver.internal; +import static java.util.Objects.requireNonNull; + import java.io.Serializable; import java.util.Collections; import java.util.HashSet; import java.util.Objects; import java.util.Set; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.internal.util.Iterables; -import static java.util.Objects.requireNonNull; - -public final class InternalBookmark implements Bookmark, Serializable -{ +public final class InternalBookmark implements Bookmark, Serializable { private static final long serialVersionUID = 8196096018245038950L; - private static final InternalBookmark EMPTY = new InternalBookmark( Collections.emptySet() ); + private static final InternalBookmark EMPTY = new InternalBookmark(Collections.emptySet()); private final Set values; - private InternalBookmark( Set values ) - { - requireNonNull( values ); + private InternalBookmark(Set values) { + requireNonNull(values); this.values = values; } - public static Bookmark empty() - { + public static Bookmark empty() { return EMPTY; } - public static Bookmark from( Iterable bookmarks ) - { - if ( bookmarks == null ) - { + public static Bookmark from(Iterable bookmarks) { + if (bookmarks == null) { return empty(); } - int size = Iterables.count( bookmarks ); - if ( size == 0 ) - { + int size = Iterables.count(bookmarks); + if (size == 0) { return empty(); - } - else if ( size == 1 ) - { - return from( bookmarks.iterator().next() ); + } else if (size == 1) { + return from(bookmarks.iterator().next()); } Set newValues = new HashSet<>(); - for ( Bookmark value : bookmarks ) - { - if ( value == null ) - { + for (Bookmark value : bookmarks) { + if (value == null) { continue; // skip any null bookmark value } - newValues.addAll( value.values() ); + newValues.addAll(value.values()); } - return new InternalBookmark( newValues ); + return new InternalBookmark(newValues); } - private static Bookmark from( Bookmark bookmark ) - { - if ( bookmark == null ) - { + private static Bookmark from(Bookmark bookmark) { + if (bookmark == null) { return empty(); } // it is safe to return the given bookmark as bookmarks values can not be modified once it is created. @@ -90,63 +77,52 @@ private static Bookmark from( Bookmark bookmark ) /** * Used to extract bookmark from metadata from server. */ - public static Bookmark parse( String value ) - { - if ( value == null ) - { + public static Bookmark parse(String value) { + if (value == null) { return empty(); } - return new InternalBookmark( Collections.singleton( value ) ); + return new InternalBookmark(Collections.singleton(value)); } /** * Used to reconstruct bookmark from values. */ - public static Bookmark parse( Set values ) - { - if ( values == null ) - { + public static Bookmark parse(Set values) { + if (values == null) { return empty(); } - return new InternalBookmark( values ); + return new InternalBookmark(values); } @Override - public boolean isEmpty() - { + public boolean isEmpty() { return values.isEmpty(); } @Override - public Set values() - { - return Collections.unmodifiableSet( values ); + public Set values() { + return Collections.unmodifiableSet(values); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalBookmark bookmark = (InternalBookmark) o; - return Objects.equals( values, bookmark.values ); + return Objects.equals(values, bookmark.values); } @Override - public int hashCode() - { - return Objects.hash( values ); + public int hashCode() { + return Objects.hash(values); } @Override - public String toString() - { + public String toString() { return "Bookmark{values=" + values + "}"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalDatabaseName.java b/driver/src/main/java/org/neo4j/driver/internal/InternalDatabaseName.java index 9812e491a0..11f0c6ffd0 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalDatabaseName.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalDatabaseName.java @@ -18,56 +18,47 @@ */ package org.neo4j.driver.internal; +import static java.util.Objects.requireNonNull; + import java.util.Objects; import java.util.Optional; -import static java.util.Objects.requireNonNull; - -public class InternalDatabaseName implements DatabaseName -{ +public class InternalDatabaseName implements DatabaseName { private final String databaseName; - InternalDatabaseName( String databaseName ) - { - this.databaseName = requireNonNull( databaseName ); + InternalDatabaseName(String databaseName) { + this.databaseName = requireNonNull(databaseName); } @Override - public Optional databaseName() - { - return Optional.of( databaseName ); + public Optional databaseName() { + return Optional.of(databaseName); } @Override - public String description() - { + public String description() { return databaseName; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalDatabaseName that = (InternalDatabaseName) o; - return databaseName.equals( that.databaseName ); + return databaseName.equals(that.databaseName); } @Override - public int hashCode() - { - return Objects.hash( databaseName ); + public int hashCode() { + return Objects.hash(databaseName); } @Override - public String toString() - { + public String toString() { return "InternalDatabaseName{" + "databaseName='" + databaseName + '\'' + '}'; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java b/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java index 8d9acaa9cb..c92bd372bf 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java @@ -18,20 +18,21 @@ */ package org.neo4j.driver.internal; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; + import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicBoolean; - import org.neo4j.driver.Driver; import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.Metrics; -import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.Session; import org.neo4j.driver.SessionConfig; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.internal.async.InternalAsyncSession; import org.neo4j.driver.internal.async.NetworkSession; import org.neo4j.driver.internal.metrics.DevNullMetricsProvider; +import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.internal.reactive.InternalRxSession; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.types.InternalTypeSystem; @@ -39,125 +40,108 @@ import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.types.TypeSystem; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; - -public class InternalDriver implements Driver -{ +public class InternalDriver implements Driver { private final SecurityPlan securityPlan; private final SessionFactory sessionFactory; private final Logger log; - private AtomicBoolean closed = new AtomicBoolean( false ); + private AtomicBoolean closed = new AtomicBoolean(false); private final MetricsProvider metricsProvider; - InternalDriver( SecurityPlan securityPlan, SessionFactory sessionFactory, MetricsProvider metricsProvider, Logging logging ) - { + InternalDriver( + SecurityPlan securityPlan, + SessionFactory sessionFactory, + MetricsProvider metricsProvider, + Logging logging) { this.securityPlan = securityPlan; this.sessionFactory = sessionFactory; this.metricsProvider = metricsProvider; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); } @Override - public Session session() - { - return new InternalSession( newSession( SessionConfig.defaultConfig() ) ); + public Session session() { + return new InternalSession(newSession(SessionConfig.defaultConfig())); } @Override - public Session session( SessionConfig sessionConfig ) - { - return new InternalSession( newSession( sessionConfig ) ); + public Session session(SessionConfig sessionConfig) { + return new InternalSession(newSession(sessionConfig)); } @Override - public RxSession rxSession() - { - return new InternalRxSession( newSession( SessionConfig.defaultConfig() ) ); + public RxSession rxSession() { + return new InternalRxSession(newSession(SessionConfig.defaultConfig())); } @Override - public RxSession rxSession( SessionConfig sessionConfig ) - { - return new InternalRxSession( newSession( sessionConfig ) ); + public RxSession rxSession(SessionConfig sessionConfig) { + return new InternalRxSession(newSession(sessionConfig)); } @Override - public AsyncSession asyncSession() - { - return new InternalAsyncSession( newSession( SessionConfig.defaultConfig() ) ); + public AsyncSession asyncSession() { + return new InternalAsyncSession(newSession(SessionConfig.defaultConfig())); } @Override - public AsyncSession asyncSession( SessionConfig sessionConfig ) - { - return new InternalAsyncSession( newSession( sessionConfig ) ); + public AsyncSession asyncSession(SessionConfig sessionConfig) { + return new InternalAsyncSession(newSession(sessionConfig)); } @Override - public Metrics metrics() - { + public Metrics metrics() { return metricsProvider.metrics(); } @Override - public boolean isMetricsEnabled() - { + public boolean isMetricsEnabled() { return metricsProvider != DevNullMetricsProvider.INSTANCE; } @Override - public boolean isEncrypted() - { + public boolean isEncrypted() { assertOpen(); return securityPlan.requiresEncryption(); } @Override - public void close() - { - Futures.blockingGet( closeAsync() ); + public void close() { + Futures.blockingGet(closeAsync()); } @Override - public CompletionStage closeAsync() - { - if ( closed.compareAndSet( false, true ) ) - { - log.info( "Closing driver instance %s", hashCode() ); + public CompletionStage closeAsync() { + if (closed.compareAndSet(false, true)) { + log.info("Closing driver instance %s", hashCode()); return sessionFactory.close(); } return completedWithNull(); } @Override - public final TypeSystem defaultTypeSystem() - { + public final TypeSystem defaultTypeSystem() { return InternalTypeSystem.TYPE_SYSTEM; } @Override - public CompletionStage verifyConnectivityAsync() - { + public CompletionStage verifyConnectivityAsync() { return sessionFactory.verifyConnectivity(); } @Override - public boolean supportsMultiDb() - { - return Futures.blockingGet( supportsMultiDbAsync() ); + public boolean supportsMultiDb() { + return Futures.blockingGet(supportsMultiDbAsync()); } @Override - public CompletionStage supportsMultiDbAsync() - { + public CompletionStage supportsMultiDbAsync() { return sessionFactory.supportsMultiDb(); } @Override - public void verifyConnectivity() - { - Futures.blockingGet( verifyConnectivityAsync() ); + public void verifyConnectivity() { + Futures.blockingGet(verifyConnectivityAsync()); } /** @@ -167,32 +151,26 @@ public void verifyConnectivity() * * @return the session factory used by this driver. */ - public SessionFactory getSessionFactory() - { + public SessionFactory getSessionFactory() { return sessionFactory; } - private static RuntimeException driverCloseException() - { - return new IllegalStateException( "This driver instance has already been closed" ); + private static RuntimeException driverCloseException() { + return new IllegalStateException("This driver instance has already been closed"); } - public NetworkSession newSession( SessionConfig config ) - { + public NetworkSession newSession(SessionConfig config) { assertOpen(); - NetworkSession session = sessionFactory.newInstance( config ); - if ( closed.get() ) - { + NetworkSession session = sessionFactory.newInstance(config); + if (closed.get()) { // session does not immediately acquire connection, it is fine to just throw throw driverCloseException(); } return session; } - private void assertOpen() - { - if ( closed.get() ) - { + private void assertOpen() { + if (closed.get()) { throw driverCloseException(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalEntity.java b/driver/src/main/java/org/neo4j/driver/internal/InternalEntity.java index bc7e194117..30d5da6913 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalEntity.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalEntity.java @@ -18,120 +18,98 @@ */ package org.neo4j.driver.internal; -import java.util.Map; +import static org.neo4j.driver.Values.ofObject; +import java.util.Map; +import java.util.function.Function; +import org.neo4j.driver.Value; +import org.neo4j.driver.Values; import org.neo4j.driver.internal.util.Extract; import org.neo4j.driver.internal.util.Iterables; import org.neo4j.driver.internal.value.MapValue; -import org.neo4j.driver.Value; -import org.neo4j.driver.Values; import org.neo4j.driver.types.Entity; -import java.util.function.Function; -import static org.neo4j.driver.Values.ofObject; - -public abstract class InternalEntity implements Entity, AsValue -{ +public abstract class InternalEntity implements Entity, AsValue { private final long id; - private final Map properties; + private final Map properties; - public InternalEntity( long id, Map properties ) - { + public InternalEntity(long id, Map properties) { this.id = id; this.properties = properties; } @Override - public long id() - { + public long id() { return id; } @Override - public int size() - { + public int size() { return properties.size(); } @Override - public Map asMap() - { - return asMap( ofObject() ); + public Map asMap() { + return asMap(ofObject()); } @Override - public Map asMap( Function mapFunction ) - { - return Extract.map( properties, mapFunction ); + public Map asMap(Function mapFunction) { + return Extract.map(properties, mapFunction); } @Override - public Value asValue() - { - return new MapValue( properties ); + public Value asValue() { + return new MapValue(properties); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalEntity that = (InternalEntity) o; return id == that.id; - } @Override - public int hashCode() - { - return (int)(id ^ (id >>> 32)); + public int hashCode() { + return (int) (id ^ (id >>> 32)); } @Override - public String toString() - { - return "Entity{" + - "id=" + id + - ", properties=" + properties + - '}'; + public String toString() { + return "Entity{" + "id=" + id + ", properties=" + properties + '}'; } @Override - public boolean containsKey( String key ) - { - return properties.containsKey( key ); + public boolean containsKey(String key) { + return properties.containsKey(key); } @Override - public Iterable keys() - { + public Iterable keys() { return properties.keySet(); } @Override - public Value get( String key ) - { - Value value = properties.get( key ); + public Value get(String key) { + Value value = properties.get(key); return value == null ? Values.NULL : value; } @Override - public Iterable values() - { + public Iterable values() { return properties.values(); } @Override - public Iterable values( Function mapFunction ) - { - return Iterables.map( properties.values(), mapFunction ); + public Iterable values(Function mapFunction) { + return Iterables.map(properties.values(), mapFunction); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalIsoDuration.java b/driver/src/main/java/org/neo4j/driver/internal/InternalIsoDuration.java index f3bc9aa3d4..f3376afe95 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalIsoDuration.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalIsoDuration.java @@ -18,6 +18,13 @@ */ package org.neo4j.driver.internal; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.NANOS; +import static java.time.temporal.ChronoUnit.SECONDS; +import static java.util.Arrays.asList; +import static java.util.Collections.unmodifiableList; + import java.time.Duration; import java.time.Period; import java.time.temporal.Temporal; @@ -25,43 +32,30 @@ import java.time.temporal.UnsupportedTemporalTypeException; import java.util.List; import java.util.Objects; - import org.neo4j.driver.types.IsoDuration; -import static java.time.temporal.ChronoUnit.DAYS; -import static java.time.temporal.ChronoUnit.MONTHS; -import static java.time.temporal.ChronoUnit.NANOS; -import static java.time.temporal.ChronoUnit.SECONDS; -import static java.util.Arrays.asList; -import static java.util.Collections.unmodifiableList; - -public class InternalIsoDuration implements IsoDuration -{ +public class InternalIsoDuration implements IsoDuration { private static final long NANOS_PER_SECOND = 1_000_000_000; - private static final List SUPPORTED_UNITS = unmodifiableList( asList( MONTHS, DAYS, SECONDS, NANOS ) ); + private static final List SUPPORTED_UNITS = unmodifiableList(asList(MONTHS, DAYS, SECONDS, NANOS)); private final long months; private final long days; private final long seconds; private final int nanoseconds; - public InternalIsoDuration( Period period ) - { - this( period.toTotalMonths(), period.getDays(), Duration.ZERO ); + public InternalIsoDuration(Period period) { + this(period.toTotalMonths(), period.getDays(), Duration.ZERO); } - public InternalIsoDuration( Duration duration ) - { - this( 0, 0, duration ); + public InternalIsoDuration(Duration duration) { + this(0, 0, duration); } - public InternalIsoDuration( long months, long days, long seconds, int nanoseconds ) - { - this( months, days, Duration.ofSeconds( seconds, nanoseconds ) ); + public InternalIsoDuration(long months, long days, long seconds, int nanoseconds) { + this(months, days, Duration.ofSeconds(seconds, nanoseconds)); } - InternalIsoDuration( long months, long days, Duration duration ) - { + InternalIsoDuration(long months, long days, Duration duration) { this.months = months; this.days = days; this.seconds = duration.getSeconds(); // normalized value of seconds @@ -69,166 +63,123 @@ public InternalIsoDuration( long months, long days, long seconds, int nanosecond } @Override - public long months() - { + public long months() { return months; } @Override - public long days() - { + public long days() { return days; } @Override - public long seconds() - { + public long seconds() { return seconds; } @Override - public int nanoseconds() - { + public int nanoseconds() { return nanoseconds; } @Override - public long get( TemporalUnit unit ) - { - if ( unit == MONTHS ) - { + public long get(TemporalUnit unit) { + if (unit == MONTHS) { return months; - } - else if ( unit == DAYS ) - { + } else if (unit == DAYS) { return days; - } - else if ( unit == SECONDS ) - { + } else if (unit == SECONDS) { return seconds; - } - else if ( unit == NANOS ) - { + } else if (unit == NANOS) { return nanoseconds; - } - else - { - throw new UnsupportedTemporalTypeException( "Unsupported unit: " + unit ); + } else { + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } } @Override - public List getUnits() - { + public List getUnits() { return SUPPORTED_UNITS; } @Override - public Temporal addTo( Temporal temporal ) - { - if ( months != 0 ) - { - temporal = temporal.plus( months, MONTHS ); + public Temporal addTo(Temporal temporal) { + if (months != 0) { + temporal = temporal.plus(months, MONTHS); } - if ( days != 0 ) - { - temporal = temporal.plus( days, DAYS ); + if (days != 0) { + temporal = temporal.plus(days, DAYS); } - if ( seconds != 0 ) - { - temporal = temporal.plus( seconds, SECONDS ); + if (seconds != 0) { + temporal = temporal.plus(seconds, SECONDS); } - if ( nanoseconds != 0 ) - { - temporal = temporal.plus( nanoseconds, NANOS ); + if (nanoseconds != 0) { + temporal = temporal.plus(nanoseconds, NANOS); } return temporal; } @Override - public Temporal subtractFrom( Temporal temporal ) - { - if ( months != 0 ) - { - temporal = temporal.minus( months, MONTHS ); + public Temporal subtractFrom(Temporal temporal) { + if (months != 0) { + temporal = temporal.minus(months, MONTHS); } - if ( days != 0 ) - { - temporal = temporal.minus( days, DAYS ); + if (days != 0) { + temporal = temporal.minus(days, DAYS); } - if ( seconds != 0 ) - { - temporal = temporal.minus( seconds, SECONDS ); + if (seconds != 0) { + temporal = temporal.minus(seconds, SECONDS); } - if ( nanoseconds != 0 ) - { - temporal = temporal.minus( nanoseconds, NANOS ); + if (nanoseconds != 0) { + temporal = temporal.minus(nanoseconds, NANOS); } return temporal; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalIsoDuration that = (InternalIsoDuration) o; - return months == that.months && - days == that.days && - seconds == that.seconds && - nanoseconds == that.nanoseconds; + return months == that.months && days == that.days && seconds == that.seconds && nanoseconds == that.nanoseconds; } @Override - public int hashCode() - { - return Objects.hash( months, days, seconds, nanoseconds ); + public int hashCode() { + return Objects.hash(months, days, seconds, nanoseconds); } @Override - public String toString() - { + public String toString() { StringBuilder sb = new StringBuilder(); - sb.append( 'P' ); - sb.append( months ).append( 'M' ); - sb.append( days ).append( 'D' ); - sb.append( 'T' ); - if ( seconds < 0 && nanoseconds > 0 ) - { - if ( seconds == -1 ) - { - sb.append( "-0" ); - } - else - { - sb.append( seconds + 1 ); + sb.append('P'); + sb.append(months).append('M'); + sb.append(days).append('D'); + sb.append('T'); + if (seconds < 0 && nanoseconds > 0) { + if (seconds == -1) { + sb.append("-0"); + } else { + sb.append(seconds + 1); } + } else { + sb.append(seconds); } - else - { - sb.append( seconds ); - } - if ( nanoseconds > 0 ) - { + if (nanoseconds > 0) { int pos = sb.length(); // append nanoseconds as a 10-digit string with leading '1' that is later replaced by a '.' - if ( seconds < 0 ) - { - sb.append( 2 * NANOS_PER_SECOND - nanoseconds ); - } - else - { - sb.append( NANOS_PER_SECOND + nanoseconds ); + if (seconds < 0) { + sb.append(2 * NANOS_PER_SECOND - nanoseconds); + } else { + sb.append(NANOS_PER_SECOND + nanoseconds); } - sb.setCharAt( pos, '.' ); // replace '1' with '.' + sb.setCharAt(pos, '.'); // replace '1' with '.' } - sb.append( 'S' ); + sb.append('S'); return sb.toString(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalNode.java b/driver/src/main/java/org/neo4j/driver/internal/InternalNode.java index e9a6938f1a..a26e3fa4a7 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalNode.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalNode.java @@ -21,50 +21,42 @@ import java.util.Collection; import java.util.Collections; import java.util.Map; - +import org.neo4j.driver.Value; import org.neo4j.driver.internal.value.NodeValue; import org.neo4j.driver.types.Node; -import org.neo4j.driver.Value; /** * {@link Node} implementation that directly contains labels and properties. */ -public class InternalNode extends InternalEntity implements Node -{ +public class InternalNode extends InternalEntity implements Node { private final Collection labels; - public InternalNode( long id ) - { - this( id, Collections.emptyList(), Collections.emptyMap() ); + public InternalNode(long id) { + this(id, Collections.emptyList(), Collections.emptyMap()); } - public InternalNode( long id, Collection labels, Map properties ) - { - super( id, properties ); + public InternalNode(long id, Collection labels, Map properties) { + super(id, properties); this.labels = labels; } @Override - public Collection labels() - { + public Collection labels() { return labels; } @Override - public boolean hasLabel( String label ) - { - return labels.contains( label ); + public boolean hasLabel(String label) { + return labels.contains(label); } @Override - public Value asValue() - { - return new NodeValue( this ); + public Value asValue() { + return new NodeValue(this); } @Override - public String toString() - { - return String.format( "node<%s>", id() ); + public String toString() { + return String.format("node<%s>", id()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalPair.java b/driver/src/main/java/org/neo4j/driver/internal/InternalPair.java index 6f88f1f9b6..a9bfeb5ce0 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalPair.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalPair.java @@ -19,63 +19,52 @@ package org.neo4j.driver.internal; import java.util.Objects; - import org.neo4j.driver.util.Pair; -public class InternalPair implements Pair -{ +public class InternalPair implements Pair { private final K key; private final V value; - protected InternalPair( K key, V value ) - { - Objects.requireNonNull( key ); - Objects.requireNonNull( value ); + protected InternalPair(K key, V value) { + Objects.requireNonNull(key); + Objects.requireNonNull(value); this.key = key; this.value = value; } - public K key() - { + public K key() { return key; } - public V value() - { + public V value() { return value; } - public static Pair of( K key, V value ) - { - return new InternalPair<>( key, value ); + public static Pair of(K key, V value) { + return new InternalPair<>(key, value); } @Override - public String toString() - { - return String.format( "%s: %s", Objects.toString( key ), Objects.toString( value ) ); + public String toString() { + return String.format("%s: %s", Objects.toString(key), Objects.toString(value)); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalPair that = (InternalPair) o; - return key.equals( that.key ) && value.equals( that.value ); + return key.equals(that.key) && value.equals(that.value); } @Override - public int hashCode() - { + public int hashCode() { int result = key.hashCode(); result = 31 * result + value.hashCode(); return result; diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalPath.java b/driver/src/main/java/org/neo4j/driver/internal/InternalPath.java index ba8990e075..e133cdfdb1 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalPath.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalPath.java @@ -23,70 +23,58 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; - +import org.neo4j.driver.Value; import org.neo4j.driver.internal.value.PathValue; import org.neo4j.driver.types.Entity; import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Path; import org.neo4j.driver.types.Relationship; -import org.neo4j.driver.Value; /** * {@link Path} implementation that directly contains all nodes and relationships. */ -public class InternalPath implements Path, AsValue -{ - public static class SelfContainedSegment implements Segment - { +public class InternalPath implements Path, AsValue { + public static class SelfContainedSegment implements Segment { private final Node start; private final Relationship relationship; private final Node end; - public SelfContainedSegment( Node start, Relationship relationship, Node end ) - { + public SelfContainedSegment(Node start, Relationship relationship, Node end) { this.start = start; this.relationship = relationship; this.end = end; } @Override - public Node start() - { + public Node start() { return start; } @Override - public Relationship relationship() - { + public Relationship relationship() { return relationship; } @Override - public Node end() - { + public Node end() { return end; } @Override - public boolean equals( Object other ) - { - if ( this == other ) - { + public boolean equals(Object other) { + if (this == other) { return true; } - if ( other == null || getClass() != other.getClass() ) - { + if (other == null || getClass() != other.getClass()) { return false; } SelfContainedSegment that = (SelfContainedSegment) other; - return start.equals( that.start ) && end.equals( that.end ) && relationship.equals( that.relationship ); - + return start.equals(that.start) && end.equals(that.end) && relationship.equals(that.relationship); } @Override - public int hashCode() - { + public int hashCode() { int result = start.hashCode(); result = 31 * result + relationship.hashCode(); result = 31 * result + end.hashCode(); @@ -94,89 +82,68 @@ public int hashCode() } @Override - public String toString() - { - return String.format( relationship.startNodeId() == start.id() ? - "(%s)-[%s:%s]->(%s)" : "(%s)<-[%s:%s]-(%s)", - start.id(), relationship.id(), relationship.type(), end.id() ); + public String toString() { + return String.format( + relationship.startNodeId() == start.id() ? "(%s)-[%s:%s]->(%s)" : "(%s)<-[%s:%s]-(%s)", + start.id(), + relationship.id(), + relationship.type(), + end.id()); } } - private static boolean isEndpoint( Node node, Relationship relationship ) - { - return node.id() == relationship.startNodeId() || node.id() == relationship.endNodeId(); + private static boolean isEndpoint(Node node, Relationship relationship) { + return node.id() == relationship.startNodeId() || node.id() == relationship.endNodeId(); } private final List nodes; private final List relationships; private final List segments; - public InternalPath( List alternatingNodeAndRel ) - { - nodes = newList( alternatingNodeAndRel.size() / 2 + 1 ); - relationships = newList( alternatingNodeAndRel.size() / 2 ); - segments = newList( alternatingNodeAndRel.size() / 2 ); + public InternalPath(List alternatingNodeAndRel) { + nodes = newList(alternatingNodeAndRel.size() / 2 + 1); + relationships = newList(alternatingNodeAndRel.size() / 2); + segments = newList(alternatingNodeAndRel.size() / 2); - if ( alternatingNodeAndRel.size() % 2 == 0 ) - { - throw new IllegalArgumentException( "An odd number of entities are required to build a path" ); + if (alternatingNodeAndRel.size() % 2 == 0) { + throw new IllegalArgumentException("An odd number of entities are required to build a path"); } Node lastNode = null; Relationship lastRelationship = null; int index = 0; - for ( Entity entity : alternatingNodeAndRel ) - { - if ( entity == null ) - { - throw new IllegalArgumentException( "Path entities cannot be null" ); + for (Entity entity : alternatingNodeAndRel) { + if (entity == null) { + throw new IllegalArgumentException("Path entities cannot be null"); } - if ( index % 2 == 0 ) - { + if (index % 2 == 0) { // even index - this should be a node - try - { + try { lastNode = (Node) entity; - if ( nodes.isEmpty() || isEndpoint( lastNode, lastRelationship ) ) - { - nodes.add( lastNode ); - } - else - { - throw new IllegalArgumentException( - "Node argument " + index + " is not an endpoint of relationship argument " + (index - - 1) ); + if (nodes.isEmpty() || isEndpoint(lastNode, lastRelationship)) { + nodes.add(lastNode); + } else { + throw new IllegalArgumentException("Node argument " + index + + " is not an endpoint of relationship argument " + (index - 1)); } - } - catch ( ClassCastException e ) - { + } catch (ClassCastException e) { String cls = entity.getClass().getName(); - throw new IllegalArgumentException( - "Expected argument " + index + " to be a node " + index + " but found a " + cls + " " + - "instead" ); + throw new IllegalArgumentException("Expected argument " + index + " to be a node " + index + + " but found a " + cls + " " + "instead"); } - } - else - { + } else { // odd index - this should be a relationship - try - { + try { lastRelationship = (Relationship) entity; - if ( isEndpoint( lastNode, lastRelationship ) ) - { - relationships.add( lastRelationship ); - } - else - { - throw new IllegalArgumentException( - "Node argument " + (index - 1) + " is not an endpoint of relationship argument " + - index ); + if (isEndpoint(lastNode, lastRelationship)) { + relationships.add(lastRelationship); + } else { + throw new IllegalArgumentException("Node argument " + (index - 1) + + " is not an endpoint of relationship argument " + index); } - } - catch ( ClassCastException e ) - { + } catch (ClassCastException e) { String cls = entity.getClass().getName(); throw new IllegalArgumentException( - "Expected argument " + index + " to be a relationship but found a " + cls + " instead" ); + "Expected argument " + index + " to be a relationship but found a " + cls + " instead"); } } index += 1; @@ -184,113 +151,93 @@ public InternalPath( List alternatingNodeAndRel ) buildSegments(); } - public InternalPath( Entity... alternatingNodeAndRel ) - { - this( Arrays.asList( alternatingNodeAndRel ) ); + public InternalPath(Entity... alternatingNodeAndRel) { + this(Arrays.asList(alternatingNodeAndRel)); } - public InternalPath( List segments, List nodes, List relationships ) - { + public InternalPath(List segments, List nodes, List relationships) { this.segments = segments; this.nodes = nodes; this.relationships = relationships; } - private List newList( int size ) - { - return size == 0 ? Collections.emptyList() : new ArrayList( size ); + private List newList(int size) { + return size == 0 ? Collections.emptyList() : new ArrayList(size); } @Override - public int length() - { + public int length() { return relationships.size(); } @Override - public boolean contains( Node node ) - { - return nodes.contains( node ); + public boolean contains(Node node) { + return nodes.contains(node); } @Override - public boolean contains( Relationship relationship ) - { - return relationships.contains( relationship ); + public boolean contains(Relationship relationship) { + return relationships.contains(relationship); } @Override - public Iterable nodes() - { + public Iterable nodes() { return nodes; } @Override - public Iterable relationships() - { + public Iterable relationships() { return relationships; } @Override - public Node start() - { - return nodes.get( 0 ); + public Node start() { + return nodes.get(0); } @Override - public Node end() - { - return nodes.get( nodes.size() - 1 ); + public Node end() { + return nodes.get(nodes.size() - 1); } @Override - public Iterator iterator() - { + public Iterator iterator() { return segments.iterator(); } @Override - public Value asValue() - { - return new PathValue( this ); + public Value asValue() { + return new PathValue(this); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalPath segments1 = (InternalPath) o; - return segments.equals( segments1.segments ); - + return segments.equals(segments1.segments); } @Override - public int hashCode() - { + public int hashCode() { return segments.hashCode(); } @Override - public String toString() - { + public String toString() { return "path" + segments; } - private void buildSegments() - { - for ( int i = 0; i < relationships.size(); i++ ) - { - segments.add( new SelfContainedSegment( nodes.get( i ), relationships.get( i ), nodes.get( i + 1 ) ) ); + private void buildSegments() { + for (int i = 0; i < relationships.size(); i++) { + segments.add(new SelfContainedSegment(nodes.get(i), relationships.get(i), nodes.get(i + 1))); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalPoint2D.java b/driver/src/main/java/org/neo4j/driver/internal/InternalPoint2D.java index edfeba8949..7450ecf3cc 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalPoint2D.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalPoint2D.java @@ -19,76 +19,58 @@ package org.neo4j.driver.internal; import java.util.Objects; - import org.neo4j.driver.types.Point; -public class InternalPoint2D implements Point -{ +public class InternalPoint2D implements Point { private final int srid; private final double x; private final double y; - public InternalPoint2D( int srid, double x, double y ) - { + public InternalPoint2D(int srid, double x, double y) { this.srid = srid; this.x = x; this.y = y; } @Override - public int srid() - { + public int srid() { return srid; } @Override - public double x() - { + public double x() { return x; } @Override - public double y() - { + public double y() { return y; } @Override - public double z() - { + public double z() { return Double.NaN; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalPoint2D that = (InternalPoint2D) o; - return srid == that.srid && - Double.compare( that.x, x ) == 0 && - Double.compare( that.y, y ) == 0; + return srid == that.srid && Double.compare(that.x, x) == 0 && Double.compare(that.y, y) == 0; } @Override - public int hashCode() - { - return Objects.hash( srid, x, y ); + public int hashCode() { + return Objects.hash(srid, x, y); } @Override - public String toString() - { - return "Point{" + - "srid=" + srid + - ", x=" + x + - ", y=" + y + - '}'; + public String toString() { + return "Point{" + "srid=" + srid + ", x=" + x + ", y=" + y + '}'; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalPoint3D.java b/driver/src/main/java/org/neo4j/driver/internal/InternalPoint3D.java index 31b8e99fc7..0e0efad437 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalPoint3D.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalPoint3D.java @@ -19,18 +19,15 @@ package org.neo4j.driver.internal; import java.util.Objects; - import org.neo4j.driver.types.Point; -public class InternalPoint3D implements Point -{ +public class InternalPoint3D implements Point { private final int srid; private final double x; private final double y; private final double z; - public InternalPoint3D( int srid, double x, double y, double z ) - { + public InternalPoint3D(int srid, double x, double y, double z) { this.srid = srid; this.x = x; this.y = y; @@ -38,61 +35,47 @@ public InternalPoint3D( int srid, double x, double y, double z ) } @Override - public int srid() - { + public int srid() { return srid; } @Override - public double x() - { + public double x() { return x; } @Override - public double y() - { + public double y() { return y; } @Override - public double z() - { + public double z() { return z; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalPoint3D that = (InternalPoint3D) o; - return srid == that.srid && - Double.compare( that.x, x ) == 0 && - Double.compare( that.y, y ) == 0 && - Double.compare( that.z, z ) == 0; + return srid == that.srid + && Double.compare(that.x, x) == 0 + && Double.compare(that.y, y) == 0 + && Double.compare(that.z, z) == 0; } @Override - public int hashCode() - { - return Objects.hash( srid, x, y, z ); + public int hashCode() { + return Objects.hash(srid, x, y, z); } @Override - public String toString() - { - return "Point{" + - "srid=" + srid + - ", x=" + x + - ", y=" + y + - ", z=" + z + - '}'; + public String toString() { + return "Point{" + "srid=" + srid + ", x=" + x + ", y=" + y + ", z=" + z + '}'; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalRecord.java b/driver/src/main/java/org/neo4j/driver/internal/InternalRecord.java index f5d8dce69c..5c72ff9a65 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalRecord.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalRecord.java @@ -18,13 +18,17 @@ */ package org.neo4j.driver.internal; +import static java.lang.String.format; +import static org.neo4j.driver.Values.ofObject; +import static org.neo4j.driver.Values.ofValue; +import static org.neo4j.driver.internal.util.Format.formatPairs; + import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.function.Function; import java.util.stream.Collectors; - import org.neo4j.driver.Record; import org.neo4j.driver.Value; import org.neo4j.driver.Values; @@ -33,160 +37,122 @@ import org.neo4j.driver.internal.util.QueryKeys; import org.neo4j.driver.util.Pair; -import static java.lang.String.format; -import static org.neo4j.driver.Values.ofObject; -import static org.neo4j.driver.Values.ofValue; -import static org.neo4j.driver.internal.util.Format.formatPairs; - -public class InternalRecord extends InternalMapAccessorWithDefaultValue implements Record -{ +public class InternalRecord extends InternalMapAccessorWithDefaultValue implements Record { private final QueryKeys queryKeys; private final Value[] values; private int hashCode = 0; - public InternalRecord( List keys, Value[] values ) - { - this.queryKeys = new QueryKeys( keys ); + public InternalRecord(List keys, Value[] values) { + this.queryKeys = new QueryKeys(keys); this.values = values; } - public InternalRecord( QueryKeys queryKeys, Value[] values ) - { + public InternalRecord(QueryKeys queryKeys, Value[] values) { this.queryKeys = queryKeys; this.values = values; } @Override - public List keys() - { + public List keys() { return queryKeys.keys(); } @Override - public List values() - { - return Arrays.asList( values ); + public List values() { + return Arrays.asList(values); } @Override - public Iterable values( Function mapFunction ) - { - return values().stream().map( mapFunction ).collect( Collectors.toList() ); + public Iterable values(Function mapFunction) { + return values().stream().map(mapFunction).collect(Collectors.toList()); } @Override - public List> fields() - { - return Extract.fields( this, ofValue() ); + public List> fields() { + return Extract.fields(this, ofValue()); } @Override - public int index( String key ) - { - int result = queryKeys.indexOf( key ); - if ( result == -1 ) - { - throw new NoSuchElementException( "Unknown key: " + key ); - } - else - { + public int index(String key) { + int result = queryKeys.indexOf(key); + if (result == -1) { + throw new NoSuchElementException("Unknown key: " + key); + } else { return result; } } @Override - public boolean containsKey( String key ) - { - return queryKeys.contains( key ); + public boolean containsKey(String key) { + return queryKeys.contains(key); } @Override - public Value get( String key ) - { - int fieldIndex = queryKeys.indexOf( key ); + public Value get(String key) { + int fieldIndex = queryKeys.indexOf(key); - if ( fieldIndex == -1 ) - { + if (fieldIndex == -1) { return Values.NULL; - } - else - { + } else { return values[fieldIndex]; } } @Override - public Value get( int index ) - { + public Value get(int index) { return index >= 0 && index < values.length ? values[index] : Values.NULL; } @Override - public int size() - { + public int size() { return values.length; } @Override - public Map asMap() - { - return Extract.map( this, ofObject() ); + public Map asMap() { + return Extract.map(this, ofObject()); } @Override - public Map asMap( Function mapper ) - { - return Extract.map( this, mapper ); + public Map asMap(Function mapper) { + return Extract.map(this, mapper); } @Override - public String toString() - { - return format( "Record<%s>", formatPairs( asMap( ofValue() ) ) ); + public String toString() { + return format("Record<%s>", formatPairs(asMap(ofValue()))); } @Override - public boolean equals( Object other ) - { - if ( this == other ) - { + public boolean equals(Object other) { + if (this == other) { return true; - } - else if ( other instanceof Record ) - { + } else if (other instanceof Record) { Record otherRecord = (Record) other; int size = size(); - if ( ! ( size == otherRecord.size() ) ) - { + if (!(size == otherRecord.size())) { return false; } - if ( !queryKeys.keys().equals( otherRecord.keys() ) ) - { + if (!queryKeys.keys().equals(otherRecord.keys())) { return false; } - for ( int i = 0; i < size; i++ ) - { - Value value = get( i ); - Value otherValue = otherRecord.get( i ); - if ( ! value.equals( otherValue ) ) - { + for (int i = 0; i < size; i++) { + Value value = get(i); + Value otherValue = otherRecord.get(i); + if (!value.equals(otherValue)) { return false; } } return true; - } - else - { + } else { return false; } } @Override - public int hashCode() - { - if ( hashCode == 0 ) - { - hashCode = 31 * queryKeys.hashCode() + Arrays.hashCode( values ); + public int hashCode() { + if (hashCode == 0) { + hashCode = 31 * queryKeys.hashCode() + Arrays.hashCode(values); } return hashCode; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalRelationship.java b/driver/src/main/java/org/neo4j/driver/internal/InternalRelationship.java index dfe00395e2..bf3da7c306 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalRelationship.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalRelationship.java @@ -20,74 +20,62 @@ import java.util.Collections; import java.util.Map; - +import org.neo4j.driver.Value; import org.neo4j.driver.internal.value.RelationshipValue; import org.neo4j.driver.types.Relationship; -import org.neo4j.driver.Value; /** * {@link Relationship} implementation that directly contains type and properties. */ -public class InternalRelationship extends InternalEntity implements Relationship -{ +public class InternalRelationship extends InternalEntity implements Relationship { private long start; private long end; private final String type; - public InternalRelationship( long id, long start, long end, String type ) - { - this( id, start, end, type, Collections.emptyMap() ); + public InternalRelationship(long id, long start, long end, String type) { + this(id, start, end, type, Collections.emptyMap()); } - public InternalRelationship( long id, long start, long end, String type, - Map properties ) - { - super( id, properties ); + public InternalRelationship(long id, long start, long end, String type, Map properties) { + super(id, properties); this.start = start; this.end = end; this.type = type; } @Override - public boolean hasType( String relationshipType ) - { - return type().equals( relationshipType ); + public boolean hasType(String relationshipType) { + return type().equals(relationshipType); } /** Modify the start/end identities of this relationship */ - public void setStartAndEnd( long start, long end ) - { + public void setStartAndEnd(long start, long end) { this.start = start; this.end = end; } @Override - public long startNodeId() - { + public long startNodeId() { return start; } @Override - public long endNodeId() - { + public long endNodeId() { return end; } @Override - public String type() - { + public String type() { return type; } @Override - public Value asValue() - { - return new RelationshipValue( this ); + public Value asValue() { + return new RelationshipValue(this); } @Override - public String toString() - { - return String.format( "relationship<%s>", id() ); + public String toString() { + return String.format("relationship<%s>", id()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalResult.java b/driver/src/main/java/org/neo4j/driver/internal/InternalResult.java index f0bf0a78a8..f123b67ae4 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalResult.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalResult.java @@ -25,7 +25,6 @@ import java.util.function.Function; import java.util.stream.Stream; import java.util.stream.StreamSupport; - import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.async.ResultCursor; @@ -35,95 +34,80 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.summary.ResultSummary; -public class InternalResult implements Result -{ +public class InternalResult implements Result { private final Connection connection; private final ResultCursor cursor; - public InternalResult(Connection connection, ResultCursor cursor ) - { + public InternalResult(Connection connection, ResultCursor cursor) { this.connection = connection; this.cursor = cursor; } @Override - public List keys() - { + public List keys() { return cursor.keys(); } @Override - public boolean hasNext() - { - return blockingGet( cursor.peekAsync() ) != null; + public boolean hasNext() { + return blockingGet(cursor.peekAsync()) != null; } @Override - public Record next() - { - Record record = blockingGet( cursor.nextAsync() ); - if ( record == null ) - { - throw new NoSuchRecordException( "No more records" ); + public Record next() { + Record record = blockingGet(cursor.nextAsync()); + if (record == null) { + throw new NoSuchRecordException("No more records"); } return record; } @Override - public Record single() - { - return blockingGet( cursor.singleAsync() ); + public Record single() { + return blockingGet(cursor.singleAsync()); } @Override - public Record peek() - { - Record record = blockingGet( cursor.peekAsync() ); - if ( record == null ) - { - throw new NoSuchRecordException( "Cannot peek past the last record" ); + public Record peek() { + Record record = blockingGet(cursor.peekAsync()); + if (record == null) { + throw new NoSuchRecordException("Cannot peek past the last record"); } return record; } @Override - public Stream stream() - { - Spliterator spliterator = Spliterators.spliteratorUnknownSize( this, Spliterator.IMMUTABLE | Spliterator.ORDERED ); - return StreamSupport.stream( spliterator, false ); + public Stream stream() { + Spliterator spliterator = + Spliterators.spliteratorUnknownSize(this, Spliterator.IMMUTABLE | Spliterator.ORDERED); + return StreamSupport.stream(spliterator, false); } @Override - public List list() - { - return blockingGet( cursor.listAsync() ); + public List list() { + return blockingGet(cursor.listAsync()); } @Override - public List list( Function mapFunction ) - { - return blockingGet( cursor.listAsync( mapFunction ) ); + public List list(Function mapFunction) { + return blockingGet(cursor.listAsync(mapFunction)); } @Override - public ResultSummary consume() - { - return blockingGet( cursor.consumeAsync() ); + public ResultSummary consume() { + return blockingGet(cursor.consumeAsync()); } @Override - public void remove() - { - throw new ClientException( "Removing records from a result is not supported." ); + public void remove() { + throw new ClientException("Removing records from a result is not supported."); } - private T blockingGet( CompletionStage stage ) - { - return Futures.blockingGet( stage, this::terminateConnectionOnThreadInterrupt ); + private T blockingGet(CompletionStage stage) { + return Futures.blockingGet(stage, this::terminateConnectionOnThreadInterrupt); } - private void terminateConnectionOnThreadInterrupt() - { - connection.terminateAndRelease( "Thread interrupted while waiting for result to arrive" ); + private void terminateConnectionOnThreadInterrupt() { + connection.terminateAndRelease("Thread interrupted while waiting for result to arrive"); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalSession.java b/driver/src/main/java/org/neo4j/driver/internal/InternalSession.java index 22aa387f1a..f0453fe60f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalSession.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalSession.java @@ -18,8 +18,9 @@ */ package org.neo4j.driver.internal; -import java.util.Map; +import static java.util.Collections.emptyMap; +import java.util.Map; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -34,153 +35,133 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.Futures; -import static java.util.Collections.emptyMap; - -public class InternalSession extends AbstractQueryRunner implements Session -{ +public class InternalSession extends AbstractQueryRunner implements Session { private final NetworkSession session; - public InternalSession( NetworkSession session ) - { + public InternalSession(NetworkSession session) { this.session = session; } @Override - public Result run(Query query) - { - return run(query, TransactionConfig.empty() ); + public Result run(Query query) { + return run(query, TransactionConfig.empty()); } @Override - public Result run(String query, TransactionConfig config ) - { - return run(query, emptyMap(), config ); + public Result run(String query, TransactionConfig config) { + return run(query, emptyMap(), config); } @Override - public Result run(String query, Map parameters, TransactionConfig config ) - { - return run( new Query(query, parameters ), config ); + public Result run(String query, Map parameters, TransactionConfig config) { + return run(new Query(query, parameters), config); } @Override - public Result run(Query query, TransactionConfig config ) - { - ResultCursor cursor = Futures.blockingGet( session.runAsync( query, config ), - () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while running query in session" ) ); + public Result run(Query query, TransactionConfig config) { + ResultCursor cursor = Futures.blockingGet( + session.runAsync(query, config), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while running query in session")); // query executed, it is safe to obtain a connection in a blocking way - Connection connection = Futures.getNow( session.connectionAsync() ); - return new InternalResult( connection, cursor ); + Connection connection = Futures.getNow(session.connectionAsync()); + return new InternalResult(connection, cursor); } @Override - public boolean isOpen() - { + public boolean isOpen() { return session.isOpen(); } @Override - public void close() - { - Futures.blockingGet( session.closeAsync(), () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while closing the session" ) ); + public void close() { + Futures.blockingGet( + session.closeAsync(), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while closing the session")); } @Override - public Transaction beginTransaction() - { - return beginTransaction( TransactionConfig.empty() ); + public Transaction beginTransaction() { + return beginTransaction(TransactionConfig.empty()); } @Override - public Transaction beginTransaction( TransactionConfig config ) - { - UnmanagedTransaction tx = Futures.blockingGet( session.beginTransactionAsync( config ), - () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while starting a transaction" ) ); - return new InternalTransaction( tx ); + public Transaction beginTransaction(TransactionConfig config) { + UnmanagedTransaction tx = Futures.blockingGet( + session.beginTransactionAsync(config), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while starting a transaction")); + return new InternalTransaction(tx); } @Override - public T readTransaction( TransactionWork work ) - { - return readTransaction( work, TransactionConfig.empty() ); + public T readTransaction(TransactionWork work) { + return readTransaction(work, TransactionConfig.empty()); } @Override - public T readTransaction( TransactionWork work, TransactionConfig config ) - { - return transaction( AccessMode.READ, work, config ); + public T readTransaction(TransactionWork work, TransactionConfig config) { + return transaction(AccessMode.READ, work, config); } @Override - public T writeTransaction( TransactionWork work ) - { - return writeTransaction( work, TransactionConfig.empty() ); + public T writeTransaction(TransactionWork work) { + return writeTransaction(work, TransactionConfig.empty()); } @Override - public T writeTransaction( TransactionWork work, TransactionConfig config ) - { - return transaction( AccessMode.WRITE, work, config ); + public T writeTransaction(TransactionWork work, TransactionConfig config) { + return transaction(AccessMode.WRITE, work, config); } @Override - public Bookmark lastBookmark() - { + public Bookmark lastBookmark() { return session.lastBookmark(); } @Override - @SuppressWarnings( "deprecation" ) - public void reset() - { - Futures.blockingGet( session.resetAsync(), () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while resetting the session" ) ); + @SuppressWarnings("deprecation") + public void reset() { + Futures.blockingGet( + session.resetAsync(), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while resetting the session")); } - private T transaction( AccessMode mode, TransactionWork work, TransactionConfig config ) - { + private T transaction(AccessMode mode, TransactionWork work, TransactionConfig config) { // use different code path compared to async so that work is executed in the caller thread // caller thread will also be the one who sleeps between retries; // it is unsafe to execute retries in the event loop threads because this can cause a deadlock // event loop thread will bock and wait for itself to read some data - return session.retryLogic().retry( () -> { - try ( Transaction tx = beginTransaction( mode, config ) ) - { + return session.retryLogic().retry(() -> { + try (Transaction tx = beginTransaction(mode, config)) { - T result = work.execute( tx ); - if ( tx.isOpen() ) - { + T result = work.execute(tx); + if (tx.isOpen()) { // commit tx if a user has not explicitly committed or rolled back the transaction tx.commit(); } return result; } - } ); + }); } - private Transaction beginTransaction( AccessMode mode, TransactionConfig config ) - { - UnmanagedTransaction tx = Futures.blockingGet( session.beginTransactionAsync( mode, config ), - () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while starting a transaction" ) ); - return new InternalTransaction( tx ); + private Transaction beginTransaction(AccessMode mode, TransactionConfig config) { + UnmanagedTransaction tx = Futures.blockingGet( + session.beginTransactionAsync(mode, config), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while starting a transaction")); + return new InternalTransaction(tx); } - private void terminateConnectionOnThreadInterrupt( String reason ) - { + private void terminateConnectionOnThreadInterrupt(String reason) { // try to get current connection if it has been acquired Connection connection = null; - try - { - connection = Futures.getNow( session.connectionAsync() ); - } - catch ( Throwable ignore ) - { + try { + connection = Futures.getNow(session.connectionAsync()); + } catch (Throwable ignore) { // ignore errors because handing interruptions is best effort } - if ( connection != null ) - { - connection.terminateAndRelease( reason ); + if (connection != null) { + connection.terminateAndRelease(reason); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalTransaction.java b/driver/src/main/java/org/neo4j/driver/internal/InternalTransaction.java index 2ef687f324..37e7b3a6ef 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalTransaction.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalTransaction.java @@ -25,51 +25,48 @@ import org.neo4j.driver.internal.async.UnmanagedTransaction; import org.neo4j.driver.internal.util.Futures; -public class InternalTransaction extends AbstractQueryRunner implements Transaction -{ +public class InternalTransaction extends AbstractQueryRunner implements Transaction { private final UnmanagedTransaction tx; - public InternalTransaction( UnmanagedTransaction tx ) - { + + public InternalTransaction(UnmanagedTransaction tx) { this.tx = tx; } @Override - public void commit() - { - Futures.blockingGet( tx.commitAsync(), - () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while committing the transaction" ) ); + public void commit() { + Futures.blockingGet( + tx.commitAsync(), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while committing the transaction")); } @Override - public void rollback() - { - Futures.blockingGet( tx.rollbackAsync(), - () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while rolling back the transaction" ) ); + public void rollback() { + Futures.blockingGet( + tx.rollbackAsync(), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while rolling back the transaction")); } @Override - public void close() - { - Futures.blockingGet( tx.closeAsync(), - () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while closing the transaction" ) ); + public void close() { + Futures.blockingGet( + tx.closeAsync(), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while closing the transaction")); } @Override - public Result run(Query query) - { - ResultCursor cursor = Futures.blockingGet( tx.runAsync( query ), - () -> terminateConnectionOnThreadInterrupt( "Thread interrupted while running query in transaction" ) ); - return new InternalResult( tx.connection(), cursor ); + public Result run(Query query) { + ResultCursor cursor = Futures.blockingGet( + tx.runAsync(query), + () -> terminateConnectionOnThreadInterrupt("Thread interrupted while running query in transaction")); + return new InternalResult(tx.connection(), cursor); } @Override - public boolean isOpen() - { + public boolean isOpen() { return tx.isOpen(); } - private void terminateConnectionOnThreadInterrupt( String reason ) - { - tx.connection().terminateAndRelease( reason ); + private void terminateConnectionOnThreadInterrupt(String reason) { + tx.connection().terminateAndRelease(reason); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/ReadOnlyBookmarkHolder.java b/driver/src/main/java/org/neo4j/driver/internal/ReadOnlyBookmarkHolder.java index c828f07aee..5bf2c11dcb 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/ReadOnlyBookmarkHolder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/ReadOnlyBookmarkHolder.java @@ -23,24 +23,20 @@ /** * @since 2.0 */ -public class ReadOnlyBookmarkHolder implements BookmarkHolder -{ +public class ReadOnlyBookmarkHolder implements BookmarkHolder { private final Bookmark bookmark; - public ReadOnlyBookmarkHolder( Bookmark bookmark ) - { + public ReadOnlyBookmarkHolder(Bookmark bookmark) { this.bookmark = bookmark; } @Override - public Bookmark getBookmark() - { + public Bookmark getBookmark() { return bookmark; } @Override - public void setBookmark( Bookmark bookmark ) - { + public void setBookmark(Bookmark bookmark) { // NO_OP } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/ResolvedBoltServerAddress.java b/driver/src/main/java/org/neo4j/driver/internal/ResolvedBoltServerAddress.java index 6fa357f987..6e520dacec 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/ResolvedBoltServerAddress.java +++ b/driver/src/main/java/org/neo4j/driver/internal/ResolvedBoltServerAddress.java @@ -18,6 +18,9 @@ */ package org.neo4j.driver.internal; +import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.joining; + import java.net.InetAddress; import java.util.Arrays; import java.util.Collections; @@ -26,14 +29,10 @@ import java.util.Set; import java.util.stream.Stream; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; - /** * An explicitly resolved version of {@link BoltServerAddress} that always contains one or more resolved IP addresses. */ -public class ResolvedBoltServerAddress extends BoltServerAddress -{ +public class ResolvedBoltServerAddress extends BoltServerAddress { private static final String HOST_ADDRESSES_FORMAT = "%s%s:%d"; private static final int MAX_HOST_ADDRESSES_IN_STRING_VALUE = 5; private static final String HOST_ADDRESS_DELIMITER = ","; @@ -44,16 +43,14 @@ public class ResolvedBoltServerAddress extends BoltServerAddress private final Set resolvedAddresses; private final String stringValue; - public ResolvedBoltServerAddress( String host, int port, InetAddress[] resolvedAddressesArr ) - { - super( host, port ); - requireNonNull( resolvedAddressesArr, "resolvedAddressesArr" ); - if ( resolvedAddressesArr.length == 0 ) - { + public ResolvedBoltServerAddress(String host, int port, InetAddress[] resolvedAddressesArr) { + super(host, port); + requireNonNull(resolvedAddressesArr, "resolvedAddressesArr"); + if (resolvedAddressesArr.length == 0) { throw new IllegalArgumentException( - "The resolvedAddressesArr must not be empty, check your DomainNameResolver is compliant with the interface contract" ); + "The resolvedAddressesArr must not be empty, check your DomainNameResolver is compliant with the interface contract"); } - resolvedAddresses = Collections.unmodifiableSet( new LinkedHashSet<>( Arrays.asList( resolvedAddressesArr ) ) ); + resolvedAddresses = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(resolvedAddressesArr))); stringValue = createStringRepresentation(); } @@ -65,51 +62,45 @@ public ResolvedBoltServerAddress( String host, int port, InetAddress[] resolvedA * @return stream of unicast addresses. */ @Override - public Stream unicastStream() - { - return resolvedAddresses.stream().map( address -> new BoltServerAddress( host, address.getHostAddress(), port ) ); + public Stream unicastStream() { + return resolvedAddresses.stream().map(address -> new BoltServerAddress(host, address.getHostAddress(), port)); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } - if ( !super.equals( o ) ) - { + if (!super.equals(o)) { return false; } ResolvedBoltServerAddress that = (ResolvedBoltServerAddress) o; - return resolvedAddresses.equals( that.resolvedAddresses ); + return resolvedAddresses.equals(that.resolvedAddresses); } @Override - public int hashCode() - { - return Objects.hash( super.hashCode(), resolvedAddresses ); + public int hashCode() { + return Objects.hash(super.hashCode(), resolvedAddresses); } @Override - public String toString() - { + public String toString() { return stringValue; } - private String createStringRepresentation() - { + private String createStringRepresentation() { String hostAddresses = resolvedAddresses.stream() - .limit( MAX_HOST_ADDRESSES_IN_STRING_VALUE ) - .map( InetAddress::getHostAddress ) - .collect( joining( HOST_ADDRESS_DELIMITER, HOST_ADDRESSES_PREFIX, - resolvedAddresses.size() > MAX_HOST_ADDRESSES_IN_STRING_VALUE - ? TRIMMED_HOST_ADDRESSES_SUFFIX - : HOST_ADDRESSES_SUFFIX ) ); - return String.format( HOST_ADDRESSES_FORMAT, host, hostAddresses, port ); + .limit(MAX_HOST_ADDRESSES_IN_STRING_VALUE) + .map(InetAddress::getHostAddress) + .collect(joining( + HOST_ADDRESS_DELIMITER, + HOST_ADDRESSES_PREFIX, + resolvedAddresses.size() > MAX_HOST_ADDRESSES_IN_STRING_VALUE + ? TRIMMED_HOST_ADDRESSES_SUFFIX + : HOST_ADDRESSES_SUFFIX)); + return String.format(HOST_ADDRESSES_FORMAT, host, hostAddresses, port); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/RevocationStrategy.java b/driver/src/main/java/org/neo4j/driver/internal/RevocationStrategy.java index 404985cdcb..d98204a853 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/RevocationStrategy.java +++ b/driver/src/main/java/org/neo4j/driver/internal/RevocationStrategy.java @@ -18,8 +18,7 @@ */ package org.neo4j.driver.internal; -public enum RevocationStrategy -{ +public enum RevocationStrategy { /** Don't do any OCSP revocation checks, regardless whether there are stapled revocation statuses or not. */ NO_CHECKS, /** Verify OCSP revocation checks when the revocation status is stapled to the certificate, continue if not. */ @@ -27,8 +26,7 @@ public enum RevocationStrategy /** Require stapled revocation status and verify OCSP revocation checks, fail if no revocation status is stapled to the certificate. */ STRICT; - public static boolean requiresRevocationChecking( RevocationStrategy revocationStrategy ) - { - return revocationStrategy.equals( STRICT ) || revocationStrategy.equals( VERIFY_IF_PRESENT ); + public static boolean requiresRevocationChecking(RevocationStrategy revocationStrategy) { + return revocationStrategy.equals(STRICT) || revocationStrategy.equals(VERIFY_IF_PRESENT); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/RoutingErrorHandler.java b/driver/src/main/java/org/neo4j/driver/internal/RoutingErrorHandler.java index a1d9c2515b..1af493c4fb 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/RoutingErrorHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/RoutingErrorHandler.java @@ -21,9 +21,8 @@ /** * Interface used for tracking errors when connected to a cluster. */ -public interface RoutingErrorHandler -{ - void onConnectionFailure( BoltServerAddress address ); +public interface RoutingErrorHandler { + void onConnectionFailure(BoltServerAddress address); - void onWriteFailure( BoltServerAddress address ); + void onWriteFailure(BoltServerAddress address); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/Scheme.java b/driver/src/main/java/org/neo4j/driver/internal/Scheme.java index ab278f03c4..d447a35d70 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/Scheme.java +++ b/driver/src/main/java/org/neo4j/driver/internal/Scheme.java @@ -18,8 +18,7 @@ */ package org.neo4j.driver.internal; -public class Scheme -{ +public class Scheme { public static final String BOLT_URI_SCHEME = "bolt"; public static final String BOLT_HIGH_TRUST_URI_SCHEME = "bolt+s"; public static final String BOLT_LOW_TRUST_URI_SCHEME = "bolt+ssc"; @@ -27,45 +26,41 @@ public class Scheme public static final String NEO4J_HIGH_TRUST_URI_SCHEME = "neo4j+s"; public static final String NEO4J_LOW_TRUST_URI_SCHEME = "neo4j+ssc"; - public static void validateScheme( String scheme ) - { - if ( scheme == null ) - { - throw new IllegalArgumentException( "Scheme must not be null" ); + public static void validateScheme(String scheme) { + if (scheme == null) { + throw new IllegalArgumentException("Scheme must not be null"); } - switch ( scheme ) - { - case BOLT_URI_SCHEME: - case BOLT_LOW_TRUST_URI_SCHEME: - case BOLT_HIGH_TRUST_URI_SCHEME: - case NEO4J_URI_SCHEME: - case NEO4J_LOW_TRUST_URI_SCHEME: - case NEO4J_HIGH_TRUST_URI_SCHEME: - return; - default: - throw new IllegalArgumentException( "Invalid address format " + scheme ); + switch (scheme) { + case BOLT_URI_SCHEME: + case BOLT_LOW_TRUST_URI_SCHEME: + case BOLT_HIGH_TRUST_URI_SCHEME: + case NEO4J_URI_SCHEME: + case NEO4J_LOW_TRUST_URI_SCHEME: + case NEO4J_HIGH_TRUST_URI_SCHEME: + return; + default: + throw new IllegalArgumentException("Invalid address format " + scheme); } } - public static boolean isHighTrustScheme( String scheme ) - { - return scheme.equals( BOLT_HIGH_TRUST_URI_SCHEME ) || scheme.equals( NEO4J_HIGH_TRUST_URI_SCHEME ); + public static boolean isHighTrustScheme(String scheme) { + return scheme.equals(BOLT_HIGH_TRUST_URI_SCHEME) || scheme.equals(NEO4J_HIGH_TRUST_URI_SCHEME); } - public static boolean isLowTrustScheme( String scheme ) - { - return scheme.equals( BOLT_LOW_TRUST_URI_SCHEME ) || scheme.equals( NEO4J_LOW_TRUST_URI_SCHEME ); + public static boolean isLowTrustScheme(String scheme) { + return scheme.equals(BOLT_LOW_TRUST_URI_SCHEME) || scheme.equals(NEO4J_LOW_TRUST_URI_SCHEME); } - public static boolean isSecurityScheme( String scheme ) - { - return scheme.equals( BOLT_LOW_TRUST_URI_SCHEME ) || scheme.equals( NEO4J_LOW_TRUST_URI_SCHEME ) - || scheme.equals( BOLT_HIGH_TRUST_URI_SCHEME ) || scheme.equals( NEO4J_HIGH_TRUST_URI_SCHEME ); + public static boolean isSecurityScheme(String scheme) { + return scheme.equals(BOLT_LOW_TRUST_URI_SCHEME) + || scheme.equals(NEO4J_LOW_TRUST_URI_SCHEME) + || scheme.equals(BOLT_HIGH_TRUST_URI_SCHEME) + || scheme.equals(NEO4J_HIGH_TRUST_URI_SCHEME); } - public static boolean isRoutingScheme( String scheme ) - { - return scheme.equals( NEO4J_LOW_TRUST_URI_SCHEME ) || scheme.equals( NEO4J_HIGH_TRUST_URI_SCHEME ) - || scheme.equals( NEO4J_URI_SCHEME ); + public static boolean isRoutingScheme(String scheme) { + return scheme.equals(NEO4J_LOW_TRUST_URI_SCHEME) + || scheme.equals(NEO4J_HIGH_TRUST_URI_SCHEME) + || scheme.equals(NEO4J_URI_SCHEME); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/SecuritySettings.java b/driver/src/main/java/org/neo4j/driver/internal/SecuritySettings.java index 5c61efc5a6..27e68d2ae0 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/SecuritySettings.java +++ b/driver/src/main/java/org/neo4j/driver/internal/SecuritySettings.java @@ -18,101 +18,83 @@ */ package org.neo4j.driver.internal; +import static org.neo4j.driver.internal.Scheme.isHighTrustScheme; +import static org.neo4j.driver.internal.Scheme.isSecurityScheme; +import static org.neo4j.driver.internal.security.SecurityPlanImpl.insecure; + import java.io.IOException; import java.io.Serializable; import java.security.GeneralSecurityException; - import org.neo4j.driver.Config; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.security.SecurityPlanImpl; -import static org.neo4j.driver.internal.Scheme.isHighTrustScheme; -import static org.neo4j.driver.internal.Scheme.isSecurityScheme; -import static org.neo4j.driver.internal.security.SecurityPlanImpl.insecure; - -public class SecuritySettings implements Serializable -{ +public class SecuritySettings implements Serializable { private static final long serialVersionUID = 4494615367164106576L; private static final boolean DEFAULT_ENCRYPTED = false; private static final Config.TrustStrategy DEFAULT_TRUST_STRATEGY = Config.TrustStrategy.trustSystemCertificates(); - private static final SecuritySettings DEFAULT = new SecuritySettings( DEFAULT_ENCRYPTED, DEFAULT_TRUST_STRATEGY ); + private static final SecuritySettings DEFAULT = new SecuritySettings(DEFAULT_ENCRYPTED, DEFAULT_TRUST_STRATEGY); private final boolean encrypted; private final Config.TrustStrategy trustStrategy; - public SecuritySettings( boolean encrypted, Config.TrustStrategy trustStrategy ) - { + public SecuritySettings(boolean encrypted, Config.TrustStrategy trustStrategy) { this.encrypted = encrypted; this.trustStrategy = trustStrategy == null ? DEFAULT_TRUST_STRATEGY : trustStrategy; } - public boolean encrypted() - { + public boolean encrypted() { return encrypted; } - public Config.TrustStrategy trustStrategy() - { + public Config.TrustStrategy trustStrategy() { return trustStrategy; } - private boolean isCustomized() - { - return !(DEFAULT.encrypted() == this.encrypted() && DEFAULT.hasEqualTrustStrategy( this )); + private boolean isCustomized() { + return !(DEFAULT.encrypted() == this.encrypted() && DEFAULT.hasEqualTrustStrategy(this)); } - private boolean hasEqualTrustStrategy( SecuritySettings other ) - { + private boolean hasEqualTrustStrategy(SecuritySettings other) { Config.TrustStrategy t1 = this.trustStrategy; Config.TrustStrategy t2 = other.trustStrategy; - if ( t1 == t2 ) - { + if (t1 == t2) { return true; } - return t1.isHostnameVerificationEnabled() == t2.isHostnameVerificationEnabled() && t1.strategy() == t2.strategy() && - t1.certFiles().equals( t2.certFiles() ) && t1.revocationStrategy() == t2.revocationStrategy(); + return t1.isHostnameVerificationEnabled() == t2.isHostnameVerificationEnabled() + && t1.strategy() == t2.strategy() + && t1.certFiles().equals(t2.certFiles()) + && t1.revocationStrategy() == t2.revocationStrategy(); } - public SecurityPlan createSecurityPlan( String uriScheme ) - { - Scheme.validateScheme( uriScheme ); - try - { - if ( isSecurityScheme( uriScheme ) ) - { - assertSecuritySettingsNotUserConfigured( uriScheme ); - return createSecurityPlanFromScheme( uriScheme ); - } - else - { - return createSecurityPlanImpl( encrypted, trustStrategy ); + public SecurityPlan createSecurityPlan(String uriScheme) { + Scheme.validateScheme(uriScheme); + try { + if (isSecurityScheme(uriScheme)) { + assertSecuritySettingsNotUserConfigured(uriScheme); + return createSecurityPlanFromScheme(uriScheme); + } else { + return createSecurityPlanImpl(encrypted, trustStrategy); } - } - catch ( GeneralSecurityException | IOException ex ) - { - throw new ClientException( "Unable to establish SSL parameters", ex ); + } catch (GeneralSecurityException | IOException ex) { + throw new ClientException("Unable to establish SSL parameters", ex); } } - private void assertSecuritySettingsNotUserConfigured( String uriScheme ) - { - if ( isCustomized() ) - { - throw new ClientException( String.format( "Scheme %s is not configurable with manual encryption and trust settings", uriScheme ) ); + private void assertSecuritySettingsNotUserConfigured(String uriScheme) { + if (isCustomized()) { + throw new ClientException(String.format( + "Scheme %s is not configurable with manual encryption and trust settings", uriScheme)); } } - private SecurityPlan createSecurityPlanFromScheme( String scheme ) throws GeneralSecurityException, IOException - { - if ( isHighTrustScheme(scheme) ) - { - return SecurityPlanImpl.forSystemCASignedCertificates( true, RevocationStrategy.NO_CHECKS ); - } - else - { - return SecurityPlanImpl.forAllCertificates( false, RevocationStrategy.NO_CHECKS ); + private SecurityPlan createSecurityPlanFromScheme(String scheme) throws GeneralSecurityException, IOException { + if (isHighTrustScheme(scheme)) { + return SecurityPlanImpl.forSystemCASignedCertificates(true, RevocationStrategy.NO_CHECKS); + } else { + return SecurityPlanImpl.forAllCertificates(false, RevocationStrategy.NO_CHECKS); } } @@ -120,62 +102,54 @@ private SecurityPlan createSecurityPlanFromScheme( String scheme ) throws Genera * Establish a complete SecurityPlan based on the details provided for * driver construction. */ - private static SecurityPlan createSecurityPlanImpl( boolean encrypted, Config.TrustStrategy trustStrategy ) - throws GeneralSecurityException, IOException - { - if ( encrypted ) - { + private static SecurityPlan createSecurityPlanImpl(boolean encrypted, Config.TrustStrategy trustStrategy) + throws GeneralSecurityException, IOException { + if (encrypted) { boolean hostnameVerificationEnabled = trustStrategy.isHostnameVerificationEnabled(); RevocationStrategy revocationStrategy = trustStrategy.revocationStrategy(); - switch ( trustStrategy.strategy() ) - { - case TRUST_CUSTOM_CA_SIGNED_CERTIFICATES: - return SecurityPlanImpl.forCustomCASignedCertificates( trustStrategy.certFiles(), hostnameVerificationEnabled, revocationStrategy ); - case TRUST_SYSTEM_CA_SIGNED_CERTIFICATES: - return SecurityPlanImpl.forSystemCASignedCertificates( hostnameVerificationEnabled, revocationStrategy ); - case TRUST_ALL_CERTIFICATES: - return SecurityPlanImpl.forAllCertificates( hostnameVerificationEnabled, revocationStrategy ); - default: - throw new ClientException( - "Unknown TLS authentication strategy: " + trustStrategy.strategy().name() ); + switch (trustStrategy.strategy()) { + case TRUST_CUSTOM_CA_SIGNED_CERTIFICATES: + return SecurityPlanImpl.forCustomCASignedCertificates( + trustStrategy.certFiles(), hostnameVerificationEnabled, revocationStrategy); + case TRUST_SYSTEM_CA_SIGNED_CERTIFICATES: + return SecurityPlanImpl.forSystemCASignedCertificates( + hostnameVerificationEnabled, revocationStrategy); + case TRUST_ALL_CERTIFICATES: + return SecurityPlanImpl.forAllCertificates(hostnameVerificationEnabled, revocationStrategy); + default: + throw new ClientException("Unknown TLS authentication strategy: " + + trustStrategy.strategy().name()); } - } - else - { + } else { return insecure(); } } - public static class SecuritySettingsBuilder - { + public static class SecuritySettingsBuilder { private boolean isCustomized = false; private boolean encrypted; private Config.TrustStrategy trustStrategy; - public SecuritySettingsBuilder withEncryption() - { + public SecuritySettingsBuilder withEncryption() { encrypted = true; isCustomized = true; return this; } - public SecuritySettingsBuilder withoutEncryption() - { + public SecuritySettingsBuilder withoutEncryption() { encrypted = false; isCustomized = true; return this; } - public SecuritySettingsBuilder withTrustStrategy( Config.TrustStrategy strategy ) - { + public SecuritySettingsBuilder withTrustStrategy(Config.TrustStrategy strategy) { trustStrategy = strategy; isCustomized = true; return this; } - public SecuritySettings build() - { - return isCustomized ? new SecuritySettings( encrypted, trustStrategy ) : SecuritySettings.DEFAULT; + public SecuritySettings build() { + return isCustomized ? new SecuritySettings(encrypted, trustStrategy) : SecuritySettings.DEFAULT; } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/SessionFactory.java b/driver/src/main/java/org/neo4j/driver/internal/SessionFactory.java index aa9f730b5c..f2407f0f1a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/SessionFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/SessionFactory.java @@ -19,13 +19,11 @@ package org.neo4j.driver.internal; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.SessionConfig; import org.neo4j.driver.internal.async.NetworkSession; -public interface SessionFactory -{ - NetworkSession newInstance( SessionConfig sessionConfig ); +public interface SessionFactory { + NetworkSession newInstance(SessionConfig sessionConfig); CompletionStage verifyConnectivity(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java index 8a9e85634e..8ec8d03753 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java @@ -20,7 +20,6 @@ import java.util.Optional; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Config; import org.neo4j.driver.Logging; @@ -30,16 +29,14 @@ import org.neo4j.driver.internal.retry.RetryLogic; import org.neo4j.driver.internal.spi.ConnectionProvider; -public class SessionFactoryImpl implements SessionFactory -{ +public class SessionFactoryImpl implements SessionFactory { private final ConnectionProvider connectionProvider; private final RetryLogic retryLogic; private final Logging logging; private final boolean leakedSessionsLoggingEnabled; private final long defaultFetchSize; - SessionFactoryImpl( ConnectionProvider connectionProvider, RetryLogic retryLogic, Config config ) - { + SessionFactoryImpl(ConnectionProvider connectionProvider, RetryLogic retryLogic, Config config) { this.connectionProvider = connectionProvider; this.leakedSessionsLoggingEnabled = config.logLeakedSessions(); this.retryLogic = retryLogic; @@ -48,41 +45,42 @@ public class SessionFactoryImpl implements SessionFactory } @Override - public NetworkSession newInstance( SessionConfig sessionConfig ) - { - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( InternalBookmark.from( sessionConfig.bookmarks() ) ); - return createSession( connectionProvider, retryLogic, parseDatabaseName( sessionConfig ), - sessionConfig.defaultAccessMode(), bookmarkHolder, parseFetchSize( sessionConfig ), - sessionConfig.impersonatedUser().orElse( null ), logging ); + public NetworkSession newInstance(SessionConfig sessionConfig) { + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(InternalBookmark.from(sessionConfig.bookmarks())); + return createSession( + connectionProvider, + retryLogic, + parseDatabaseName(sessionConfig), + sessionConfig.defaultAccessMode(), + bookmarkHolder, + parseFetchSize(sessionConfig), + sessionConfig.impersonatedUser().orElse(null), + logging); } - private long parseFetchSize( SessionConfig sessionConfig ) - { - return sessionConfig.fetchSize().orElse( defaultFetchSize ); + private long parseFetchSize(SessionConfig sessionConfig) { + return sessionConfig.fetchSize().orElse(defaultFetchSize); } - private DatabaseName parseDatabaseName( SessionConfig sessionConfig ) - { - return sessionConfig.database() - .flatMap( name -> Optional.of( DatabaseNameUtil.database( name ) ) ) - .orElse( DatabaseNameUtil.defaultDatabase() ); + private DatabaseName parseDatabaseName(SessionConfig sessionConfig) { + return sessionConfig + .database() + .flatMap(name -> Optional.of(DatabaseNameUtil.database(name))) + .orElse(DatabaseNameUtil.defaultDatabase()); } @Override - public CompletionStage verifyConnectivity() - { + public CompletionStage verifyConnectivity() { return connectionProvider.verifyConnectivity(); } @Override - public CompletionStage close() - { + public CompletionStage close() { return connectionProvider.close(); } @Override - public CompletionStage supportsMultiDb() - { + public CompletionStage supportsMultiDb() { return connectionProvider.supportsMultiDb(); } @@ -93,16 +91,37 @@ public CompletionStage supportsMultiDb() * * @return the connection provider used by this factory. */ - public ConnectionProvider getConnectionProvider() - { + public ConnectionProvider getConnectionProvider() { return connectionProvider; } - private NetworkSession createSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode, - BookmarkHolder bookmarkHolder, long fetchSize, String impersonatedUser, Logging logging ) - { + private NetworkSession createSession( + ConnectionProvider connectionProvider, + RetryLogic retryLogic, + DatabaseName databaseName, + AccessMode mode, + BookmarkHolder bookmarkHolder, + long fetchSize, + String impersonatedUser, + Logging logging) { return leakedSessionsLoggingEnabled - ? new LeakLoggingNetworkSession( connectionProvider, retryLogic, databaseName, mode, bookmarkHolder, impersonatedUser, fetchSize, logging ) - : new NetworkSession( connectionProvider, retryLogic, databaseName, mode, bookmarkHolder, impersonatedUser, fetchSize, logging ); + ? new LeakLoggingNetworkSession( + connectionProvider, + retryLogic, + databaseName, + mode, + bookmarkHolder, + impersonatedUser, + fetchSize, + logging) + : new NetworkSession( + connectionProvider, + retryLogic, + databaseName, + mode, + bookmarkHolder, + impersonatedUser, + fetchSize, + logging); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/AsyncAbstractQueryRunner.java b/driver/src/main/java/org/neo4j/driver/internal/async/AsyncAbstractQueryRunner.java index c107b850d7..7a487698b6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/AsyncAbstractQueryRunner.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/AsyncAbstractQueryRunner.java @@ -18,41 +18,35 @@ */ package org.neo4j.driver.internal.async; +import static org.neo4j.driver.internal.AbstractQueryRunner.parameters; + import java.util.Map; import java.util.concurrent.CompletionStage; - -import org.neo4j.driver.Record; import org.neo4j.driver.Query; +import org.neo4j.driver.Record; import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.async.AsyncQueryRunner; import org.neo4j.driver.async.ResultCursor; -import static org.neo4j.driver.internal.AbstractQueryRunner.parameters; - -public abstract class AsyncAbstractQueryRunner implements AsyncQueryRunner -{ +public abstract class AsyncAbstractQueryRunner implements AsyncQueryRunner { @Override - public final CompletionStage runAsync(String query, Value parameters ) - { - return runAsync( new Query(query, parameters ) ); + public final CompletionStage runAsync(String query, Value parameters) { + return runAsync(new Query(query, parameters)); } @Override - public final CompletionStage runAsync(String query, Map parameters) - { - return runAsync(query, parameters(parameters) ); + public final CompletionStage runAsync(String query, Map parameters) { + return runAsync(query, parameters(parameters)); } @Override - public final CompletionStage runAsync(String query, Record parameters) - { - return runAsync(query, parameters(parameters) ); + public final CompletionStage runAsync(String query, Record parameters) { + return runAsync(query, parameters(parameters)); } @Override - public final CompletionStage runAsync(String query) - { - return runAsync(query, Values.EmptyMap ); + public final CompletionStage runAsync(String query) { + return runAsync(query, Values.EmptyMap); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ConnectionContext.java b/driver/src/main/java/org/neo4j/driver/internal/async/ConnectionContext.java index 31efe28b90..30b3a68451 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ConnectionContext.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/ConnectionContext.java @@ -20,7 +20,6 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.internal.DatabaseName; @@ -29,9 +28,9 @@ /** * Describes what kind of connection to return by {@link ConnectionProvider} */ -public interface ConnectionContext -{ - Supplier PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER = () -> new IllegalStateException( "Pending database name encountered." ); +public interface ConnectionContext { + Supplier PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER = + () -> new IllegalStateException("Pending database name encountered."); CompletableFuture databaseNameFuture(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ImmutableConnectionContext.java b/driver/src/main/java/org/neo4j/driver/internal/async/ImmutableConnectionContext.java index ccaa86c389..fdcd94bcce 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ImmutableConnectionContext.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/ImmutableConnectionContext.java @@ -18,57 +18,52 @@ */ package org.neo4j.driver.internal.async; -import java.util.concurrent.CompletableFuture; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.DatabaseNameUtil.systemDatabase; +import static org.neo4j.driver.internal.InternalBookmark.empty; +import java.util.concurrent.CompletableFuture; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.internal.DatabaseName; import org.neo4j.driver.internal.spi.Connection; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.DatabaseNameUtil.systemDatabase; -import static org.neo4j.driver.internal.InternalBookmark.empty; - /** * A {@link Connection} shall fulfil this {@link ImmutableConnectionContext} when acquired from a connection provider. */ -public class ImmutableConnectionContext implements ConnectionContext -{ - private static final ConnectionContext SINGLE_DB_CONTEXT = new ImmutableConnectionContext( defaultDatabase(), empty(), AccessMode.READ ); - private static final ConnectionContext MULTI_DB_CONTEXT = new ImmutableConnectionContext( systemDatabase(), empty(), AccessMode.READ ); +public class ImmutableConnectionContext implements ConnectionContext { + private static final ConnectionContext SINGLE_DB_CONTEXT = + new ImmutableConnectionContext(defaultDatabase(), empty(), AccessMode.READ); + private static final ConnectionContext MULTI_DB_CONTEXT = + new ImmutableConnectionContext(systemDatabase(), empty(), AccessMode.READ); private final CompletableFuture databaseNameFuture; private final AccessMode mode; private final Bookmark rediscoveryBookmark; - public ImmutableConnectionContext( DatabaseName databaseName, Bookmark bookmark, AccessMode mode ) - { - this.databaseNameFuture = CompletableFuture.completedFuture( databaseName ); + public ImmutableConnectionContext(DatabaseName databaseName, Bookmark bookmark, AccessMode mode) { + this.databaseNameFuture = CompletableFuture.completedFuture(databaseName); this.rediscoveryBookmark = bookmark; this.mode = mode; } @Override - public CompletableFuture databaseNameFuture() - { + public CompletableFuture databaseNameFuture() { return databaseNameFuture; } @Override - public AccessMode mode() - { + public AccessMode mode() { return mode; } @Override - public Bookmark rediscoveryBookmark() - { + public Bookmark rediscoveryBookmark() { return rediscoveryBookmark; } @Override - public String impersonatedUser() - { + public String impersonatedUser() { return null; } @@ -76,8 +71,7 @@ public String impersonatedUser() * A simple context is used to test connectivity with a remote server/cluster. As long as there is a read only service, the connection shall be established * successfully. Depending on whether multidb is supported or not, this method returns different context for routing table discovery. */ - public static ConnectionContext simple( boolean supportsMultiDb ) - { + public static ConnectionContext simple(boolean supportsMultiDb) { return supportsMultiDb ? MULTI_DB_CONTEXT : SINGLE_DB_CONTEXT; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncSession.java b/driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncSession.java index efc291933b..c8846c25c5 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncSession.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncSession.java @@ -18,10 +18,13 @@ */ package org.neo4j.driver.internal.async; +import static java.util.Collections.emptyMap; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; + import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -32,175 +35,143 @@ import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.internal.util.Futures; -import static java.util.Collections.emptyMap; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; - -public class InternalAsyncSession extends AsyncAbstractQueryRunner implements AsyncSession -{ +public class InternalAsyncSession extends AsyncAbstractQueryRunner implements AsyncSession { private final NetworkSession session; - public InternalAsyncSession( NetworkSession session ) - { + public InternalAsyncSession(NetworkSession session) { this.session = session; } @Override - public CompletionStage runAsync(Query query) - { - return runAsync(query, TransactionConfig.empty() ); + public CompletionStage runAsync(Query query) { + return runAsync(query, TransactionConfig.empty()); } @Override - public CompletionStage runAsync(String query, TransactionConfig config ) - { - return runAsync(query, emptyMap(), config ); + public CompletionStage runAsync(String query, TransactionConfig config) { + return runAsync(query, emptyMap(), config); } @Override - public CompletionStage runAsync(String query, Map parameters, TransactionConfig config ) - { - return runAsync( new Query(query, parameters ), config ); + public CompletionStage runAsync( + String query, Map parameters, TransactionConfig config) { + return runAsync(new Query(query, parameters), config); } @Override - public CompletionStage runAsync(Query query, TransactionConfig config ) - { - return session.runAsync( query, config ); + public CompletionStage runAsync(Query query, TransactionConfig config) { + return session.runAsync(query, config); } @Override - public CompletionStage closeAsync() - { + public CompletionStage closeAsync() { return session.closeAsync(); } @Override - public CompletionStage beginTransactionAsync() - { - return beginTransactionAsync( TransactionConfig.empty() ); + public CompletionStage beginTransactionAsync() { + return beginTransactionAsync(TransactionConfig.empty()); } @Override - public CompletionStage beginTransactionAsync( TransactionConfig config ) - { - return session.beginTransactionAsync( config ).thenApply( InternalAsyncTransaction::new ); + public CompletionStage beginTransactionAsync(TransactionConfig config) { + return session.beginTransactionAsync(config).thenApply(InternalAsyncTransaction::new); } @Override - public CompletionStage readTransactionAsync( AsyncTransactionWork> work ) - { - return readTransactionAsync( work, TransactionConfig.empty() ); + public CompletionStage readTransactionAsync(AsyncTransactionWork> work) { + return readTransactionAsync(work, TransactionConfig.empty()); } @Override - public CompletionStage readTransactionAsync( AsyncTransactionWork> work, TransactionConfig config ) - { - return transactionAsync( AccessMode.READ, work, config ); + public CompletionStage readTransactionAsync( + AsyncTransactionWork> work, TransactionConfig config) { + return transactionAsync(AccessMode.READ, work, config); } @Override - public CompletionStage writeTransactionAsync( AsyncTransactionWork> work ) - { - return writeTransactionAsync( work, TransactionConfig.empty() ); + public CompletionStage writeTransactionAsync(AsyncTransactionWork> work) { + return writeTransactionAsync(work, TransactionConfig.empty()); } @Override - public CompletionStage writeTransactionAsync( AsyncTransactionWork> work, TransactionConfig config ) - { - return transactionAsync( AccessMode.WRITE, work, config ); + public CompletionStage writeTransactionAsync( + AsyncTransactionWork> work, TransactionConfig config) { + return transactionAsync(AccessMode.WRITE, work, config); } @Override - public Bookmark lastBookmark() - { + public Bookmark lastBookmark() { return session.lastBookmark(); } - private CompletionStage transactionAsync( AccessMode mode, AsyncTransactionWork> work, TransactionConfig config ) - { - return session.retryLogic().retryAsync( () -> { + private CompletionStage transactionAsync( + AccessMode mode, AsyncTransactionWork> work, TransactionConfig config) { + return session.retryLogic().retryAsync(() -> { CompletableFuture resultFuture = new CompletableFuture<>(); - CompletionStage txFuture = session.beginTransactionAsync( mode, config ); - - txFuture.whenComplete( ( tx, completionError ) -> { - Throwable error = Futures.completionExceptionCause( completionError ); - if ( error != null ) - { - resultFuture.completeExceptionally( error ); - } - else - { - executeWork( resultFuture, tx, work ); + CompletionStage txFuture = session.beginTransactionAsync(mode, config); + + txFuture.whenComplete((tx, completionError) -> { + Throwable error = Futures.completionExceptionCause(completionError); + if (error != null) { + resultFuture.completeExceptionally(error); + } else { + executeWork(resultFuture, tx, work); } - } ); + }); return resultFuture; - } ); - } - - private void executeWork(CompletableFuture resultFuture, UnmanagedTransaction tx, AsyncTransactionWork> work ) - { - CompletionStage workFuture = safeExecuteWork( tx, work ); - workFuture.whenComplete( ( result, completionError ) -> { - Throwable error = Futures.completionExceptionCause( completionError ); - if ( error != null ) - { - closeTxAfterFailedTransactionWork( tx, resultFuture, error ); + }); + } + + private void executeWork( + CompletableFuture resultFuture, UnmanagedTransaction tx, AsyncTransactionWork> work) { + CompletionStage workFuture = safeExecuteWork(tx, work); + workFuture.whenComplete((result, completionError) -> { + Throwable error = Futures.completionExceptionCause(completionError); + if (error != null) { + closeTxAfterFailedTransactionWork(tx, resultFuture, error); + } else { + closeTxAfterSucceededTransactionWork(tx, resultFuture, result); } - else - { - closeTxAfterSucceededTransactionWork( tx, resultFuture, result ); - } - } ); + }); } - private CompletionStage safeExecuteWork(UnmanagedTransaction tx, AsyncTransactionWork> work ) - { + private CompletionStage safeExecuteWork( + UnmanagedTransaction tx, AsyncTransactionWork> work) { // given work might fail in both async and sync way // async failure will result in a failed future being returned // sync failure will result in an exception being thrown - try - { - CompletionStage result = work.execute( new InternalAsyncTransaction( tx ) ); + try { + CompletionStage result = work.execute(new InternalAsyncTransaction(tx)); // protect from given transaction function returning null return result == null ? completedWithNull() : result; - } - catch ( Throwable workError ) - { + } catch (Throwable workError) { // work threw an exception, wrap it in a future and proceed - return failedFuture( workError ); + return failedFuture(workError); } } - private void closeTxAfterFailedTransactionWork( UnmanagedTransaction tx, CompletableFuture resultFuture, Throwable error ) - { - tx.closeAsync().whenComplete( - ( ignored, rollbackError ) -> - { - if ( rollbackError != null ) - { - error.addSuppressed( rollbackError ); - } - resultFuture.completeExceptionally( error ); - } ); - } - - private void closeTxAfterSucceededTransactionWork(UnmanagedTransaction tx, CompletableFuture resultFuture, T result ) - { - tx.closeAsync( true ).whenComplete( - ( ignored, completionError ) -> - { - Throwable commitError = Futures.completionExceptionCause( completionError ); - if ( commitError != null ) - { - resultFuture.completeExceptionally( commitError ); - } - else - { - resultFuture.complete( result ); - } - } ); + private void closeTxAfterFailedTransactionWork( + UnmanagedTransaction tx, CompletableFuture resultFuture, Throwable error) { + tx.closeAsync().whenComplete((ignored, rollbackError) -> { + if (rollbackError != null) { + error.addSuppressed(rollbackError); + } + resultFuture.completeExceptionally(error); + }); + } + + private void closeTxAfterSucceededTransactionWork( + UnmanagedTransaction tx, CompletableFuture resultFuture, T result) { + tx.closeAsync(true).whenComplete((ignored, completionError) -> { + Throwable commitError = Futures.completionExceptionCause(completionError); + if (commitError != null) { + resultFuture.completeExceptionally(commitError); + } else { + resultFuture.complete(result); + } + }); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncTransaction.java b/driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncTransaction.java index 5e7123b4db..a8515470ba 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncTransaction.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncTransaction.java @@ -19,45 +19,38 @@ package org.neo4j.driver.internal.async; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Query; import org.neo4j.driver.async.AsyncTransaction; import org.neo4j.driver.async.ResultCursor; -public class InternalAsyncTransaction extends AsyncAbstractQueryRunner implements AsyncTransaction -{ +public class InternalAsyncTransaction extends AsyncAbstractQueryRunner implements AsyncTransaction { private final UnmanagedTransaction tx; - public InternalAsyncTransaction( UnmanagedTransaction tx ) - { + + public InternalAsyncTransaction(UnmanagedTransaction tx) { this.tx = tx; } @Override - public CompletionStage commitAsync() - { + public CompletionStage commitAsync() { return tx.commitAsync(); } @Override - public CompletionStage rollbackAsync() - { + public CompletionStage rollbackAsync() { return tx.rollbackAsync(); } @Override - public CompletionStage closeAsync() - { + public CompletionStage closeAsync() { return tx.closeAsync(); } @Override - public CompletionStage runAsync( Query query ) - { - return tx.runAsync( query ); + public CompletionStage runAsync(Query query) { + return tx.runAsync(query); } - public boolean isOpen() - { + public boolean isOpen() { return tx.isOpen(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java b/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java index 952c17e243..fb5046455e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java @@ -18,6 +18,8 @@ */ package org.neo4j.driver.internal.async; +import static java.lang.System.lineSeparator; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BookmarkHolder; @@ -26,43 +28,45 @@ import org.neo4j.driver.internal.spi.ConnectionProvider; import org.neo4j.driver.internal.util.Futures; -import static java.lang.System.lineSeparator; - -public class LeakLoggingNetworkSession extends NetworkSession -{ +public class LeakLoggingNetworkSession extends NetworkSession { private final String stackTrace; - public LeakLoggingNetworkSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode, - BookmarkHolder bookmarkHolder, String impersonatedUser, long fetchSize, Logging logging ) - { - super( connectionProvider, retryLogic, databaseName, mode, bookmarkHolder, impersonatedUser, fetchSize, logging ); + public LeakLoggingNetworkSession( + ConnectionProvider connectionProvider, + RetryLogic retryLogic, + DatabaseName databaseName, + AccessMode mode, + BookmarkHolder bookmarkHolder, + String impersonatedUser, + long fetchSize, + Logging logging) { + super(connectionProvider, retryLogic, databaseName, mode, bookmarkHolder, impersonatedUser, fetchSize, logging); this.stackTrace = captureStackTrace(); } @Override - protected void finalize() throws Throwable - { + protected void finalize() throws Throwable { logLeakIfNeeded(); super.finalize(); } - private void logLeakIfNeeded() - { - Boolean isOpen = Futures.blockingGet( currentConnectionIsOpen() ); - if ( isOpen ) - { - log.error( "Neo4j Session object leaked, please ensure that your application " + - "fully consumes results in Sessions or explicitly calls `close` on Sessions before disposing of the objects.\n" + - "Session was create at:\n" + stackTrace, null ); + private void logLeakIfNeeded() { + Boolean isOpen = Futures.blockingGet(currentConnectionIsOpen()); + if (isOpen) { + log.error( + "Neo4j Session object leaked, please ensure that your application " + + "fully consumes results in Sessions or explicitly calls `close` on Sessions before disposing of the objects.\n" + + "Session was create at:\n" + + stackTrace, + null); } } - private static String captureStackTrace() - { + + private static String captureStackTrace() { StringBuilder result = new StringBuilder(); StackTraceElement[] elements = Thread.currentThread().getStackTrace(); - for ( StackTraceElement element : elements ) - { - result.append( "\t" ).append( element ).append( lineSeparator() ); + for (StackTraceElement element : elements) { + result.append("\t").append(element).append(lineSeparator()); } return result.toString(); } 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 c9e607f85b..b1817af077 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 @@ -18,14 +18,17 @@ */ package org.neo4j.driver.internal.async; +import static java.util.Collections.emptyMap; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.poolId; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setTerminationReason; +import static org.neo4j.driver.internal.util.Futures.asCompletionStage; + import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; - import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BoltServerAddress; @@ -45,17 +48,11 @@ import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.ServerVersion; -import static java.util.Collections.emptyMap; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.poolId; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setTerminationReason; -import static org.neo4j.driver.internal.util.Futures.asCompletionStage; - /** * 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 * connection start from the moment the channel is borrowed out of the pool and end at the time the connection is released back to the pool. */ -public class NetworkConnection implements Connection -{ +public class NetworkConnection implements Connection { private final Logger log; private final Channel channel; private final InboundMessageDispatcher messageDispatcher; @@ -67,294 +64,246 @@ public class NetworkConnection implements Connection private final CompletableFuture releaseFuture; private final Clock clock; - private final AtomicReference status = new AtomicReference<>( Status.OPEN ); + private final AtomicReference status = new AtomicReference<>(Status.OPEN); private final MetricsListener metricsListener; private final ListenerEvent inUseEvent; private final Long connectionReadTimeout; private ChannelHandler connectionReadTimeoutHandler; - public NetworkConnection( Channel channel, ExtendedChannelPool channelPool, Clock clock, MetricsListener metricsListener, Logging logging ) - { - this.log = logging.getLog( getClass() ); + public NetworkConnection( + Channel channel, + ExtendedChannelPool channelPool, + Clock clock, + MetricsListener metricsListener, + Logging logging) { + this.log = logging.getLog(getClass()); this.channel = channel; - this.messageDispatcher = ChannelAttributes.messageDispatcher( channel ); - this.serverAgent = ChannelAttributes.serverAgent( channel ); - this.serverAddress = ChannelAttributes.serverAddress( channel ); - this.serverVersion = ChannelAttributes.serverVersion( channel ); - this.protocol = BoltProtocol.forChannel( channel ); + this.messageDispatcher = ChannelAttributes.messageDispatcher(channel); + this.serverAgent = ChannelAttributes.serverAgent(channel); + this.serverAddress = ChannelAttributes.serverAddress(channel); + this.serverVersion = ChannelAttributes.serverVersion(channel); + this.protocol = BoltProtocol.forChannel(channel); this.channelPool = channelPool; this.releaseFuture = new CompletableFuture<>(); this.clock = clock; this.metricsListener = metricsListener; this.inUseEvent = metricsListener.createListenerEvent(); - this.connectionReadTimeout = ChannelAttributes.connectionReadTimeout( channel ).orElse( null ); - metricsListener.afterConnectionCreated( poolId( this.channel ), this.inUseEvent ); + this.connectionReadTimeout = + ChannelAttributes.connectionReadTimeout(channel).orElse(null); + metricsListener.afterConnectionCreated(poolId(this.channel), this.inUseEvent); } @Override - public boolean isOpen() - { + public boolean isOpen() { return status.get() == Status.OPEN; } @Override - public void enableAutoRead() - { - if ( isOpen() ) - { - setAutoRead( true ); + public void enableAutoRead() { + if (isOpen()) { + setAutoRead(true); } } @Override - public void disableAutoRead() - { - if ( isOpen() ) - { - setAutoRead( false ); + public void disableAutoRead() { + if (isOpen()) { + setAutoRead(false); } } @Override - public void flush() - { - if ( verifyOpen( null, null ) ) - { + public void flush() { + if (verifyOpen(null, null)) { flushInEventLoop(); } } @Override - public void write( Message message, ResponseHandler handler ) - { - if ( verifyOpen( handler, null ) ) - { - writeMessageInEventLoop( message, handler, false ); + public void write(Message message, ResponseHandler handler) { + if (verifyOpen(handler, null)) { + writeMessageInEventLoop(message, handler, false); } } @Override - public void write( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ) - { - if ( verifyOpen( handler1, handler2 ) ) - { - writeMessagesInEventLoop( message1, handler1, message2, handler2, false ); + public void write(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2) { + if (verifyOpen(handler1, handler2)) { + writeMessagesInEventLoop(message1, handler1, message2, handler2, false); } } @Override - public void writeAndFlush( Message message, ResponseHandler handler ) - { - if ( verifyOpen( handler, null ) ) - { - writeMessageInEventLoop( message, handler, true ); + public void writeAndFlush(Message message, ResponseHandler handler) { + if (verifyOpen(handler, null)) { + writeMessageInEventLoop(message, handler, true); } } @Override - public void writeAndFlush( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ) - { - if ( verifyOpen( handler1, handler2 ) ) - { - writeMessagesInEventLoop( message1, handler1, message2, handler2, true ); + public void writeAndFlush(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2) { + if (verifyOpen(handler1, handler2)) { + writeMessagesInEventLoop(message1, handler1, message2, handler2, true); } } @Override - public CompletionStage reset() - { + public CompletionStage reset() { CompletableFuture result = new CompletableFuture<>(); - ResetResponseHandler handler = new ResetResponseHandler( messageDispatcher, result ); - writeResetMessageIfNeeded( handler, true ); + ResetResponseHandler handler = new ResetResponseHandler(messageDispatcher, result); + writeResetMessageIfNeeded(handler, true); return result; } @Override - public CompletionStage release() - { - if ( status.compareAndSet( Status.OPEN, Status.RELEASED ) ) - { - ChannelReleasingResetResponseHandler handler = new ChannelReleasingResetResponseHandler( channel, - channelPool, messageDispatcher, clock, releaseFuture ); - - writeResetMessageIfNeeded( handler, false ); - metricsListener.afterConnectionReleased( poolId( this.channel ), this.inUseEvent ); + public CompletionStage release() { + if (status.compareAndSet(Status.OPEN, Status.RELEASED)) { + ChannelReleasingResetResponseHandler handler = new ChannelReleasingResetResponseHandler( + channel, channelPool, messageDispatcher, clock, releaseFuture); + + writeResetMessageIfNeeded(handler, false); + metricsListener.afterConnectionReleased(poolId(this.channel), this.inUseEvent); } return releaseFuture; } @Override - public void terminateAndRelease( String reason ) - { - if ( status.compareAndSet( Status.OPEN, Status.TERMINATED ) ) - { - setTerminationReason( channel, reason ); - asCompletionStage( channel.close() ) - .exceptionally( throwable -> null ) - .thenCompose( ignored -> channelPool.release( channel ) ) - .whenComplete( ( ignored, throwable ) -> - { - releaseFuture.complete( null ); - metricsListener.afterConnectionReleased( poolId( this.channel ), this.inUseEvent ); - } ); + public void terminateAndRelease(String reason) { + if (status.compareAndSet(Status.OPEN, Status.TERMINATED)) { + setTerminationReason(channel, reason); + asCompletionStage(channel.close()) + .exceptionally(throwable -> null) + .thenCompose(ignored -> channelPool.release(channel)) + .whenComplete((ignored, throwable) -> { + releaseFuture.complete(null); + metricsListener.afterConnectionReleased(poolId(this.channel), this.inUseEvent); + }); } } @Override - public String serverAgent() - { + public String serverAgent() { return serverAgent; } @Override - public BoltServerAddress serverAddress() - { + public BoltServerAddress serverAddress() { return serverAddress; } @Override - public ServerVersion serverVersion() - { + public ServerVersion serverVersion() { return serverVersion; } @Override - public BoltProtocol protocol() - { + public BoltProtocol protocol() { return protocol; } - private void writeResetMessageIfNeeded( ResponseHandler resetHandler, boolean isSessionReset ) - { - channel.eventLoop().execute( () -> - { - if ( isSessionReset && !isOpen() ) - { - resetHandler.onSuccess( emptyMap() ); - } - else - { + private void writeResetMessageIfNeeded(ResponseHandler resetHandler, boolean isSessionReset) { + channel.eventLoop().execute(() -> { + if (isSessionReset && !isOpen()) { + resetHandler.onSuccess(emptyMap()); + } else { // auto-read could've been disabled, re-enable it to automatically receive response for RESET - setAutoRead( true ); + setAutoRead(true); - messageDispatcher.enqueue( resetHandler ); - channel.writeAndFlush( ResetMessage.RESET ).addListener( future -> registerConnectionReadTimeout( channel ) ); + messageDispatcher.enqueue(resetHandler); + channel.writeAndFlush(ResetMessage.RESET).addListener(future -> registerConnectionReadTimeout(channel)); } - } ); + }); } - private void flushInEventLoop() - { - channel.eventLoop().execute( - () -> - { - channel.flush(); - registerConnectionReadTimeout( channel ); - } ); + private void flushInEventLoop() { + channel.eventLoop().execute(() -> { + channel.flush(); + registerConnectionReadTimeout(channel); + }); } - private void writeMessageInEventLoop( Message message, ResponseHandler handler, boolean flush ) - { - channel.eventLoop().execute( () -> - { - messageDispatcher.enqueue( handler ); + private void writeMessageInEventLoop(Message message, ResponseHandler handler, boolean flush) { + channel.eventLoop().execute(() -> { + messageDispatcher.enqueue(handler); - if ( flush ) - { - channel.writeAndFlush( message ).addListener( future -> registerConnectionReadTimeout( channel ) ); - } - else - { - channel.write( message, channel.voidPromise() ); + if (flush) { + channel.writeAndFlush(message).addListener(future -> registerConnectionReadTimeout(channel)); + } else { + channel.write(message, channel.voidPromise()); } - } ); + }); } - private void writeMessagesInEventLoop( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2, boolean flush ) - { - channel.eventLoop().execute( () -> - { - messageDispatcher.enqueue( handler1 ); - messageDispatcher.enqueue( handler2 ); + private void writeMessagesInEventLoop( + Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2, boolean flush) { + channel.eventLoop().execute(() -> { + messageDispatcher.enqueue(handler1); + messageDispatcher.enqueue(handler2); - channel.write( message1, channel.voidPromise() ); + channel.write(message1, channel.voidPromise()); - if ( flush ) - { - channel.writeAndFlush( message2 ).addListener( future -> registerConnectionReadTimeout( channel ) ); + if (flush) { + channel.writeAndFlush(message2).addListener(future -> registerConnectionReadTimeout(channel)); + } else { + channel.write(message2, channel.voidPromise()); } - else - { - channel.write( message2, channel.voidPromise() ); - } - } ); + }); } - private void setAutoRead( boolean value ) - { - channel.config().setAutoRead( value ); + private void setAutoRead(boolean value) { + channel.config().setAutoRead(value); } - private boolean verifyOpen( ResponseHandler handler1, ResponseHandler handler2 ) - { + private boolean verifyOpen(ResponseHandler handler1, ResponseHandler handler2) { Status connectionStatus = this.status.get(); - switch ( connectionStatus ) - { - case OPEN: - return true; - case RELEASED: - Exception error = new IllegalStateException( "Connection has been released to the pool and can't be used" ); - if ( handler1 != null ) - { - handler1.onFailure( error ); - } - if ( handler2 != null ) - { - handler2.onFailure( error ); - } - return false; - case TERMINATED: - Exception terminatedError = new IllegalStateException( "Connection has been terminated and can't be used" ); - if ( handler1 != null ) - { - handler1.onFailure( terminatedError ); - } - if ( handler2 != null ) - { - handler2.onFailure( terminatedError ); - } - return false; - default: - throw new IllegalStateException( "Unknown status: " + connectionStatus ); + switch (connectionStatus) { + case OPEN: + return true; + case RELEASED: + Exception error = + new IllegalStateException("Connection has been released to the pool and can't be used"); + if (handler1 != null) { + handler1.onFailure(error); + } + if (handler2 != null) { + handler2.onFailure(error); + } + return false; + case TERMINATED: + Exception terminatedError = + new IllegalStateException("Connection has been terminated and can't be used"); + if (handler1 != null) { + handler1.onFailure(terminatedError); + } + if (handler2 != null) { + handler2.onFailure(terminatedError); + } + return false; + default: + throw new IllegalStateException("Unknown status: " + connectionStatus); } } - private void registerConnectionReadTimeout( Channel channel ) - { - if ( !channel.eventLoop().inEventLoop() ) - { - throw new IllegalStateException( "This method may only be called in the EventLoop" ); + private void registerConnectionReadTimeout(Channel channel) { + if (!channel.eventLoop().inEventLoop()) { + throw new IllegalStateException("This method may only be called in the EventLoop"); } - if ( connectionReadTimeout != null && connectionReadTimeoutHandler == null ) - { - connectionReadTimeoutHandler = new ConnectionReadTimeoutHandler( connectionReadTimeout, TimeUnit.SECONDS ); - channel.pipeline().addFirst( connectionReadTimeoutHandler ); - log.debug( "Added ConnectionReadTimeoutHandler" ); - messageDispatcher.setBeforeLastHandlerHook( - ( messageType ) -> - { - channel.pipeline().remove( connectionReadTimeoutHandler ); - connectionReadTimeoutHandler = null; - messageDispatcher.setBeforeLastHandlerHook( null ); - log.debug( "Removed ConnectionReadTimeoutHandler" ); - } ); + if (connectionReadTimeout != null && connectionReadTimeoutHandler == null) { + connectionReadTimeoutHandler = new ConnectionReadTimeoutHandler(connectionReadTimeout, TimeUnit.SECONDS); + channel.pipeline().addFirst(connectionReadTimeoutHandler); + log.debug("Added ConnectionReadTimeoutHandler"); + messageDispatcher.setBeforeLastHandlerHook((messageType) -> { + channel.pipeline().remove(connectionReadTimeoutHandler); + connectionReadTimeoutHandler = null; + messageDispatcher.setBeforeLastHandlerHook(null); + log.debug("Removed ConnectionReadTimeoutHandler"); + }); } } - private enum Status - { + private enum Status { OPEN, RELEASED, TERMINATED diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java b/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java index a967a7d990..e6abf8ffc2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java @@ -18,11 +18,13 @@ */ package org.neo4j.driver.internal.async; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; + import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicBoolean; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Logger; @@ -45,11 +47,7 @@ import org.neo4j.driver.internal.spi.ConnectionProvider; import org.neo4j.driver.internal.util.Futures; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; - -public class NetworkSession -{ +public class NetworkSession { private final ConnectionProvider connectionProvider; private final NetworkSessionConnectionContext connectionContext; private final AccessMode mode; @@ -62,301 +60,270 @@ public class NetworkSession private volatile CompletionStage connectionStage = completedWithNull(); private volatile CompletionStage resultCursorStage = completedWithNull(); - private final AtomicBoolean open = new AtomicBoolean( true ); - - public NetworkSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode, - BookmarkHolder bookmarkHolder, String impersonatedUser, long fetchSize, Logging logging ) - { + private final AtomicBoolean open = new AtomicBoolean(true); + + public NetworkSession( + ConnectionProvider connectionProvider, + RetryLogic retryLogic, + DatabaseName databaseName, + AccessMode mode, + BookmarkHolder bookmarkHolder, + String impersonatedUser, + long fetchSize, + Logging logging) { this.connectionProvider = connectionProvider; this.mode = mode; this.retryLogic = retryLogic; - this.log = new PrefixedLogger( "[" + hashCode() + "]", logging.getLog( getClass() ) ); + this.log = new PrefixedLogger("[" + hashCode() + "]", logging.getLog(getClass())); this.bookmarkHolder = bookmarkHolder; - CompletableFuture databaseNameFuture = databaseName.databaseName() - .map( ignored -> CompletableFuture.completedFuture( databaseName ) ) - .orElse( new CompletableFuture<>() ); - this.connectionContext = new NetworkSessionConnectionContext( databaseNameFuture, bookmarkHolder.getBookmark(), impersonatedUser ); + CompletableFuture databaseNameFuture = databaseName + .databaseName() + .map(ignored -> CompletableFuture.completedFuture(databaseName)) + .orElse(new CompletableFuture<>()); + this.connectionContext = + new NetworkSessionConnectionContext(databaseNameFuture, bookmarkHolder.getBookmark(), impersonatedUser); this.fetchSize = fetchSize; } - public CompletionStage runAsync( Query query, TransactionConfig config ) - { + public CompletionStage runAsync(Query query, TransactionConfig config) { CompletionStage newResultCursorStage = - buildResultCursorFactory( query, config ).thenCompose( ResultCursorFactory::asyncResult ); + buildResultCursorFactory(query, config).thenCompose(ResultCursorFactory::asyncResult); - resultCursorStage = newResultCursorStage.exceptionally( error -> null ); - return newResultCursorStage.thenCompose( AsyncResultCursor::mapSuccessfulRunCompletionAsync ).thenApply( cursor -> cursor ); // convert the return type + resultCursorStage = newResultCursorStage.exceptionally(error -> null); + return newResultCursorStage + .thenCompose(AsyncResultCursor::mapSuccessfulRunCompletionAsync) + .thenApply(cursor -> cursor); // convert the return type } - public CompletionStage runRx(Query query, TransactionConfig config ) - { + public CompletionStage runRx(Query query, TransactionConfig config) { CompletionStage newResultCursorStage = - buildResultCursorFactory( query, config ).thenCompose( ResultCursorFactory::rxResult ); + buildResultCursorFactory(query, config).thenCompose(ResultCursorFactory::rxResult); - resultCursorStage = newResultCursorStage.exceptionally( error -> null ); + resultCursorStage = newResultCursorStage.exceptionally(error -> null); return newResultCursorStage; } - public CompletionStage beginTransactionAsync( TransactionConfig config ) - { - return this.beginTransactionAsync( mode, config ); + public CompletionStage beginTransactionAsync(TransactionConfig config) { + return this.beginTransactionAsync(mode, config); } - public CompletionStage beginTransactionAsync( AccessMode mode, TransactionConfig config ) - { + public CompletionStage beginTransactionAsync(AccessMode mode, TransactionConfig config) { ensureSessionIsOpen(); // create a chain that acquires connection and starts a transaction CompletionStage newTransactionStage = ensureNoOpenTxBeforeStartingTx() - .thenCompose( ignore -> acquireConnection( mode ) ) - .thenApply( connection -> ImpersonationUtil.ensureImpersonationSupport( connection, connection.impersonatedUser() ) ) - .thenCompose( connection -> - { - UnmanagedTransaction tx = new UnmanagedTransaction( connection, bookmarkHolder, fetchSize ); - return tx.beginAsync( bookmarkHolder.getBookmark(), config ); - } ); + .thenCompose(ignore -> acquireConnection(mode)) + .thenApply(connection -> + ImpersonationUtil.ensureImpersonationSupport(connection, connection.impersonatedUser())) + .thenCompose(connection -> { + UnmanagedTransaction tx = new UnmanagedTransaction(connection, bookmarkHolder, fetchSize); + return tx.beginAsync(bookmarkHolder.getBookmark(), config); + }); // update the reference to the only known transaction CompletionStage currentTransactionStage = transactionStage; transactionStage = newTransactionStage - .exceptionally( error -> null ) // ignore errors from starting new transaction - .thenCompose( tx -> - { - if ( tx == null ) - { + .exceptionally(error -> null) // ignore errors from starting new transaction + .thenCompose(tx -> { + if (tx == null) { // failed to begin new transaction, keep reference to the existing one return currentTransactionStage; } // new transaction started, keep reference to it - return completedFuture( tx ); - } ); + return completedFuture(tx); + }); return newTransactionStage; } - public CompletionStage resetAsync() - { + public CompletionStage resetAsync() { return existingTransactionOrNull() - .thenAccept( tx -> - { - if ( tx != null ) - { - tx.markTerminated( null ); + .thenAccept(tx -> { + if (tx != null) { + tx.markTerminated(null); } - } ) - .thenCompose( ignore -> connectionStage ) - .thenCompose( connection -> - { - if ( connection != null ) - { + }) + .thenCompose(ignore -> connectionStage) + .thenCompose(connection -> { + if (connection != null) { // there exists an active connection, send a RESET message over it return connection.reset(); } return completedWithNull(); - } ); + }); } - public RetryLogic retryLogic() - { + public RetryLogic retryLogic() { return retryLogic; } - public Bookmark lastBookmark() - { + public Bookmark lastBookmark() { return bookmarkHolder.getBookmark(); } - public CompletionStage releaseConnectionAsync() - { - return connectionStage.thenCompose( connection -> - { - if ( connection != null ) - { + public CompletionStage releaseConnectionAsync() { + return connectionStage.thenCompose(connection -> { + if (connection != null) { // there exists connection, try to release it back to the pool return connection.release(); } // no connection so return null return completedWithNull(); - } ); + }); } - public CompletionStage connectionAsync() - { + public CompletionStage connectionAsync() { return connectionStage; } - public boolean isOpen() - { + public boolean isOpen() { return open.get(); } - public CompletionStage closeAsync() - { - if ( open.compareAndSet( true, false ) ) - { - return resultCursorStage.thenCompose( cursor -> - { - if ( cursor != null ) - { - // there exists a cursor with potentially unconsumed error, try to extract and propagate it - return cursor.discardAllFailureAsync(); - } - // no result cursor exists so no error exists - return completedWithNull(); - } ).thenCompose( cursorError -> closeTransactionAndReleaseConnection().thenApply( txCloseError -> - { - // now we have cursor error, active transaction has been closed and connection has been released - // back to the pool; try to propagate cursor and transaction close errors, if any - CompletionException combinedError = Futures.combineErrors( cursorError, txCloseError ); - if ( combinedError != null ) - { - throw combinedError; - } - return null; - } ) ); + public CompletionStage closeAsync() { + if (open.compareAndSet(true, false)) { + return resultCursorStage + .thenCompose(cursor -> { + if (cursor != null) { + // there exists a cursor with potentially unconsumed error, try to extract and propagate it + return cursor.discardAllFailureAsync(); + } + // no result cursor exists so no error exists + return completedWithNull(); + }) + .thenCompose(cursorError -> closeTransactionAndReleaseConnection() + .thenApply(txCloseError -> { + // now we have cursor error, active transaction has been closed and connection has been + // released + // back to the pool; try to propagate cursor and transaction close errors, if any + CompletionException combinedError = Futures.combineErrors(cursorError, txCloseError); + if (combinedError != null) { + throw combinedError; + } + return null; + })); } return completedWithNull(); } - protected CompletionStage currentConnectionIsOpen() - { - return connectionStage.handle( ( connection, error ) -> - error == null && // no acquisition error - connection != null && // some connection has actually been acquired - connection.isOpen() ); // and it's still open + protected CompletionStage currentConnectionIsOpen() { + return connectionStage.handle((connection, error) -> error == null + && // no acquisition error + connection != null + && // some connection has actually been acquired + connection.isOpen()); // and it's still open } - private CompletionStage buildResultCursorFactory( Query query, TransactionConfig config ) - { + private CompletionStage buildResultCursorFactory(Query query, TransactionConfig config) { ensureSessionIsOpen(); return ensureNoOpenTxBeforeRunningQuery() - .thenCompose( ignore -> acquireConnection( mode ) ) - .thenApply( connection -> ImpersonationUtil.ensureImpersonationSupport( connection, connection.impersonatedUser() ) ) - .thenCompose( - connection -> - { - try - { - ResultCursorFactory factory = connection - .protocol() - .runInAutoCommitTransaction( connection, query, bookmarkHolder, config, fetchSize ); - return completedFuture( factory ); - } - catch ( Throwable e ) - { - return Futures.failedFuture( e ); - } - } ); + .thenCompose(ignore -> acquireConnection(mode)) + .thenApply(connection -> + ImpersonationUtil.ensureImpersonationSupport(connection, connection.impersonatedUser())) + .thenCompose(connection -> { + try { + ResultCursorFactory factory = connection + .protocol() + .runInAutoCommitTransaction(connection, query, bookmarkHolder, config, fetchSize); + return completedFuture(factory); + } catch (Throwable e) { + return Futures.failedFuture(e); + } + }); } - private CompletionStage acquireConnection( AccessMode mode ) - { + private CompletionStage acquireConnection(AccessMode mode) { CompletionStage currentConnectionStage = connectionStage; - CompletionStage newConnectionStage = resultCursorStage.thenCompose( cursor -> - { - if ( cursor == null ) - { - return completedWithNull(); - } - // make sure previous result is fully consumed and connection is released back to the pool - return cursor.pullAllFailureAsync(); - } ).thenCompose( error -> - { - if ( error == null ) - { - // there is no unconsumed error, so one of the following is true: - // 1) this is first time connection is acquired in this session - // 2) previous result has been successful and is fully consumed - // 3) previous result failed and error has been consumed - - // return existing connection, which should've been released back to the pool by now - return currentConnectionStage.exceptionally( ignore -> null ); - } - else - { - // there exists unconsumed error, re-throw it - throw new CompletionException( error ); - } - } ).thenCompose( existingConnection -> - { - if ( existingConnection != null && existingConnection.isOpen() ) - { - // there somehow is an existing open connection, this should not happen, just a precondition - throw new IllegalStateException( "Existing open connection detected" ); - } - return connectionProvider.acquireConnection( connectionContext.contextWithMode( mode ) ); - } ); + CompletionStage newConnectionStage = resultCursorStage + .thenCompose(cursor -> { + if (cursor == null) { + return completedWithNull(); + } + // make sure previous result is fully consumed and connection is released back to the pool + return cursor.pullAllFailureAsync(); + }) + .thenCompose(error -> { + if (error == null) { + // there is no unconsumed error, so one of the following is true: + // 1) this is first time connection is acquired in this session + // 2) previous result has been successful and is fully consumed + // 3) previous result failed and error has been consumed + + // return existing connection, which should've been released back to the pool by now + return currentConnectionStage.exceptionally(ignore -> null); + } else { + // there exists unconsumed error, re-throw it + throw new CompletionException(error); + } + }) + .thenCompose(existingConnection -> { + if (existingConnection != null && existingConnection.isOpen()) { + // there somehow is an existing open connection, this should not happen, just a precondition + throw new IllegalStateException("Existing open connection detected"); + } + return connectionProvider.acquireConnection(connectionContext.contextWithMode(mode)); + }); - connectionStage = newConnectionStage.exceptionally( error -> null ); + connectionStage = newConnectionStage.exceptionally(error -> null); return newConnectionStage; } - private CompletionStage closeTransactionAndReleaseConnection() - { - return existingTransactionOrNull().thenCompose( tx -> - { - if ( tx != null ) - { - // there exists an open transaction, let's close it and propagate the error, if any - return tx.closeAsync() - .thenApply( ignore -> (Throwable) null ) - .exceptionally( error -> error ); - } - // no open transaction so nothing to close - return completedWithNull(); - } ).thenCompose( txCloseError -> - // then release the connection and propagate transaction close error, if any - releaseConnectionAsync().thenApply( ignore -> txCloseError ) ); + private CompletionStage closeTransactionAndReleaseConnection() { + return existingTransactionOrNull() + .thenCompose(tx -> { + if (tx != null) { + // there exists an open transaction, let's close it and propagate the error, if any + return tx.closeAsync() + .thenApply(ignore -> (Throwable) null) + .exceptionally(error -> error); + } + // no open transaction so nothing to close + return completedWithNull(); + }) + .thenCompose(txCloseError -> + // then release the connection and propagate transaction close error, if any + releaseConnectionAsync().thenApply(ignore -> txCloseError)); } - private CompletionStage ensureNoOpenTxBeforeRunningQuery() - { - return ensureNoOpenTx( "Queries cannot be run directly on a session with an open transaction; " + - "either run from within the transaction or use a different session." ); + private CompletionStage ensureNoOpenTxBeforeRunningQuery() { + return ensureNoOpenTx("Queries cannot be run directly on a session with an open transaction; " + + "either run from within the transaction or use a different session."); } - private CompletionStage ensureNoOpenTxBeforeStartingTx() - { - return ensureNoOpenTx( "You cannot begin a transaction on a session with an open transaction; " + - "either run from within the transaction or use a different session." ); + private CompletionStage ensureNoOpenTxBeforeStartingTx() { + return ensureNoOpenTx("You cannot begin a transaction on a session with an open transaction; " + + "either run from within the transaction or use a different session."); } - private CompletionStage ensureNoOpenTx( String errorMessage ) - { - return existingTransactionOrNull().thenAccept( tx -> - { - if ( tx != null ) - { - throw new TransactionNestingException( errorMessage ); + private CompletionStage ensureNoOpenTx(String errorMessage) { + return existingTransactionOrNull().thenAccept(tx -> { + if (tx != null) { + throw new TransactionNestingException(errorMessage); } - } ); + }); } - private CompletionStage existingTransactionOrNull() - { + private CompletionStage existingTransactionOrNull() { return transactionStage - .exceptionally( error -> null ) // handle previous connection acquisition and tx begin failures - .thenApply( tx -> tx != null && tx.isOpen() ? tx : null ); + .exceptionally(error -> null) // handle previous connection acquisition and tx begin failures + .thenApply(tx -> tx != null && tx.isOpen() ? tx : null); } - private void ensureSessionIsOpen() - { - if ( !open.get() ) - { + private void ensureSessionIsOpen() { + if (!open.get()) { throw new ClientException( - "No more interaction with this session are allowed as the current session is already closed. " ); + "No more interaction with this session are allowed as the current session is already closed. "); } } /** * The {@link NetworkSessionConnectionContext#mode} can be mutable for a session connection context */ - private static class NetworkSessionConnectionContext implements ConnectionContext - { + private static class NetworkSessionConnectionContext implements ConnectionContext { private final CompletableFuture databaseNameFuture; private AccessMode mode; @@ -366,42 +333,36 @@ private static class NetworkSessionConnectionContext implements ConnectionContex private final Bookmark rediscoveryBookmark; private final String impersonatedUser; - private NetworkSessionConnectionContext( CompletableFuture databaseNameFuture, Bookmark bookmark, String impersonatedUser ) - { + private NetworkSessionConnectionContext( + CompletableFuture databaseNameFuture, Bookmark bookmark, String impersonatedUser) { this.databaseNameFuture = databaseNameFuture; this.rediscoveryBookmark = bookmark; this.impersonatedUser = impersonatedUser; } - private ConnectionContext contextWithMode( AccessMode mode ) - { + private ConnectionContext contextWithMode(AccessMode mode) { this.mode = mode; return this; } @Override - public CompletableFuture databaseNameFuture() - { + public CompletableFuture databaseNameFuture() { return databaseNameFuture; } @Override - public AccessMode mode() - { + public AccessMode mode() { return mode; } @Override - public Bookmark rediscoveryBookmark() - { + public Bookmark rediscoveryBookmark() { return rediscoveryBookmark; } @Override - public String impersonatedUser() - { + public String impersonatedUser() { return impersonatedUser; } } - } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ResultCursorsHolder.java b/driver/src/main/java/org/neo4j/driver/internal/async/ResultCursorsHolder.java index c33f5bca1b..e1447a7abe 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ResultCursorsHolder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/ResultCursorsHolder.java @@ -18,63 +18,54 @@ */ package org.neo4j.driver.internal.async; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.internal.FailableCursor; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; - -public class ResultCursorsHolder -{ - private final List> cursorStages = Collections.synchronizedList( new ArrayList<>() ); +public class ResultCursorsHolder { + private final List> cursorStages = + Collections.synchronizedList(new ArrayList<>()); - public void add( CompletionStage cursorStage ) - { - Objects.requireNonNull( cursorStage ); - cursorStages.add( cursorStage ); + public void add(CompletionStage cursorStage) { + Objects.requireNonNull(cursorStage); + cursorStages.add(cursorStage); } - CompletionStage retrieveNotConsumedError() - { + CompletionStage retrieveNotConsumedError() { CompletableFuture[] failures = retrieveAllFailures(); - return CompletableFuture.allOf( failures ) - .thenApply( ignore -> findFirstFailure( failures ) ); + return CompletableFuture.allOf(failures).thenApply(ignore -> findFirstFailure(failures)); } - @SuppressWarnings( "unchecked" ) - private CompletableFuture[] retrieveAllFailures() - { + @SuppressWarnings("unchecked") + private CompletableFuture[] retrieveAllFailures() { return cursorStages.stream() - .map( ResultCursorsHolder::retrieveFailure ) - .map( CompletionStage::toCompletableFuture ) - .toArray( CompletableFuture[]::new ); + .map(ResultCursorsHolder::retrieveFailure) + .map(CompletionStage::toCompletableFuture) + .toArray(CompletableFuture[]::new); } - private static Throwable findFirstFailure( CompletableFuture[] completedFailureFutures ) - { + private static Throwable findFirstFailure(CompletableFuture[] completedFailureFutures) { // all given futures should be completed, it is thus safe to get their values - for ( CompletableFuture failureFuture : completedFailureFutures ) - { - Throwable failure = failureFuture.getNow( null ); // does not block - if ( failure != null ) - { + for (CompletableFuture failureFuture : completedFailureFutures) { + Throwable failure = failureFuture.getNow(null); // does not block + if (failure != null) { return failure; } } return null; } - private static CompletionStage retrieveFailure( CompletionStage cursorStage ) - { + private static CompletionStage retrieveFailure(CompletionStage cursorStage) { return cursorStage - .exceptionally( cursor -> null ) - .thenCompose( cursor -> cursor == null ? completedWithNull() : cursor.discardAllFailureAsync() ); + .exceptionally(cursor -> null) + .thenCompose(cursor -> cursor == null ? completedWithNull() : cursor.discardAllFailureAsync()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java b/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java index fbd7a985c7..6d64286398 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java @@ -18,6 +18,13 @@ */ package org.neo4j.driver.internal.async; +import static org.neo4j.driver.internal.util.Futures.asCompletionException; +import static org.neo4j.driver.internal.util.Futures.combineErrors; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; +import static org.neo4j.driver.internal.util.Futures.futureCompletingConsumer; +import static org.neo4j.driver.internal.util.LockUtil.executeWithLock; + import java.util.Arrays; import java.util.EnumSet; import java.util.concurrent.CompletableFuture; @@ -27,7 +34,6 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiFunction; import java.util.function.Function; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; import org.neo4j.driver.Session; @@ -42,17 +48,8 @@ import org.neo4j.driver.internal.messaging.BoltProtocol; import org.neo4j.driver.internal.spi.Connection; -import static org.neo4j.driver.internal.util.Futures.asCompletionException; -import static org.neo4j.driver.internal.util.Futures.combineErrors; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; -import static org.neo4j.driver.internal.util.Futures.futureCompletingConsumer; -import static org.neo4j.driver.internal.util.LockUtil.executeWithLock; - -public class UnmanagedTransaction -{ - private enum State - { +public class UnmanagedTransaction { + private enum State { /** * The transaction is running with no explicit success or failure marked */ @@ -78,9 +75,11 @@ private enum State protected static final String CANT_ROLLBACK_COMMITTED_MSG = "Can't rollback, transaction has been committed"; protected static final String CANT_COMMIT_ROLLED_BACK_MSG = "Can't commit, transaction has been rolled back"; protected static final String CANT_ROLLBACK_ROLLED_BACK_MSG = "Can't rollback, transaction has been rolled back"; - protected static final String CANT_COMMIT_ROLLING_BACK_MSG = "Can't commit, transaction has been requested to be rolled back"; - protected static final String CANT_ROLLBACK_COMMITTING_MSG = "Can't rollback, transaction has been requested to be committed"; - private static final EnumSet OPEN_STATES = EnumSet.of( State.ACTIVE, State.TERMINATED ); + protected static final String CANT_COMMIT_ROLLING_BACK_MSG = + "Can't commit, transaction has been requested to be rolled back"; + protected static final String CANT_ROLLBACK_COMMITTING_MSG = + "Can't rollback, transaction has been requested to be committed"; + private static final EnumSet OPEN_STATES = EnumSet.of(State.ACTIVE, State.TERMINATED); private final Connection connection; private final BoltProtocol protocol; @@ -93,13 +92,12 @@ private enum State private CompletableFuture rollbackFuture; private Throwable causeOfTermination; - public UnmanagedTransaction( Connection connection, BookmarkHolder bookmarkHolder, long fetchSize ) - { - this( connection, bookmarkHolder, fetchSize, new ResultCursorsHolder() ); + public UnmanagedTransaction(Connection connection, BookmarkHolder bookmarkHolder, long fetchSize) { + this(connection, bookmarkHolder, fetchSize, new ResultCursorsHolder()); } - protected UnmanagedTransaction( Connection connection, BookmarkHolder bookmarkHolder, long fetchSize, ResultCursorsHolder resultCursors ) - { + protected UnmanagedTransaction( + Connection connection, BookmarkHolder bookmarkHolder, long fetchSize, ResultCursorsHolder resultCursors) { this.connection = connection; this.protocol = connection.protocol(); this.bookmarkHolder = bookmarkHolder; @@ -107,258 +105,199 @@ protected UnmanagedTransaction( Connection connection, BookmarkHolder bookmarkHo this.fetchSize = fetchSize; } - public CompletionStage beginAsync( Bookmark initialBookmark, TransactionConfig config ) - { - return protocol.beginTransaction( connection, initialBookmark, config ) - .handle( ( ignore, beginError ) -> - { - if ( beginError != null ) - { - if ( beginError instanceof AuthorizationExpiredException ) - { - connection.terminateAndRelease( AuthorizationExpiredException.DESCRIPTION ); - } - else if ( beginError instanceof ConnectionReadTimeoutException ) - { - connection.terminateAndRelease( beginError.getMessage() ); - } - else - { - connection.release(); - } - throw asCompletionException( beginError ); - } - return this; - } ); + public CompletionStage beginAsync(Bookmark initialBookmark, TransactionConfig config) { + return protocol.beginTransaction(connection, initialBookmark, config).handle((ignore, beginError) -> { + if (beginError != null) { + if (beginError instanceof AuthorizationExpiredException) { + connection.terminateAndRelease(AuthorizationExpiredException.DESCRIPTION); + } else if (beginError instanceof ConnectionReadTimeoutException) { + connection.terminateAndRelease(beginError.getMessage()); + } else { + connection.release(); + } + throw asCompletionException(beginError); + } + return this; + }); } - public CompletionStage closeAsync() - { - return closeAsync( false ); + public CompletionStage closeAsync() { + return closeAsync(false); } - public CompletionStage closeAsync( boolean commit ) - { - return closeAsync( commit, true ); + public CompletionStage closeAsync(boolean commit) { + return closeAsync(commit, true); } - public CompletionStage commitAsync() - { - return closeAsync( true, false ); + public CompletionStage commitAsync() { + return closeAsync(true, false); } - public CompletionStage rollbackAsync() - { - return closeAsync( false, false ); + public CompletionStage rollbackAsync() { + return closeAsync(false, false); } - public CompletionStage runAsync( Query query ) - { + public CompletionStage runAsync(Query query) { ensureCanRunQueries(); - CompletionStage cursorStage = - protocol.runInUnmanagedTransaction( connection, query, this, fetchSize ).asyncResult(); - resultCursors.add( cursorStage ); - return cursorStage.thenCompose( AsyncResultCursor::mapSuccessfulRunCompletionAsync ).thenApply( cursor -> cursor ); + CompletionStage cursorStage = protocol.runInUnmanagedTransaction( + connection, query, this, fetchSize) + .asyncResult(); + resultCursors.add(cursorStage); + return cursorStage + .thenCompose(AsyncResultCursor::mapSuccessfulRunCompletionAsync) + .thenApply(cursor -> cursor); } - public CompletionStage runRx( Query query ) - { + public CompletionStage runRx(Query query) { ensureCanRunQueries(); - CompletionStage cursorStage = - protocol.runInUnmanagedTransaction( connection, query, this, fetchSize ).rxResult(); - resultCursors.add( cursorStage ); + CompletionStage cursorStage = protocol.runInUnmanagedTransaction( + connection, query, this, fetchSize) + .rxResult(); + resultCursors.add(cursorStage); return cursorStage; } - public boolean isOpen() - { - return OPEN_STATES.contains( executeWithLock( lock, () -> state ) ); + public boolean isOpen() { + return OPEN_STATES.contains(executeWithLock(lock, () -> state)); } - public void markTerminated( Throwable cause ) - { - executeWithLock( lock, () -> - { - if ( state == State.TERMINATED ) - { - if ( causeOfTermination != null ) - { - addSuppressedWhenNotCaptured( causeOfTermination, cause ); + public void markTerminated(Throwable cause) { + executeWithLock(lock, () -> { + if (state == State.TERMINATED) { + if (causeOfTermination != null) { + addSuppressedWhenNotCaptured(causeOfTermination, cause); } - } - else - { + } else { state = State.TERMINATED; causeOfTermination = cause; } - } ); + }); } - private void addSuppressedWhenNotCaptured( Throwable currentCause, Throwable newCause ) - { - if ( currentCause != newCause ) - { - boolean noneMatch = Arrays.stream( currentCause.getSuppressed() ).noneMatch( suppressed -> suppressed == newCause ); - if ( noneMatch ) - { - currentCause.addSuppressed( newCause ); + private void addSuppressedWhenNotCaptured(Throwable currentCause, Throwable newCause) { + if (currentCause != newCause) { + boolean noneMatch = + Arrays.stream(currentCause.getSuppressed()).noneMatch(suppressed -> suppressed == newCause); + if (noneMatch) { + currentCause.addSuppressed(newCause); } } } - public Connection connection() - { + public Connection connection() { return connection; } - private void ensureCanRunQueries() - { - executeWithLock( lock, () -> - { - if ( state == State.COMMITTED ) - { - throw new ClientException( "Cannot run more queries in this transaction, it has been committed" ); - } - else if ( state == State.ROLLED_BACK ) - { - throw new ClientException( "Cannot run more queries in this transaction, it has been rolled back" ); - } - else if ( state == State.TERMINATED ) - { - throw new ClientException( "Cannot run more queries in this transaction, " + - "it has either experienced an fatal error or was explicitly terminated", causeOfTermination ); + private void ensureCanRunQueries() { + executeWithLock(lock, () -> { + if (state == State.COMMITTED) { + throw new ClientException("Cannot run more queries in this transaction, it has been committed"); + } else if (state == State.ROLLED_BACK) { + throw new ClientException("Cannot run more queries in this transaction, it has been rolled back"); + } else if (state == State.TERMINATED) { + throw new ClientException( + "Cannot run more queries in this transaction, " + + "it has either experienced an fatal error or was explicitly terminated", + causeOfTermination); } - } ); + }); } - private CompletionStage doCommitAsync( Throwable cursorFailure ) - { + private CompletionStage doCommitAsync(Throwable cursorFailure) { ClientException exception = executeWithLock( - lock, () -> state == State.TERMINATED - ? new ClientException( "Transaction can't be committed. " + - "It has been rolled back either because of an error or explicit termination", - cursorFailure != causeOfTermination ? causeOfTermination : null ) - : null - ); - return exception != null ? failedFuture( exception ) : protocol.commitTransaction( connection ).thenAccept( bookmarkHolder::setBookmark ); + lock, + () -> state == State.TERMINATED + ? new ClientException( + "Transaction can't be committed. " + + "It has been rolled back either because of an error or explicit termination", + cursorFailure != causeOfTermination ? causeOfTermination : null) + : null); + return exception != null + ? failedFuture(exception) + : protocol.commitTransaction(connection).thenAccept(bookmarkHolder::setBookmark); } - private CompletionStage doRollbackAsync() - { - return executeWithLock( lock, () -> state ) == State.TERMINATED ? completedWithNull() : protocol.rollbackTransaction( connection ); + private CompletionStage doRollbackAsync() { + return executeWithLock(lock, () -> state) == State.TERMINATED + ? completedWithNull() + : protocol.rollbackTransaction(connection); } - private static BiFunction handleCommitOrRollback( Throwable cursorFailure ) - { - return ( ignore, commitOrRollbackError ) -> - { - CompletionException combinedError = combineErrors( cursorFailure, commitOrRollbackError ); - if ( combinedError != null ) - { + private static BiFunction handleCommitOrRollback(Throwable cursorFailure) { + return (ignore, commitOrRollbackError) -> { + CompletionException combinedError = combineErrors(cursorFailure, commitOrRollbackError); + if (combinedError != null) { throw combinedError; } return null; }; } - private void handleTransactionCompletion( boolean commitAttempt, Throwable throwable ) - { - executeWithLock( lock, () -> - { - if ( commitAttempt && throwable == null ) - { + private void handleTransactionCompletion(boolean commitAttempt, Throwable throwable) { + executeWithLock(lock, () -> { + if (commitAttempt && throwable == null) { state = State.COMMITTED; - } - else - { + } else { state = State.ROLLED_BACK; } - } ); - if ( throwable instanceof AuthorizationExpiredException ) - { - connection.terminateAndRelease( AuthorizationExpiredException.DESCRIPTION ); - } - else if ( throwable instanceof ConnectionReadTimeoutException ) - { - connection.terminateAndRelease( throwable.getMessage() ); - } - else - { + }); + if (throwable instanceof AuthorizationExpiredException) { + connection.terminateAndRelease(AuthorizationExpiredException.DESCRIPTION); + } else if (throwable instanceof ConnectionReadTimeoutException) { + connection.terminateAndRelease(throwable.getMessage()); + } else { connection.release(); // release in background } } - private CompletionStage closeAsync( boolean commit, boolean completeWithNullIfNotOpen ) - { - CompletionStage stage = executeWithLock( lock, () -> - { + private CompletionStage closeAsync(boolean commit, boolean completeWithNullIfNotOpen) { + CompletionStage stage = executeWithLock(lock, () -> { CompletionStage resultStage = null; - if ( completeWithNullIfNotOpen && !isOpen() ) - { + if (completeWithNullIfNotOpen && !isOpen()) { resultStage = completedWithNull(); - } - else if ( state == State.COMMITTED ) - { - resultStage = failedFuture( new ClientException( commit ? CANT_COMMIT_COMMITTED_MSG : CANT_ROLLBACK_COMMITTED_MSG ) ); - } - else if ( state == State.ROLLED_BACK ) - { - resultStage = failedFuture( new ClientException( commit ? CANT_COMMIT_ROLLED_BACK_MSG : CANT_ROLLBACK_ROLLED_BACK_MSG ) ); - } - else - { - if ( commit ) - { - if ( rollbackFuture != null ) - { - resultStage = failedFuture( new ClientException( CANT_COMMIT_ROLLING_BACK_MSG ) ); - } - else if ( commitFuture != null ) - { + } else if (state == State.COMMITTED) { + resultStage = failedFuture( + new ClientException(commit ? CANT_COMMIT_COMMITTED_MSG : CANT_ROLLBACK_COMMITTED_MSG)); + } else if (state == State.ROLLED_BACK) { + resultStage = failedFuture( + new ClientException(commit ? CANT_COMMIT_ROLLED_BACK_MSG : CANT_ROLLBACK_ROLLED_BACK_MSG)); + } else { + if (commit) { + if (rollbackFuture != null) { + resultStage = failedFuture(new ClientException(CANT_COMMIT_ROLLING_BACK_MSG)); + } else if (commitFuture != null) { resultStage = commitFuture; - } - else - { + } else { commitFuture = new CompletableFuture<>(); } - } - else - { - if ( commitFuture != null ) - { - resultStage = failedFuture( new ClientException( CANT_ROLLBACK_COMMITTING_MSG ) ); - } - else if ( rollbackFuture != null ) - { + } else { + if (commitFuture != null) { + resultStage = failedFuture(new ClientException(CANT_ROLLBACK_COMMITTING_MSG)); + } else if (rollbackFuture != null) { resultStage = rollbackFuture; - } - else - { + } else { rollbackFuture = new CompletableFuture<>(); } } } return resultStage; - } ); + }); - if ( stage == null ) - { + if (stage == null) { CompletableFuture targetFuture; - Function> targetAction; - if ( commit ) - { + Function> targetAction; + if (commit) { targetFuture = commitFuture; - targetAction = throwable -> doCommitAsync( throwable ).handle( handleCommitOrRollback( throwable ) ); - } - else - { + targetAction = throwable -> doCommitAsync(throwable).handle(handleCommitOrRollback(throwable)); + } else { targetFuture = rollbackFuture; - targetAction = throwable -> doRollbackAsync().handle( handleCommitOrRollback( throwable ) ); + targetAction = throwable -> doRollbackAsync().handle(handleCommitOrRollback(throwable)); } - resultCursors.retrieveNotConsumedError() - .thenCompose( targetAction ) - .whenComplete( ( ignored, throwable ) -> handleTransactionCompletion( commit, throwable ) ) - .whenComplete( futureCompletingConsumer( targetFuture ) ); + resultCursors + .retrieveNotConsumedError() + .thenCompose(targetAction) + .whenComplete((ignored, throwable) -> handleTransactionCompletion(commit, throwable)) + .whenComplete(futureCompletingConsumer(targetFuture)); stage = targetFuture; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/AuthorizationStateListener.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/AuthorizationStateListener.java index 3a7dac6297..eff66fb863 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/AuthorizationStateListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/AuthorizationStateListener.java @@ -19,19 +19,17 @@ package org.neo4j.driver.internal.async.connection; import io.netty.channel.Channel; - import org.neo4j.driver.exceptions.AuthorizationExpiredException; /** * Listener for authorization info state maintained on the server side. */ -public interface AuthorizationStateListener -{ +public interface AuthorizationStateListener { /** * Notifies the listener that the credentials stored on the server side have expired. * * @param e the {@link AuthorizationExpiredException} exception. * @param channel the channel that received the error. */ - void onExpired( AuthorizationExpiredException e, Channel channel ); + void onExpired(AuthorizationExpiredException e, Channel channel); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java index 5576de874f..33d58114ab 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java @@ -18,8 +18,11 @@ */ package org.neo4j.driver.internal.async.connection; -import io.netty.buffer.ByteBuf; +import static io.netty.buffer.Unpooled.copyInt; +import static io.netty.buffer.Unpooled.unreleasableBuffer; +import static java.lang.Integer.toHexString; +import io.netty.buffer.ByteBuf; import org.neo4j.driver.internal.messaging.BoltProtocolVersion; import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; @@ -27,60 +30,50 @@ import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42; import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44; -import static io.netty.buffer.Unpooled.copyInt; -import static io.netty.buffer.Unpooled.unreleasableBuffer; -import static java.lang.Integer.toHexString; - -public final class BoltProtocolUtil -{ +public final class BoltProtocolUtil { public static final int BOLT_MAGIC_PREAMBLE = 0x6060B017; - public static final BoltProtocolVersion NO_PROTOCOL_VERSION = new BoltProtocolVersion( 0 , 0 ); + public static final BoltProtocolVersion NO_PROTOCOL_VERSION = new BoltProtocolVersion(0, 0); public static final int CHUNK_HEADER_SIZE_BYTES = 2; public static final int DEFAULT_MAX_OUTBOUND_CHUNK_SIZE_BYTES = Short.MAX_VALUE / 2; - private static final ByteBuf HANDSHAKE_BUF = unreleasableBuffer( copyInt( - BOLT_MAGIC_PREAMBLE, - BoltProtocolV44.VERSION.toIntRange( BoltProtocolV42.VERSION ), - BoltProtocolV41.VERSION.toInt(), - BoltProtocolV4.VERSION.toInt(), - BoltProtocolV3.VERSION.toInt() ) ).asReadOnly(); + private static final ByteBuf HANDSHAKE_BUF = unreleasableBuffer(copyInt( + BOLT_MAGIC_PREAMBLE, + BoltProtocolV44.VERSION.toIntRange(BoltProtocolV42.VERSION), + BoltProtocolV41.VERSION.toInt(), + BoltProtocolV4.VERSION.toInt(), + BoltProtocolV3.VERSION.toInt())) + .asReadOnly(); private static final String HANDSHAKE_STRING = createHandshakeString(); - private BoltProtocolUtil() - { - } + private BoltProtocolUtil() {} - public static ByteBuf handshakeBuf() - { + public static ByteBuf handshakeBuf() { return HANDSHAKE_BUF.duplicate(); } - public static String handshakeString() - { + public static String handshakeString() { return HANDSHAKE_STRING; } - public static void writeMessageBoundary( ByteBuf buf ) - { - buf.writeShort( 0 ); + public static void writeMessageBoundary(ByteBuf buf) { + buf.writeShort(0); } - public static void writeEmptyChunkHeader( ByteBuf buf ) - { - buf.writeShort( 0 ); + public static void writeEmptyChunkHeader(ByteBuf buf) { + buf.writeShort(0); } - public static void writeChunkHeader( ByteBuf buf, int chunkStartIndex, int headerValue ) - { - buf.setShort( chunkStartIndex, headerValue ); + public static void writeChunkHeader(ByteBuf buf, int chunkStartIndex, int headerValue) { + buf.setShort(chunkStartIndex, headerValue); } - private static String createHandshakeString() - { + private static String createHandshakeString() { ByteBuf buf = handshakeBuf(); - return String.format( "[0x%s, %s, %s, %s, %s]", toHexString( buf.readInt() ), buf.readInt(), buf.readInt(), buf.readInt(), buf.readInt() ); + return String.format( + "[0x%s, %s, %s, %s, %s]", + toHexString(buf.readInt()), buf.readInt(), buf.readInt(), buf.readInt(), buf.readInt()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/BootstrapFactory.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/BootstrapFactory.java index 4f1ac0c3ba..9377123a99 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/BootstrapFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/BootstrapFactory.java @@ -22,24 +22,19 @@ import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; -public final class BootstrapFactory -{ - private BootstrapFactory() - { - } +public final class BootstrapFactory { + private BootstrapFactory() {} - public static Bootstrap newBootstrap( int threadCount ) - { - return newBootstrap( EventLoopGroupFactory.newEventLoopGroup( threadCount ) ); + public static Bootstrap newBootstrap(int threadCount) { + return newBootstrap(EventLoopGroupFactory.newEventLoopGroup(threadCount)); } - public static Bootstrap newBootstrap( EventLoopGroup eventLoopGroup ) - { + public static Bootstrap newBootstrap(EventLoopGroup eventLoopGroup) { Bootstrap bootstrap = new Bootstrap(); - bootstrap.group( eventLoopGroup ); - bootstrap.channel( EventLoopGroupFactory.channelClass() ); - bootstrap.option( ChannelOption.SO_KEEPALIVE, true ); - bootstrap.option( ChannelOption.SO_REUSEADDR, true ); + bootstrap.group(eventLoopGroup); + bootstrap.channel(EventLoopGroupFactory.channelClass()); + bootstrap.option(ChannelOption.SO_KEEPALIVE, true); + bootstrap.option(ChannelOption.SO_REUSEADDR, true); return bootstrap; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelAttributes.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelAttributes.java index f3a8eefc95..faddf708fc 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelAttributes.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelAttributes.java @@ -18,176 +18,145 @@ */ package org.neo4j.driver.internal.async.connection; +import static io.netty.util.AttributeKey.newInstance; + import io.netty.channel.Channel; import io.netty.util.AttributeKey; - import java.util.Optional; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.messaging.BoltProtocolVersion; import org.neo4j.driver.internal.util.ServerVersion; -import static io.netty.util.AttributeKey.newInstance; - -public final class ChannelAttributes -{ - private static final AttributeKey CONNECTION_ID = newInstance( "connectionId" ); - private static final AttributeKey POOL_ID = newInstance( "poolId" ); - private static final AttributeKey PROTOCOL_VERSION = newInstance( "protocolVersion" ); - private static final AttributeKey SERVER_AGENT = newInstance( "serverAgent" ); - private static final AttributeKey ADDRESS = newInstance( "serverAddress" ); - private static final AttributeKey SERVER_VERSION = newInstance( "serverVersion" ); - private static final AttributeKey CREATION_TIMESTAMP = newInstance( "creationTimestamp" ); - private static final AttributeKey LAST_USED_TIMESTAMP = newInstance( "lastUsedTimestamp" ); - private static final AttributeKey MESSAGE_DISPATCHER = newInstance( "messageDispatcher" ); - private static final AttributeKey TERMINATION_REASON = newInstance( "terminationReason" ); - private static final AttributeKey AUTHORIZATION_STATE_LISTENER = newInstance( "authorizationStateListener" ); +public final class ChannelAttributes { + private static final AttributeKey CONNECTION_ID = newInstance("connectionId"); + private static final AttributeKey POOL_ID = newInstance("poolId"); + private static final AttributeKey PROTOCOL_VERSION = newInstance("protocolVersion"); + private static final AttributeKey SERVER_AGENT = newInstance("serverAgent"); + private static final AttributeKey ADDRESS = newInstance("serverAddress"); + private static final AttributeKey SERVER_VERSION = newInstance("serverVersion"); + private static final AttributeKey CREATION_TIMESTAMP = newInstance("creationTimestamp"); + private static final AttributeKey LAST_USED_TIMESTAMP = newInstance("lastUsedTimestamp"); + private static final AttributeKey MESSAGE_DISPATCHER = newInstance("messageDispatcher"); + private static final AttributeKey TERMINATION_REASON = newInstance("terminationReason"); + private static final AttributeKey AUTHORIZATION_STATE_LISTENER = + newInstance("authorizationStateListener"); // configuration hints provided by the server - private static final AttributeKey CONNECTION_READ_TIMEOUT = newInstance( "connectionReadTimeout" ); + private static final AttributeKey CONNECTION_READ_TIMEOUT = newInstance("connectionReadTimeout"); - private ChannelAttributes() - { - } + private ChannelAttributes() {} - public static String connectionId( Channel channel ) - { - return get( channel, CONNECTION_ID ); + public static String connectionId(Channel channel) { + return get(channel, CONNECTION_ID); } - public static void setConnectionId( Channel channel, String id ) - { - setOnce( channel, CONNECTION_ID, id ); + public static void setConnectionId(Channel channel, String id) { + setOnce(channel, CONNECTION_ID, id); } - public static String poolId( Channel channel ) - { - return get( channel, POOL_ID ); + public static String poolId(Channel channel) { + return get(channel, POOL_ID); } - public static void setPoolId( Channel channel, String id ) - { - setOnce( channel, POOL_ID, id ); + public static void setPoolId(Channel channel, String id) { + setOnce(channel, POOL_ID, id); } - public static BoltProtocolVersion protocolVersion( Channel channel ) - { - return get( channel, PROTOCOL_VERSION ); + public static BoltProtocolVersion protocolVersion(Channel channel) { + return get(channel, PROTOCOL_VERSION); } - public static void setProtocolVersion( Channel channel, BoltProtocolVersion version ) - { - setOnce( channel, PROTOCOL_VERSION, version ); + public static void setProtocolVersion(Channel channel, BoltProtocolVersion version) { + setOnce(channel, PROTOCOL_VERSION, version); } - public static void setServerAgent( Channel channel, String serverAgent ) - { - setOnce( channel, SERVER_AGENT, serverAgent ); + public static void setServerAgent(Channel channel, String serverAgent) { + setOnce(channel, SERVER_AGENT, serverAgent); } - public static String serverAgent( Channel channel ) - { - return get( channel, SERVER_AGENT ); + public static String serverAgent(Channel channel) { + return get(channel, SERVER_AGENT); } - public static BoltServerAddress serverAddress( Channel channel ) - { - return get( channel, ADDRESS ); + public static BoltServerAddress serverAddress(Channel channel) { + return get(channel, ADDRESS); } - public static void setServerAddress( Channel channel, BoltServerAddress address ) - { - setOnce( channel, ADDRESS, address ); + public static void setServerAddress(Channel channel, BoltServerAddress address) { + setOnce(channel, ADDRESS, address); } - public static ServerVersion serverVersion( Channel channel ) - { - return get( channel, SERVER_VERSION ); + public static ServerVersion serverVersion(Channel channel) { + return get(channel, SERVER_VERSION); } - public static void setServerVersion( Channel channel, ServerVersion version ) - { - setOnce( channel, SERVER_VERSION, version ); + public static void setServerVersion(Channel channel, ServerVersion version) { + setOnce(channel, SERVER_VERSION, version); } - public static long creationTimestamp( Channel channel ) - { - return get( channel, CREATION_TIMESTAMP ); + public static long creationTimestamp(Channel channel) { + return get(channel, CREATION_TIMESTAMP); } - public static void setCreationTimestamp( Channel channel, long creationTimestamp ) - { - setOnce( channel, CREATION_TIMESTAMP, creationTimestamp ); + public static void setCreationTimestamp(Channel channel, long creationTimestamp) { + setOnce(channel, CREATION_TIMESTAMP, creationTimestamp); } - public static Long lastUsedTimestamp( Channel channel ) - { - return get( channel, LAST_USED_TIMESTAMP ); + public static Long lastUsedTimestamp(Channel channel) { + return get(channel, LAST_USED_TIMESTAMP); } - public static void setLastUsedTimestamp( Channel channel, long lastUsedTimestamp ) - { - set( channel, LAST_USED_TIMESTAMP, lastUsedTimestamp ); + public static void setLastUsedTimestamp(Channel channel, long lastUsedTimestamp) { + set(channel, LAST_USED_TIMESTAMP, lastUsedTimestamp); } - public static InboundMessageDispatcher messageDispatcher( Channel channel ) - { - return get( channel, MESSAGE_DISPATCHER ); + public static InboundMessageDispatcher messageDispatcher(Channel channel) { + return get(channel, MESSAGE_DISPATCHER); } - public static void setMessageDispatcher( Channel channel, InboundMessageDispatcher messageDispatcher ) - { - setOnce( channel, MESSAGE_DISPATCHER, messageDispatcher ); + public static void setMessageDispatcher(Channel channel, InboundMessageDispatcher messageDispatcher) { + setOnce(channel, MESSAGE_DISPATCHER, messageDispatcher); } - public static String terminationReason( Channel channel ) - { - return get( channel, TERMINATION_REASON ); + public static String terminationReason(Channel channel) { + return get(channel, TERMINATION_REASON); } - public static void setTerminationReason( Channel channel, String reason ) - { - setOnce( channel, TERMINATION_REASON, reason ); + public static void setTerminationReason(Channel channel, String reason) { + setOnce(channel, TERMINATION_REASON, reason); } - public static AuthorizationStateListener authorizationStateListener( Channel channel ) - { - return get( channel, AUTHORIZATION_STATE_LISTENER ); + public static AuthorizationStateListener authorizationStateListener(Channel channel) { + return get(channel, AUTHORIZATION_STATE_LISTENER); } - public static void setAuthorizationStateListener( Channel channel, AuthorizationStateListener authorizationStateListener ) - { - set( channel, AUTHORIZATION_STATE_LISTENER, authorizationStateListener ); + public static void setAuthorizationStateListener( + Channel channel, AuthorizationStateListener authorizationStateListener) { + set(channel, AUTHORIZATION_STATE_LISTENER, authorizationStateListener); } - public static Optional connectionReadTimeout( Channel channel ) - { - return Optional.ofNullable( get( channel, CONNECTION_READ_TIMEOUT ) ); + public static Optional connectionReadTimeout(Channel channel) { + return Optional.ofNullable(get(channel, CONNECTION_READ_TIMEOUT)); } - public static void setConnectionReadTimeout( Channel channel, Long connectionReadTimeout ) - { - setOnce( channel, CONNECTION_READ_TIMEOUT, connectionReadTimeout ); + public static void setConnectionReadTimeout(Channel channel, Long connectionReadTimeout) { + setOnce(channel, CONNECTION_READ_TIMEOUT, connectionReadTimeout); } - private static T get( Channel channel, AttributeKey key ) - { - return channel.attr( key ).get(); + private static T get(Channel channel, AttributeKey key) { + return channel.attr(key).get(); } - private static void set( Channel channel, AttributeKey key, T value ) - { - channel.attr( key ).set( value ); + private static void set(Channel channel, AttributeKey key, T value) { + channel.attr(key).set(value); } - private static void setOnce( Channel channel, AttributeKey key, T value ) - { - T existingValue = channel.attr( key ).setIfAbsent( value ); - if ( existingValue != null ) - { + private static void setOnce(Channel channel, AttributeKey key, T value) { + T existingValue = channel.attr(key).setIfAbsent(value); + if (existingValue != null) { throw new IllegalStateException( - "Unable to set " + key.name() + " because it is already set to " + existingValue ); + "Unable to set " + key.name() + " because it is already set to " + existingValue); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectedListener.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectedListener.java index 92e1b26ba5..0025574fc5 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectedListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnectedListener.java @@ -18,32 +18,32 @@ */ package org.neo4j.driver.internal.async.connection; +import static java.lang.String.format; +import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.handshakeBuf; +import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.handshakeString; + import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; - -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.logging.ChannelActivityLogger; import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.exceptions.ServiceUnavailableException; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.logging.ChannelActivityLogger; -import static java.lang.String.format; -import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.handshakeBuf; -import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.handshakeString; - -public class ChannelConnectedListener implements ChannelFutureListener -{ +public class ChannelConnectedListener implements ChannelFutureListener { private final BoltServerAddress address; private final ChannelPipelineBuilder pipelineBuilder; private final ChannelPromise handshakeCompletedPromise; private final Logging logging; - public ChannelConnectedListener( BoltServerAddress address, ChannelPipelineBuilder pipelineBuilder, - ChannelPromise handshakeCompletedPromise, Logging logging ) - { + public ChannelConnectedListener( + BoltServerAddress address, + ChannelPipelineBuilder pipelineBuilder, + ChannelPromise handshakeCompletedPromise, + Logging logging) { this.address = address; this.pipelineBuilder = pipelineBuilder; this.handshakeCompletedPromise = handshakeCompletedPromise; @@ -51,30 +51,28 @@ public ChannelConnectedListener( BoltServerAddress address, ChannelPipelineBuild } @Override - public void operationComplete( ChannelFuture future ) - { + public void operationComplete(ChannelFuture future) { Channel channel = future.channel(); - Logger log = new ChannelActivityLogger( channel, logging, getClass() ); + Logger log = new ChannelActivityLogger(channel, logging, getClass()); - if ( future.isSuccess() ) - { - log.trace( "Channel %s connected, initiating bolt handshake", channel ); + if (future.isSuccess()) { + log.trace("Channel %s connected, initiating bolt handshake", channel); ChannelPipeline pipeline = channel.pipeline(); - pipeline.addLast( new HandshakeHandler( pipelineBuilder, handshakeCompletedPromise, logging ) ); - log.debug( "C: [Bolt Handshake] %s", handshakeString() ); - channel.writeAndFlush( handshakeBuf(), channel.voidPromise() ); - } - else - { - handshakeCompletedPromise.setFailure( databaseUnavailableError( address, future.cause() ) ); + pipeline.addLast(new HandshakeHandler(pipelineBuilder, handshakeCompletedPromise, logging)); + log.debug("C: [Bolt Handshake] %s", handshakeString()); + channel.writeAndFlush(handshakeBuf(), channel.voidPromise()); + } else { + handshakeCompletedPromise.setFailure(databaseUnavailableError(address, future.cause())); } } - private static Throwable databaseUnavailableError( BoltServerAddress address, Throwable cause ) - { - return new ServiceUnavailableException( format( - "Unable to connect to %s, ensure the database is running and that there " + - "is a working network connection to it.", address ), cause ); + private static Throwable databaseUnavailableError(BoltServerAddress address, Throwable cause) { + return new ServiceUnavailableException( + format( + "Unable to connect to %s, ensure the database is running and that there " + + "is a working network connection to it.", + address), + cause); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnector.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnector.java index 76fa713e1e..affef4b650 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnector.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelConnector.java @@ -20,10 +20,8 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; - import org.neo4j.driver.internal.BoltServerAddress; -public interface ChannelConnector -{ - ChannelFuture connect( BoltServerAddress address, Bootstrap bootstrap ); +public interface ChannelConnector { + ChannelFuture connect(BoltServerAddress address, Bootstrap bootstrap); } 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 0bfe976f1a..32630d6450 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 @@ -18,6 +18,8 @@ */ package org.neo4j.driver.internal.async.connection; +import static java.util.Objects.requireNonNull; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -25,10 +27,8 @@ import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; import io.netty.resolver.AddressResolverGroup; - import java.net.InetSocketAddress; import java.net.SocketAddress; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Logging; @@ -42,10 +42,7 @@ import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.util.Clock; -import static java.util.Objects.requireNonNull; - -public class ChannelConnectorImpl implements ChannelConnector -{ +public class ChannelConnectorImpl implements ChannelConnector { private final String userAgent; private final AuthToken authToken; private final RoutingContext routingContext; @@ -57,97 +54,102 @@ public class ChannelConnectorImpl implements ChannelConnector private final DomainNameResolver domainNameResolver; private final AddressResolverGroup addressResolverGroup; - public ChannelConnectorImpl( ConnectionSettings connectionSettings, SecurityPlan securityPlan, Logging logging, - Clock clock, RoutingContext routingContext, DomainNameResolver domainNameResolver ) - { - this( connectionSettings, securityPlan, new ChannelPipelineBuilderImpl(), logging, clock, routingContext, domainNameResolver ); + public ChannelConnectorImpl( + ConnectionSettings connectionSettings, + SecurityPlan securityPlan, + Logging logging, + Clock clock, + RoutingContext routingContext, + DomainNameResolver domainNameResolver) { + this( + connectionSettings, + securityPlan, + new ChannelPipelineBuilderImpl(), + logging, + clock, + routingContext, + domainNameResolver); } - public ChannelConnectorImpl( ConnectionSettings connectionSettings, SecurityPlan securityPlan, - ChannelPipelineBuilder pipelineBuilder, Logging logging, Clock clock, RoutingContext routingContext, - DomainNameResolver domainNameResolver ) - { + public ChannelConnectorImpl( + ConnectionSettings connectionSettings, + SecurityPlan securityPlan, + ChannelPipelineBuilder pipelineBuilder, + Logging logging, + Clock clock, + RoutingContext routingContext, + DomainNameResolver domainNameResolver) { this.userAgent = connectionSettings.userAgent(); - this.authToken = requireValidAuthToken( connectionSettings.authToken() ); + this.authToken = requireValidAuthToken(connectionSettings.authToken()); this.routingContext = routingContext; this.connectTimeoutMillis = connectionSettings.connectTimeoutMillis(); - this.securityPlan = requireNonNull( securityPlan ); + this.securityPlan = requireNonNull(securityPlan); this.pipelineBuilder = pipelineBuilder; - this.logging = requireNonNull( logging ); - this.clock = requireNonNull( clock ); - this.domainNameResolver = requireNonNull( domainNameResolver ); - this.addressResolverGroup = new NettyDomainNameResolverGroup( this.domainNameResolver ); + this.logging = requireNonNull(logging); + this.clock = requireNonNull(clock); + this.domainNameResolver = requireNonNull(domainNameResolver); + this.addressResolverGroup = new NettyDomainNameResolverGroup(this.domainNameResolver); } @Override - public ChannelFuture connect( BoltServerAddress address, Bootstrap bootstrap ) - { - bootstrap.option( ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeoutMillis ); - bootstrap.handler( new NettyChannelInitializer( address, securityPlan, connectTimeoutMillis, clock, logging ) ); - bootstrap.resolver( addressResolverGroup ); + public ChannelFuture connect(BoltServerAddress address, Bootstrap bootstrap) { + bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeoutMillis); + bootstrap.handler(new NettyChannelInitializer(address, securityPlan, connectTimeoutMillis, clock, logging)); + bootstrap.resolver(addressResolverGroup); SocketAddress socketAddress; - try - { - socketAddress = new InetSocketAddress( domainNameResolver.resolve( address.connectionHost() )[0], address.port() ); - } - catch ( Throwable t ) - { - socketAddress = InetSocketAddress.createUnresolved( address.connectionHost(), address.port() ); + try { + socketAddress = + new InetSocketAddress(domainNameResolver.resolve(address.connectionHost())[0], address.port()); + } catch (Throwable t) { + socketAddress = InetSocketAddress.createUnresolved(address.connectionHost(), address.port()); } - ChannelFuture channelConnected = bootstrap.connect( socketAddress ); + ChannelFuture channelConnected = bootstrap.connect(socketAddress); Channel channel = channelConnected.channel(); ChannelPromise handshakeCompleted = channel.newPromise(); ChannelPromise connectionInitialized = channel.newPromise(); - installChannelConnectedListeners( address, channelConnected, handshakeCompleted ); - installHandshakeCompletedListeners( handshakeCompleted, connectionInitialized ); + installChannelConnectedListeners(address, channelConnected, handshakeCompleted); + installHandshakeCompletedListeners(handshakeCompleted, connectionInitialized); return connectionInitialized; } - private void installChannelConnectedListeners( BoltServerAddress address, ChannelFuture channelConnected, - ChannelPromise handshakeCompleted ) - { + private void installChannelConnectedListeners( + BoltServerAddress address, ChannelFuture channelConnected, ChannelPromise handshakeCompleted) { ChannelPipeline pipeline = channelConnected.channel().pipeline(); // add timeout handler to the pipeline when channel is connected. it's needed to limit amount of time code // spends in TLS and Bolt handshakes. prevents infinite waiting when database does not respond - channelConnected.addListener( future -> - pipeline.addFirst( new ConnectTimeoutHandler( connectTimeoutMillis ) ) ); + channelConnected.addListener(future -> pipeline.addFirst(new ConnectTimeoutHandler(connectTimeoutMillis))); // add listener that sends Bolt handshake bytes when channel is connected channelConnected.addListener( - new ChannelConnectedListener( address, pipelineBuilder, handshakeCompleted, logging ) ); + new ChannelConnectedListener(address, pipelineBuilder, handshakeCompleted, logging)); } - private void installHandshakeCompletedListeners( ChannelPromise handshakeCompleted, - ChannelPromise connectionInitialized ) - { + private void installHandshakeCompletedListeners( + ChannelPromise handshakeCompleted, ChannelPromise connectionInitialized) { ChannelPipeline pipeline = handshakeCompleted.channel().pipeline(); // remove timeout handler from the pipeline once TLS and Bolt handshakes are completed. regular protocol // messages will flow next and we do not want to have read timeout for them - handshakeCompleted.addListener( future -> pipeline.remove( ConnectTimeoutHandler.class ) ); + handshakeCompleted.addListener(future -> pipeline.remove(ConnectTimeoutHandler.class)); // add listener that sends an INIT message. connection is now fully established. channel pipeline if fully // set to send/receive messages for a selected protocol version - handshakeCompleted.addListener( new HandshakeCompletedListener( userAgent, authToken, routingContext, connectionInitialized ) ); + handshakeCompleted.addListener( + new HandshakeCompletedListener(userAgent, authToken, routingContext, connectionInitialized)); } - private static AuthToken requireValidAuthToken( AuthToken token ) - { - if ( token instanceof InternalAuthToken ) - { + private static AuthToken requireValidAuthToken(AuthToken token) { + if (token instanceof InternalAuthToken) { return token; - } - else - { - throw new ClientException( - "Unknown authentication token, `" + token + "`. Please use one of the supported " + - "tokens from `" + AuthTokens.class.getSimpleName() + "`." ); + } else { + throw new ClientException("Unknown authentication token, `" + token + "`. Please use one of the supported " + + "tokens from `" + AuthTokens.class.getSimpleName() + "`."); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilder.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilder.java index 4064dc71fa..6c439b9abc 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilder.java @@ -19,11 +19,9 @@ package org.neo4j.driver.internal.async.connection; import io.netty.channel.ChannelPipeline; - -import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.Logging; +import org.neo4j.driver.internal.messaging.MessageFormat; -public interface ChannelPipelineBuilder -{ - void build( MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging ); +public interface ChannelPipelineBuilder { + void build(MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilderImpl.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilderImpl.java index 34bf560bc9..0d9869dccd 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilderImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilderImpl.java @@ -19,29 +19,26 @@ package org.neo4j.driver.internal.async.connection; import io.netty.channel.ChannelPipeline; - +import org.neo4j.driver.Logging; import org.neo4j.driver.internal.async.inbound.ChannelErrorHandler; import org.neo4j.driver.internal.async.inbound.ChunkDecoder; import org.neo4j.driver.internal.async.inbound.InboundMessageHandler; import org.neo4j.driver.internal.async.inbound.MessageDecoder; import org.neo4j.driver.internal.async.outbound.OutboundMessageHandler; import org.neo4j.driver.internal.messaging.MessageFormat; -import org.neo4j.driver.Logging; -public class ChannelPipelineBuilderImpl implements ChannelPipelineBuilder -{ +public class ChannelPipelineBuilderImpl implements ChannelPipelineBuilder { @Override - public void build( MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging ) - { + public void build(MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging) { // inbound handlers - pipeline.addLast( new ChunkDecoder( logging ) ); - pipeline.addLast( new MessageDecoder() ); - pipeline.addLast( new InboundMessageHandler( messageFormat, logging ) ); + pipeline.addLast(new ChunkDecoder(logging)); + pipeline.addLast(new MessageDecoder()); + pipeline.addLast(new InboundMessageHandler(messageFormat, logging)); // outbound handlers - pipeline.addLast( OutboundMessageHandler.NAME, new OutboundMessageHandler( messageFormat, logging ) ); + pipeline.addLast(OutboundMessageHandler.NAME, new OutboundMessageHandler(messageFormat, logging)); // last one - error handler - pipeline.addLast( new ChannelErrorHandler( logging ) ); + pipeline.addLast(new ChannelErrorHandler(logging)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/DirectConnection.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/DirectConnection.java index ff0f663e55..da6b25d1c6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/DirectConnection.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/DirectConnection.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.async.connection; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DatabaseName; @@ -33,131 +32,110 @@ /** * This is a connection used by {@link DirectConnectionProvider} to connect to a remote database. */ -public class DirectConnection implements Connection -{ +public class DirectConnection implements Connection { private final Connection delegate; private final AccessMode mode; private final DatabaseName databaseName; private final String impersonatedUser; - public DirectConnection( Connection delegate, DatabaseName databaseName, AccessMode mode, String impersonatedUser ) - { + public DirectConnection(Connection delegate, DatabaseName databaseName, AccessMode mode, String impersonatedUser) { this.delegate = delegate; this.mode = mode; this.databaseName = databaseName; this.impersonatedUser = impersonatedUser; } - public Connection connection() - { + public Connection connection() { return delegate; } @Override - public boolean isOpen() - { + public boolean isOpen() { return delegate.isOpen(); } @Override - public void enableAutoRead() - { + public void enableAutoRead() { delegate.enableAutoRead(); } @Override - public void disableAutoRead() - { + public void disableAutoRead() { delegate.disableAutoRead(); } @Override - public void write( Message message, ResponseHandler handler ) - { - delegate.write( message, handler ); + public void write(Message message, ResponseHandler handler) { + delegate.write(message, handler); } @Override - public void write( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ) - { - delegate.write( message1, handler1, message2, handler2 ); + public void write(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2) { + delegate.write(message1, handler1, message2, handler2); } @Override - public void writeAndFlush( Message message, ResponseHandler handler ) - { - delegate.writeAndFlush( message, handler ); + public void writeAndFlush(Message message, ResponseHandler handler) { + delegate.writeAndFlush(message, handler); } @Override - public void writeAndFlush( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ) - { - delegate.writeAndFlush( message1, handler1, message2, handler2 ); + public void writeAndFlush(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2) { + delegate.writeAndFlush(message1, handler1, message2, handler2); } @Override - public CompletionStage reset() - { + public CompletionStage reset() { return delegate.reset(); } @Override - public CompletionStage release() - { + public CompletionStage release() { return delegate.release(); } @Override - public void terminateAndRelease( String reason ) - { - delegate.terminateAndRelease( reason ); + public void terminateAndRelease(String reason) { + delegate.terminateAndRelease(reason); } @Override - public String serverAgent() - { + public String serverAgent() { return delegate.serverAgent(); } @Override - public BoltServerAddress serverAddress() - { + public BoltServerAddress serverAddress() { return delegate.serverAddress(); } @Override - public ServerVersion serverVersion() - { + public ServerVersion serverVersion() { return delegate.serverVersion(); } @Override - public BoltProtocol protocol() - { + public BoltProtocol protocol() { return delegate.protocol(); } @Override - public AccessMode mode() - { + public AccessMode mode() { return mode; } @Override - public DatabaseName databaseName() - { + public DatabaseName databaseName() { return this.databaseName; } @Override - public String impersonatedUser() - { + public String impersonatedUser() { return impersonatedUser; } @Override - public void flush() - { + public void flush() { delegate.flush(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/EventLoopGroupFactory.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/EventLoopGroupFactory.java index 600b45630d..e97371ea83 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/EventLoopGroupFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/EventLoopGroupFactory.java @@ -25,26 +25,21 @@ import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.util.concurrent.DefaultThreadFactory; import io.netty.util.concurrent.FastThreadLocalThread; - import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; - import org.neo4j.driver.Session; import org.neo4j.driver.async.AsyncSession; /** * Manages creation of Netty {@link EventLoopGroup}s, which are basically {@link Executor}s that perform IO operations. */ -public final class EventLoopGroupFactory -{ +public final class EventLoopGroupFactory { private static final String THREAD_NAME_PREFIX = "Neo4jDriverIO"; private static final int THREAD_PRIORITY = Thread.MAX_PRIORITY; private static final boolean THREAD_IS_DAEMON = true; - private EventLoopGroupFactory() - { - } + private EventLoopGroupFactory() {} /** * Get class of {@link Channel} for {@link Bootstrap#channel(Class)} method. @@ -52,8 +47,7 @@ private EventLoopGroupFactory() * @return class of the channel, which should be consistent with {@link EventLoopGroup}s returned by * {@link #newEventLoopGroup(int)}. */ - public static Class channelClass() - { + public static Class channelClass() { return NioSocketChannel.class; } @@ -64,9 +58,8 @@ public static Class channelClass() * @param threadCount amount of IO threads for the new group. * @return new group consistent with channel class returned by {@link #channelClass()}. */ - public static EventLoopGroup newEventLoopGroup( int threadCount ) - { - return new DriverEventLoopGroup( threadCount ); + public static EventLoopGroup newEventLoopGroup(int threadCount) { + return new DriverEventLoopGroup(threadCount); } /** @@ -77,13 +70,11 @@ public static EventLoopGroup newEventLoopGroup( int threadCount ) * * @throws IllegalStateException when current thread is an event loop IO thread. */ - public static void assertNotInEventLoopThread() throws IllegalStateException - { - if ( isEventLoopThread( Thread.currentThread() ) ) - { + public static void assertNotInEventLoopThread() throws IllegalStateException { + if (isEventLoopThread(Thread.currentThread())) { throw new IllegalStateException( - "Blocking operation can't be executed in IO thread because it might result in a deadlock. " + - "Please do not use blocking API when chaining futures returned by async API methods." ); + "Blocking operation can't be executed in IO thread because it might result in a deadlock. " + + "Please do not use blocking API when chaining futures returned by async API methods."); } } @@ -93,8 +84,7 @@ public static void assertNotInEventLoopThread() throws IllegalStateException * @param thread the thread to check. * @return {@code true} when given thread belongs to the event loop, {@code false} otherwise. */ - public static boolean isEventLoopThread( Thread thread ) - { + public static boolean isEventLoopThread(Thread thread) { return thread instanceof DriverThread; } @@ -102,20 +92,15 @@ public static boolean isEventLoopThread( Thread thread ) * Same as {@link NioEventLoopGroup} but uses a different {@link ThreadFactory} that produces threads of * {@link DriverThread} class. Such threads can be recognized by {@link #assertNotInEventLoopThread()}. */ - private static class DriverEventLoopGroup extends NioEventLoopGroup - { - DriverEventLoopGroup() - { - } + private static class DriverEventLoopGroup extends NioEventLoopGroup { + DriverEventLoopGroup() {} - DriverEventLoopGroup( int nThreads ) - { - super( nThreads ); + DriverEventLoopGroup(int nThreads) { + super(nThreads); } @Override - protected ThreadFactory newDefaultThreadFactory() - { + protected ThreadFactory newDefaultThreadFactory() { return new DriverThreadFactory(); } } @@ -124,17 +109,14 @@ protected ThreadFactory newDefaultThreadFactory() * Same as {@link DefaultThreadFactory} created by {@link NioEventLoopGroup} by default, except produces threads of * {@link DriverThread} class. Such threads can be recognized by {@link #assertNotInEventLoopThread()}. */ - private static class DriverThreadFactory extends DefaultThreadFactory - { - DriverThreadFactory() - { - super( THREAD_NAME_PREFIX, THREAD_IS_DAEMON, THREAD_PRIORITY ); + private static class DriverThreadFactory extends DefaultThreadFactory { + DriverThreadFactory() { + super(THREAD_NAME_PREFIX, THREAD_IS_DAEMON, THREAD_PRIORITY); } @Override - protected Thread newThread( Runnable r, String name ) - { - return new DriverThread( threadGroup, r, name ); + protected Thread newThread(Runnable r, String name) { + return new DriverThread(threadGroup, r, name); } } @@ -142,11 +124,9 @@ protected Thread newThread( Runnable r, String name ) * Same as default thread created by {@link DefaultThreadFactory} except this dedicated class can be easily * recognized by {@link #assertNotInEventLoopThread()}. */ - private static class DriverThread extends FastThreadLocalThread - { - DriverThread( ThreadGroup group, Runnable target, String name ) - { - super( group, target, name ); + private static class DriverThread extends FastThreadLocalThread { + DriverThread(ThreadGroup group, Runnable target, String name) { + super(group, target, name); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListener.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListener.java index a65913bed7..2a9f3e5953 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListener.java @@ -18,46 +18,39 @@ */ package org.neo4j.driver.internal.async.connection; +import static java.util.Objects.requireNonNull; + import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPromise; - -import java.util.Map; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.internal.cluster.RoutingContext; import org.neo4j.driver.internal.messaging.BoltProtocol; -import org.neo4j.driver.Value; -import static java.util.Objects.requireNonNull; - -public class HandshakeCompletedListener implements ChannelFutureListener -{ +public class HandshakeCompletedListener implements ChannelFutureListener { private final String userAgent; private final AuthToken authToken; private final RoutingContext routingContext; private final ChannelPromise connectionInitializedPromise; - public HandshakeCompletedListener( String userAgent, AuthToken authToken, - RoutingContext routingContext, ChannelPromise connectionInitializedPromise ) - { - this.userAgent = requireNonNull( userAgent ); - this.authToken = requireNonNull( authToken ); + public HandshakeCompletedListener( + String userAgent, + AuthToken authToken, + RoutingContext routingContext, + ChannelPromise connectionInitializedPromise) { + this.userAgent = requireNonNull(userAgent); + this.authToken = requireNonNull(authToken); this.routingContext = routingContext; - this.connectionInitializedPromise = requireNonNull( connectionInitializedPromise ); + this.connectionInitializedPromise = requireNonNull(connectionInitializedPromise); } @Override - public void operationComplete( ChannelFuture future ) - { - if ( future.isSuccess() ) - { - BoltProtocol protocol = BoltProtocol.forChannel( future.channel() ); - protocol.initializeChannel( userAgent, authToken, routingContext, connectionInitializedPromise ); - } - else - { - connectionInitializedPromise.setFailure( future.cause() ); + public void operationComplete(ChannelFuture future) { + if (future.isSuccess()) { + BoltProtocol protocol = BoltProtocol.forChannel(future.channel()); + protocol.initializeChannel(userAgent, authToken, routingContext, connectionInitializedPromise); + } else { + connectionInitializedPromise.setFailure(future.cause()); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeHandler.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeHandler.java index 6fa8a0244e..6ea0371290 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/HandshakeHandler.java @@ -18,15 +18,16 @@ */ package org.neo4j.driver.internal.async.connection; +import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.NO_PROTOCOL_VERSION; +import static org.neo4j.driver.internal.messaging.BoltProtocolVersion.isHttp; + import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.ReplayingDecoder; - import java.util.List; import javax.net.ssl.SSLHandshakeException; - import org.neo4j.driver.Logging; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.SecurityException; @@ -38,11 +39,7 @@ import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.util.ErrorUtil; -import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.NO_PROTOCOL_VERSION; -import static org.neo4j.driver.internal.messaging.BoltProtocolVersion.isHttp; - -public class HandshakeHandler extends ReplayingDecoder -{ +public class HandshakeHandler extends ReplayingDecoder { private final ChannelPipelineBuilder pipelineBuilder; private final ChannelPromise handshakeCompletedPromise; private final Logging logging; @@ -51,155 +48,120 @@ public class HandshakeHandler extends ReplayingDecoder private ChannelActivityLogger log; private ChannelErrorLogger errorLog; - public HandshakeHandler( ChannelPipelineBuilder pipelineBuilder, ChannelPromise handshakeCompletedPromise, - Logging logging ) - { + public HandshakeHandler( + ChannelPipelineBuilder pipelineBuilder, ChannelPromise handshakeCompletedPromise, Logging logging) { this.pipelineBuilder = pipelineBuilder; this.handshakeCompletedPromise = handshakeCompletedPromise; this.logging = logging; } @Override - public void handlerAdded( ChannelHandlerContext ctx ) - { - log = new ChannelActivityLogger( ctx.channel(), logging, getClass() ); - errorLog = new ChannelErrorLogger( ctx.channel(), logging ); + public void handlerAdded(ChannelHandlerContext ctx) { + log = new ChannelActivityLogger(ctx.channel(), logging, getClass()); + errorLog = new ChannelErrorLogger(ctx.channel(), logging); } @Override - protected void handlerRemoved0( ChannelHandlerContext ctx ) - { + protected void handlerRemoved0(ChannelHandlerContext ctx) { failed = false; log = null; } @Override - public void channelInactive( ChannelHandlerContext ctx ) - { - log.debug( "Channel is inactive" ); + public void channelInactive(ChannelHandlerContext ctx) { + log.debug("Channel is inactive"); - if ( !failed ) - { + if (!failed) { // channel became inactive while doing bolt handshake, not because of some previous error ServiceUnavailableException error = ErrorUtil.newConnectionTerminatedError(); - fail( ctx, error ); + fail(ctx, error); } } @Override - public void exceptionCaught( ChannelHandlerContext ctx, Throwable error ) - { - if ( failed ) - { - errorLog.traceOrDebug( "Another fatal error occurred in the pipeline", error ); - } - else - { + public void exceptionCaught(ChannelHandlerContext ctx, Throwable error) { + if (failed) { + errorLog.traceOrDebug("Another fatal error occurred in the pipeline", error); + } else { failed = true; - Throwable cause = transformError( error ); - fail( ctx, cause ); + Throwable cause = transformError(error); + fail(ctx, cause); } } @Override - protected void decode( ChannelHandlerContext ctx, ByteBuf in, List out ) - { - BoltProtocolVersion serverSuggestedVersion = BoltProtocolVersion.fromRawBytes( in.readInt() ); - log.debug( "S: [Bolt Handshake] %s", serverSuggestedVersion ); + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + BoltProtocolVersion serverSuggestedVersion = BoltProtocolVersion.fromRawBytes(in.readInt()); + log.debug("S: [Bolt Handshake] %s", serverSuggestedVersion); // this is a one-time handler, remove it when protocol version has been read - ctx.pipeline().remove( this ); + ctx.pipeline().remove(this); - BoltProtocol protocol = protocolForVersion( serverSuggestedVersion ); - if ( protocol != null ) - { - protocolSelected( serverSuggestedVersion, protocol.createMessageFormat(), ctx ); - } - else - { - handleUnknownSuggestedProtocolVersion( serverSuggestedVersion, ctx ); + BoltProtocol protocol = protocolForVersion(serverSuggestedVersion); + if (protocol != null) { + protocolSelected(serverSuggestedVersion, protocol.createMessageFormat(), ctx); + } else { + handleUnknownSuggestedProtocolVersion(serverSuggestedVersion, ctx); } } - private BoltProtocol protocolForVersion( BoltProtocolVersion version ) - { - try - { - return BoltProtocol.forVersion( version ); - } - catch ( ClientException e ) - { + private BoltProtocol protocolForVersion(BoltProtocolVersion version) { + try { + return BoltProtocol.forVersion(version); + } catch (ClientException e) { return null; } } - private void protocolSelected( BoltProtocolVersion version, MessageFormat messageFormat, ChannelHandlerContext ctx ) - { - ChannelAttributes.setProtocolVersion( ctx.channel(), version ); - pipelineBuilder.build( messageFormat, ctx.pipeline(), logging ); + private void protocolSelected(BoltProtocolVersion version, MessageFormat messageFormat, ChannelHandlerContext ctx) { + ChannelAttributes.setProtocolVersion(ctx.channel(), version); + pipelineBuilder.build(messageFormat, ctx.pipeline(), logging); handshakeCompletedPromise.setSuccess(); } - private void handleUnknownSuggestedProtocolVersion( BoltProtocolVersion version, ChannelHandlerContext ctx ) - { - if ( NO_PROTOCOL_VERSION.equals( version ) ) - { - fail( ctx, protocolNoSupportedByServerError() ); - } - else if ( isHttp( version ) ) - { - fail( ctx, httpEndpointError() ); - } - else - { - fail( ctx, protocolNoSupportedByDriverError( version ) ); + private void handleUnknownSuggestedProtocolVersion(BoltProtocolVersion version, ChannelHandlerContext ctx) { + if (NO_PROTOCOL_VERSION.equals(version)) { + fail(ctx, protocolNoSupportedByServerError()); + } else if (isHttp(version)) { + fail(ctx, httpEndpointError()); + } else { + fail(ctx, protocolNoSupportedByDriverError(version)); } } - private void fail( ChannelHandlerContext ctx, Throwable error ) - { - ctx.close().addListener( future -> handshakeCompletedPromise.tryFailure( error ) ); + private void fail(ChannelHandlerContext ctx, Throwable error) { + ctx.close().addListener(future -> handshakeCompletedPromise.tryFailure(error)); } - private static Throwable protocolNoSupportedByServerError() - { - return new ClientException( "The server does not support any of the protocol versions supported by " + - "this driver. Ensure that you are using driver and server versions that " + - "are compatible with one another." ); + private static Throwable protocolNoSupportedByServerError() { + return new ClientException("The server does not support any of the protocol versions supported by " + + "this driver. Ensure that you are using driver and server versions that " + + "are compatible with one another."); } - private static Throwable httpEndpointError() - { + private static Throwable httpEndpointError() { return new ClientException( - "Server responded HTTP. Make sure you are not trying to connect to the http endpoint " + - "(HTTP defaults to port 7474 whereas BOLT defaults to port 7687)" ); + "Server responded HTTP. Make sure you are not trying to connect to the http endpoint " + + "(HTTP defaults to port 7474 whereas BOLT defaults to port 7687)"); } - private static Throwable protocolNoSupportedByDriverError( BoltProtocolVersion suggestedProtocolVersion ) - { + private static Throwable protocolNoSupportedByDriverError(BoltProtocolVersion suggestedProtocolVersion) { return new ClientException( - "Protocol error, server suggested unexpected protocol version: " + suggestedProtocolVersion ); + "Protocol error, server suggested unexpected protocol version: " + suggestedProtocolVersion); } - private static Throwable transformError( Throwable error ) - { - if ( error instanceof DecoderException && error.getCause() != null ) - { + private static Throwable transformError(Throwable error) { + if (error instanceof DecoderException && error.getCause() != null) { // unwrap the DecoderException if it has a cause error = error.getCause(); } - if ( error instanceof ServiceUnavailableException ) - { + if (error instanceof ServiceUnavailableException) { return error; - } - else if ( error instanceof SSLHandshakeException ) - { - return new SecurityException( "Failed to establish secured connection with the server", error ); - } - else - { - return new ServiceUnavailableException( "Failed to establish connection with the server", error ); + } else if (error instanceof SSLHandshakeException) { + return new SecurityException("Failed to establish secured connection with the server", error); + } else { + return new ServiceUnavailableException("Failed to establish connection with the server", error); } } } 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 72476ae570..0bb96e5e59 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 @@ -18,35 +18,35 @@ */ package org.neo4j.driver.internal.async.connection; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setCreationTimestamp; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerAddress; + import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.handler.ssl.SslHandler; - import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters; - +import org.neo4j.driver.Logging; 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; -import org.neo4j.driver.Logging; - -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setCreationTimestamp; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerAddress; -public class NettyChannelInitializer extends ChannelInitializer -{ +public class NettyChannelInitializer extends ChannelInitializer { private final BoltServerAddress address; private final SecurityPlan securityPlan; private final int connectTimeoutMillis; private final Clock clock; private final Logging logging; - public NettyChannelInitializer( BoltServerAddress address, SecurityPlan securityPlan, int connectTimeoutMillis, - Clock clock, Logging logging ) - { + public NettyChannelInitializer( + BoltServerAddress address, + SecurityPlan securityPlan, + int connectTimeoutMillis, + Clock clock, + Logging logging) { this.address = address; this.securityPlan = securityPlan; this.connectTimeoutMillis = connectTimeoutMillis; @@ -55,43 +55,37 @@ public NettyChannelInitializer( BoltServerAddress address, SecurityPlan security } @Override - protected void initChannel( Channel channel ) - { - if ( securityPlan.requiresEncryption() ) - { + protected void initChannel(Channel channel) { + if (securityPlan.requiresEncryption()) { SslHandler sslHandler = createSslHandler(); - channel.pipeline().addFirst( sslHandler ); + channel.pipeline().addFirst(sslHandler); } - updateChannelAttributes( channel ); + updateChannelAttributes(channel); } - private SslHandler createSslHandler() - { + private SslHandler createSslHandler() { SSLEngine sslEngine = createSslEngine(); - SslHandler sslHandler = new SslHandler( sslEngine ); - sslHandler.setHandshakeTimeoutMillis( connectTimeoutMillis ); + SslHandler sslHandler = new SslHandler(sslEngine); + sslHandler.setHandshakeTimeoutMillis(connectTimeoutMillis); return sslHandler; } - private SSLEngine createSslEngine() - { + private SSLEngine createSslEngine() { SSLContext sslContext = securityPlan.sslContext(); - SSLEngine sslEngine = sslContext.createSSLEngine( address.host(), address.port() ); - sslEngine.setUseClientMode( true ); - if ( securityPlan.requiresHostnameVerification() ) - { + SSLEngine sslEngine = sslContext.createSSLEngine(address.host(), address.port()); + sslEngine.setUseClientMode(true); + if (securityPlan.requiresHostnameVerification()) { SSLParameters sslParameters = sslEngine.getSSLParameters(); - sslParameters.setEndpointIdentificationAlgorithm( "HTTPS" ); - sslEngine.setSSLParameters( sslParameters ); + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslEngine.setSSLParameters(sslParameters); } return sslEngine; } - private void updateChannelAttributes( Channel channel ) - { - setServerAddress( channel, address ); - setCreationTimestamp( channel, clock.millis() ); - setMessageDispatcher( channel, new InboundMessageDispatcher( channel, logging ) ); + private void updateChannelAttributes(Channel channel) { + setServerAddress(channel, address); + setCreationTimestamp(channel, clock.millis()); + setMessageDispatcher(channel, new InboundMessageDispatcher(channel, logging)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyDomainNameResolver.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyDomainNameResolver.java index 87351e252b..3bbdb3c95c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyDomainNameResolver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyDomainNameResolver.java @@ -21,47 +21,35 @@ import io.netty.resolver.InetNameResolver; import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.Promise; - import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.List; - import org.neo4j.driver.internal.DomainNameResolver; -public class NettyDomainNameResolver extends InetNameResolver -{ +public class NettyDomainNameResolver extends InetNameResolver { private final DomainNameResolver domainNameResolver; - public NettyDomainNameResolver( EventExecutor executor, DomainNameResolver domainNameResolver ) - { - super( executor ); + public NettyDomainNameResolver(EventExecutor executor, DomainNameResolver domainNameResolver) { + super(executor); this.domainNameResolver = domainNameResolver; } @Override - protected void doResolve( String inetHost, Promise promise ) - { - try - { - promise.setSuccess( domainNameResolver.resolve( inetHost )[0] ); - } - catch ( UnknownHostException e ) - { - promise.setFailure( e ); + protected void doResolve(String inetHost, Promise promise) { + try { + promise.setSuccess(domainNameResolver.resolve(inetHost)[0]); + } catch (UnknownHostException e) { + promise.setFailure(e); } } @Override - protected void doResolveAll( String inetHost, Promise> promise ) - { - try - { - promise.setSuccess( Arrays.asList( domainNameResolver.resolve( inetHost ) ) ); - } - catch ( UnknownHostException e ) - { - promise.setFailure( e ); + protected void doResolveAll(String inetHost, Promise> promise) { + try { + promise.setSuccess(Arrays.asList(domainNameResolver.resolve(inetHost))); + } catch (UnknownHostException e) { + promise.setFailure(e); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyDomainNameResolverGroup.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyDomainNameResolverGroup.java index 720e213be6..2afdd25a21 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyDomainNameResolverGroup.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/NettyDomainNameResolverGroup.java @@ -21,23 +21,18 @@ import io.netty.resolver.AddressResolver; import io.netty.resolver.AddressResolverGroup; import io.netty.util.concurrent.EventExecutor; - import java.net.InetSocketAddress; - import org.neo4j.driver.internal.DomainNameResolver; -public class NettyDomainNameResolverGroup extends AddressResolverGroup -{ +public class NettyDomainNameResolverGroup extends AddressResolverGroup { private final DomainNameResolver domainNameResolver; - public NettyDomainNameResolverGroup( DomainNameResolver domainNameResolver ) - { + public NettyDomainNameResolverGroup(DomainNameResolver domainNameResolver) { this.domainNameResolver = domainNameResolver; } @Override - protected AddressResolver newResolver( EventExecutor executor ) throws Exception - { - return new NettyDomainNameResolver( executor, domainNameResolver ).asAddressResolver(); + protected AddressResolver newResolver(EventExecutor executor) throws Exception { + return new NettyDomainNameResolver(executor, domainNameResolver).asAddressResolver(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/connection/RoutingConnection.java b/driver/src/main/java/org/neo4j/driver/internal/async/connection/RoutingConnection.java index 9735a6382e..e0e84d5600 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/connection/RoutingConnection.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/connection/RoutingConnection.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.async.connection; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DatabaseName; @@ -34,16 +33,19 @@ /** * A connection used by the routing driver. */ -public class RoutingConnection implements Connection -{ +public class RoutingConnection implements Connection { private final Connection delegate; private final AccessMode accessMode; private final RoutingErrorHandler errorHandler; private final DatabaseName databaseName; private final String impersonatedUser; - public RoutingConnection( Connection delegate, DatabaseName databaseName, AccessMode accessMode, String impersonatedUser, RoutingErrorHandler errorHandler ) - { + public RoutingConnection( + Connection delegate, + DatabaseName databaseName, + AccessMode accessMode, + String impersonatedUser, + RoutingErrorHandler errorHandler) { this.delegate = delegate; this.databaseName = databaseName; this.accessMode = accessMode; @@ -52,115 +54,97 @@ public RoutingConnection( Connection delegate, DatabaseName databaseName, Access } @Override - public void enableAutoRead() - { + public void enableAutoRead() { delegate.enableAutoRead(); } @Override - public void disableAutoRead() - { + public void disableAutoRead() { delegate.disableAutoRead(); } @Override - public void write( Message message, ResponseHandler handler ) - { - delegate.write( message, newRoutingResponseHandler( handler ) ); + public void write(Message message, ResponseHandler handler) { + delegate.write(message, newRoutingResponseHandler(handler)); } @Override - public void write( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ) - { - delegate.write( message1, newRoutingResponseHandler( handler1 ), message2, newRoutingResponseHandler( handler2 ) ); + public void write(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2) { + delegate.write(message1, newRoutingResponseHandler(handler1), message2, newRoutingResponseHandler(handler2)); } @Override - public void writeAndFlush( Message message, ResponseHandler handler ) - { - delegate.writeAndFlush( message, newRoutingResponseHandler( handler ) ); + public void writeAndFlush(Message message, ResponseHandler handler) { + delegate.writeAndFlush(message, newRoutingResponseHandler(handler)); } @Override - public void writeAndFlush( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ) - { - delegate.writeAndFlush( message1, newRoutingResponseHandler( handler1 ), message2, newRoutingResponseHandler( handler2 ) ); + public void writeAndFlush(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2) { + delegate.writeAndFlush( + message1, newRoutingResponseHandler(handler1), message2, newRoutingResponseHandler(handler2)); } @Override - public CompletionStage reset() - { + public CompletionStage reset() { return delegate.reset(); } @Override - public boolean isOpen() - { + public boolean isOpen() { return delegate.isOpen(); } @Override - public CompletionStage release() - { + public CompletionStage release() { return delegate.release(); } @Override - public void terminateAndRelease( String reason ) - { - delegate.terminateAndRelease( reason ); + public void terminateAndRelease(String reason) { + delegate.terminateAndRelease(reason); } @Override - public String serverAgent() - { + public String serverAgent() { return delegate.serverAgent(); } @Override - public BoltServerAddress serverAddress() - { + public BoltServerAddress serverAddress() { return delegate.serverAddress(); } @Override - public ServerVersion serverVersion() - { + public ServerVersion serverVersion() { return delegate.serverVersion(); } @Override - public BoltProtocol protocol() - { + public BoltProtocol protocol() { return delegate.protocol(); } @Override - public void flush() - { + public void flush() { delegate.flush(); } @Override - public AccessMode mode() - { + public AccessMode mode() { return this.accessMode; } @Override - public DatabaseName databaseName() - { + public DatabaseName databaseName() { return this.databaseName; } @Override - public String impersonatedUser() - { + public String impersonatedUser() { return impersonatedUser; } - private RoutingResponseHandler newRoutingResponseHandler( ResponseHandler handler ) - { - return new RoutingResponseHandler( handler, serverAddress(), accessMode, errorHandler ); + private RoutingResponseHandler newRoutingResponseHandler(ResponseHandler handler) { + return new RoutingResponseHandler(handler, serverAddress(), accessMode, errorHandler); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ByteBufInput.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ByteBufInput.java index 6d955d7d70..0a1c15809d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ByteBufInput.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ByteBufInput.java @@ -18,74 +18,61 @@ */ package org.neo4j.driver.internal.async.inbound; -import io.netty.buffer.ByteBuf; +import static java.util.Objects.requireNonNull; +import io.netty.buffer.ByteBuf; import org.neo4j.driver.internal.packstream.PackInput; -import static java.util.Objects.requireNonNull; - -public class ByteBufInput implements PackInput -{ +public class ByteBufInput implements PackInput { private ByteBuf buf; - public void start( ByteBuf newBuf ) - { + public void start(ByteBuf newBuf) { assertNotStarted(); - buf = requireNonNull( newBuf ); + buf = requireNonNull(newBuf); } - public void stop() - { + public void stop() { buf = null; } @Override - public byte readByte() - { + public byte readByte() { return buf.readByte(); } @Override - public short readShort() - { + public short readShort() { return buf.readShort(); } @Override - public int readInt() - { + public int readInt() { return buf.readInt(); } @Override - public long readLong() - { + public long readLong() { return buf.readLong(); } @Override - public double readDouble() - { + public double readDouble() { return buf.readDouble(); } @Override - public void readBytes( byte[] into, int offset, int toRead ) - { - buf.readBytes( into, offset, toRead ); + public void readBytes(byte[] into, int offset, int toRead) { + buf.readBytes(into, offset, toRead); } @Override - public byte peekByte() - { - return buf.getByte( buf.readerIndex() ); + public byte peekByte() { + return buf.getByte(buf.readerIndex()); } - private void assertNotStarted() - { - if ( buf != null ) - { - throw new IllegalStateException( "Already started" ); + private void assertNotStarted() { + if (buf != null) { + throw new IllegalStateException("Already started"); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChannelErrorHandler.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChannelErrorHandler.java index 1a6de004c0..99d0d4e306 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChannelErrorHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChannelErrorHandler.java @@ -18,12 +18,14 @@ */ package org.neo4j.driver.internal.async.inbound; +import static java.util.Objects.requireNonNull; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.terminationReason; + import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.CodecException; - import java.io.IOException; - import org.neo4j.driver.Logging; import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; import org.neo4j.driver.exceptions.ServiceUnavailableException; @@ -31,12 +33,7 @@ import org.neo4j.driver.internal.logging.ChannelErrorLogger; import org.neo4j.driver.internal.util.ErrorUtil; -import static java.util.Objects.requireNonNull; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.terminationReason; - -public class ChannelErrorHandler extends ChannelInboundHandlerAdapter -{ +public class ChannelErrorHandler extends ChannelInboundHandlerAdapter { private final Logging logging; private InboundMessageDispatcher messageDispatcher; @@ -44,92 +41,73 @@ public class ChannelErrorHandler extends ChannelInboundHandlerAdapter private ChannelErrorLogger errorLog; private boolean failed; - public ChannelErrorHandler( Logging logging ) - { + public ChannelErrorHandler(Logging logging) { this.logging = logging; } @Override - public void handlerAdded( ChannelHandlerContext ctx ) - { - messageDispatcher = requireNonNull( messageDispatcher( ctx.channel() ) ); - log = new ChannelActivityLogger( ctx.channel(), logging, getClass() ); - errorLog = new ChannelErrorLogger( ctx.channel(), logging ); + public void handlerAdded(ChannelHandlerContext ctx) { + messageDispatcher = requireNonNull(messageDispatcher(ctx.channel())); + log = new ChannelActivityLogger(ctx.channel(), logging, getClass()); + errorLog = new ChannelErrorLogger(ctx.channel(), logging); } @Override - public void handlerRemoved( ChannelHandlerContext ctx ) - { + public void handlerRemoved(ChannelHandlerContext ctx) { messageDispatcher = null; log = null; failed = false; } @Override - public void channelInactive( ChannelHandlerContext ctx ) - { - log.debug( "Channel is inactive" ); + public void channelInactive(ChannelHandlerContext ctx) { + log.debug("Channel is inactive"); - String terminationReason = terminationReason( ctx.channel() ); - Throwable error = ErrorUtil.newConnectionTerminatedError( terminationReason ); + String terminationReason = terminationReason(ctx.channel()); + Throwable error = ErrorUtil.newConnectionTerminatedError(terminationReason); - if ( !failed ) - { + if (!failed) { // channel became inactive not because of a fatal exception that came from exceptionCaught // it is most likely inactive because actual network connection broke or was explicitly closed by the driver - messageDispatcher.handleChannelInactive( error ); + messageDispatcher.handleChannelInactive(error); ctx.channel().close(); - } - else - { - fail( error ); + } else { + fail(error); } } @Override - public void exceptionCaught( ChannelHandlerContext ctx, Throwable error ) - { - if ( failed ) - { - errorLog.traceOrDebug( "Another fatal error occurred in the pipeline", error ); - } - else - { + public void exceptionCaught(ChannelHandlerContext ctx, Throwable error) { + if (failed) { + errorLog.traceOrDebug("Another fatal error occurred in the pipeline", error); + } else { failed = true; - logUnexpectedErrorWarning( error ); - fail( error ); + logUnexpectedErrorWarning(error); + fail(error); } } - private void logUnexpectedErrorWarning( Throwable error ) - { - if ( !(error instanceof ConnectionReadTimeoutException) ) - { - errorLog.traceOrDebug( "Fatal error occurred in the pipeline", error ); + private void logUnexpectedErrorWarning(Throwable error) { + if (!(error instanceof ConnectionReadTimeoutException)) { + errorLog.traceOrDebug("Fatal error occurred in the pipeline", error); } } - private void fail( Throwable error ) - { - Throwable cause = transformError( error ); - messageDispatcher.handleChannelError( cause ); + private void fail(Throwable error) { + Throwable cause = transformError(error); + messageDispatcher.handleChannelError(cause); } - private static Throwable transformError( Throwable error ) - { - if ( error instanceof CodecException && error.getCause() != null ) - { + private static Throwable transformError(Throwable error) { + if (error instanceof CodecException && error.getCause() != null) { // unwrap the CodecException if it has a cause error = error.getCause(); } - if ( error instanceof IOException ) - { - return new ServiceUnavailableException( "Connection to the database failed", error ); - } - else - { + if (error instanceof IOException) { + return new ServiceUnavailableException("Connection to the database failed", error); + } else { return error; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChunkDecoder.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChunkDecoder.java index 8482ab68d4..57085f168a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChunkDecoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChunkDecoder.java @@ -22,13 +22,11 @@ import io.netty.buffer.ByteBufUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; - -import org.neo4j.driver.internal.logging.ChannelActivityLogger; import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; +import org.neo4j.driver.internal.logging.ChannelActivityLogger; -public class ChunkDecoder extends LengthFieldBasedFrameDecoder -{ +public class ChunkDecoder extends LengthFieldBasedFrameDecoder { private static final int MAX_FRAME_BODY_LENGTH = 0xFFFF; private static final int LENGTH_FIELD_OFFSET = 0; private static final int LENGTH_FIELD_LENGTH = 2; @@ -39,35 +37,30 @@ public class ChunkDecoder extends LengthFieldBasedFrameDecoder private final Logging logging; private Logger log; - public ChunkDecoder( Logging logging ) - { - super( MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, LENGTH_ADJUSTMENT, INITIAL_BYTES_TO_STRIP ); + public ChunkDecoder(Logging logging) { + super(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, LENGTH_ADJUSTMENT, INITIAL_BYTES_TO_STRIP); this.logging = logging; } @Override - public void handlerAdded( ChannelHandlerContext ctx ) - { - log = new ChannelActivityLogger( ctx.channel(), logging, getClass() ); + public void handlerAdded(ChannelHandlerContext ctx) { + log = new ChannelActivityLogger(ctx.channel(), logging, getClass()); } @Override - protected void handlerRemoved0( ChannelHandlerContext ctx ) - { + protected void handlerRemoved0(ChannelHandlerContext ctx) { log = null; } @Override - protected ByteBuf extractFrame( ChannelHandlerContext ctx, ByteBuf buffer, int index, int length ) - { - if ( log.isTraceEnabled() ) - { + protected ByteBuf extractFrame(ChannelHandlerContext ctx, ByteBuf buffer, int index, int length) { + if (log.isTraceEnabled()) { int originalReaderIndex = buffer.readerIndex(); int readerIndexWithChunkHeader = originalReaderIndex - INITIAL_BYTES_TO_STRIP; int lengthWithChunkHeader = INITIAL_BYTES_TO_STRIP + length; - String hexDump = ByteBufUtil.hexDump( buffer, readerIndexWithChunkHeader, lengthWithChunkHeader ); - log.trace( "S: %s", hexDump ); + String hexDump = ByteBufUtil.hexDump(buffer, readerIndexWithChunkHeader, lengthWithChunkHeader); + log.trace("S: %s", hexDump); } - return super.extractFrame( ctx, buffer, index, length ); + return super.extractFrame(ctx, buffer, index, length); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ConnectTimeoutHandler.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ConnectTimeoutHandler.java index b9efbc471e..8901441508 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ConnectTimeoutHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ConnectTimeoutHandler.java @@ -20,9 +20,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.timeout.ReadTimeoutHandler; - import java.util.concurrent.TimeUnit; - import org.neo4j.driver.exceptions.ServiceUnavailableException; /** @@ -30,29 +28,24 @@ * It should only be used when connection is established and removed from the pipeline afterwards. * Otherwise it will make long running queries fail. */ -public class ConnectTimeoutHandler extends ReadTimeoutHandler -{ +public class ConnectTimeoutHandler extends ReadTimeoutHandler { private final long timeoutMillis; private boolean triggered; - public ConnectTimeoutHandler( long timeoutMillis ) - { - super( timeoutMillis, TimeUnit.MILLISECONDS ); + public ConnectTimeoutHandler(long timeoutMillis) { + super(timeoutMillis, TimeUnit.MILLISECONDS); this.timeoutMillis = timeoutMillis; } @Override - protected void readTimedOut( ChannelHandlerContext ctx ) - { - if ( !triggered ) - { + protected void readTimedOut(ChannelHandlerContext ctx) { + if (!triggered) { triggered = true; - ctx.fireExceptionCaught( unableToConnectError() ); + ctx.fireExceptionCaught(unableToConnectError()); } } - private ServiceUnavailableException unableToConnectError() - { - return new ServiceUnavailableException( "Unable to establish connection in " + timeoutMillis + "ms" ); + private ServiceUnavailableException unableToConnectError() { + return new ServiceUnavailableException("Unable to establish connection in " + timeoutMillis + "ms"); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ConnectionReadTimeoutHandler.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ConnectionReadTimeoutHandler.java index 81ece4335a..10de16d39f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ConnectionReadTimeoutHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ConnectionReadTimeoutHandler.java @@ -20,26 +20,20 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.timeout.ReadTimeoutHandler; - import java.util.concurrent.TimeUnit; - import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; -public class ConnectionReadTimeoutHandler extends ReadTimeoutHandler -{ +public class ConnectionReadTimeoutHandler extends ReadTimeoutHandler { private boolean triggered; - public ConnectionReadTimeoutHandler( long timeout, TimeUnit unit ) - { - super( timeout, unit ); + public ConnectionReadTimeoutHandler(long timeout, TimeUnit unit) { + super(timeout, unit); } @Override - protected void readTimedOut( ChannelHandlerContext ctx ) - { - if ( !triggered ) - { - ctx.fireExceptionCaught( ConnectionReadTimeoutException.INSTANCE ); + protected void readTimedOut(ChannelHandlerContext ctx) { + if (!triggered) { + ctx.fireExceptionCaught(ConnectionReadTimeoutException.INSTANCE); ctx.close(); triggered = true; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcher.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcher.java index 6b958b4e73..8f5e71470a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcher.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcher.java @@ -18,13 +18,16 @@ */ package org.neo4j.driver.internal.async.inbound; -import io.netty.channel.Channel; +import static java.util.Objects.requireNonNull; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.authorizationStateListener; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; +import static org.neo4j.driver.internal.util.ErrorUtil.addSuppressed; +import io.netty.channel.Channel; import java.util.Arrays; import java.util.LinkedList; import java.util.Map; import java.util.Queue; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.Value; @@ -37,13 +40,7 @@ import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.internal.util.ErrorUtil; -import static java.util.Objects.requireNonNull; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.authorizationStateListener; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; -import static org.neo4j.driver.internal.util.ErrorUtil.addSuppressed; - -public class InboundMessageDispatcher implements ResponseMessageHandler -{ +public class InboundMessageDispatcher implements ResponseMessageHandler { private final Channel channel; private final Queue handlers = new LinkedList<>(); private final Logger log; @@ -56,244 +53,201 @@ public class InboundMessageDispatcher implements ResponseMessageHandler private ResponseHandler autoReadManagingHandler; - public InboundMessageDispatcher( Channel channel, Logging logging ) - { - this.channel = requireNonNull( channel ); - this.log = new ChannelActivityLogger( channel, logging, getClass() ); - this.errorLog = new ChannelErrorLogger( channel, logging ); + public InboundMessageDispatcher(Channel channel, Logging logging) { + this.channel = requireNonNull(channel); + this.log = new ChannelActivityLogger(channel, logging, getClass()); + this.errorLog = new ChannelErrorLogger(channel, logging); } - public void enqueue( ResponseHandler handler ) - { - if ( fatalErrorOccurred ) - { - handler.onFailure( currentError ); - } - else - { - handlers.add( handler ); - updateAutoReadManagingHandlerIfNeeded( handler ); + public void enqueue(ResponseHandler handler) { + if (fatalErrorOccurred) { + handler.onFailure(currentError); + } else { + handlers.add(handler); + updateAutoReadManagingHandlerIfNeeded(handler); } } - public void setBeforeLastHandlerHook( HandlerHook beforeLastHandlerHook ) - { - if ( !channel.eventLoop().inEventLoop() ) - { - throw new IllegalStateException( "This method may only be called in the EventLoop" ); + public void setBeforeLastHandlerHook(HandlerHook beforeLastHandlerHook) { + if (!channel.eventLoop().inEventLoop()) { + throw new IllegalStateException("This method may only be called in the EventLoop"); } this.beforeLastHandlerHook = beforeLastHandlerHook; } - public int queuedHandlersCount() - { + public int queuedHandlersCount() { return handlers.size(); } @Override - public void handleSuccessMessage( Map meta ) - { - log.debug( "S: SUCCESS %s", meta ); - invokeBeforeLastHandlerHook( HandlerHook.MessageType.SUCCESS ); + public void handleSuccessMessage(Map meta) { + log.debug("S: SUCCESS %s", meta); + invokeBeforeLastHandlerHook(HandlerHook.MessageType.SUCCESS); ResponseHandler handler = removeHandler(); - handler.onSuccess( meta ); + handler.onSuccess(meta); } @Override - public void handleRecordMessage( Value[] fields ) - { - if ( log.isDebugEnabled() ) - { - log.debug( "S: RECORD %s", Arrays.toString( fields ) ); + public void handleRecordMessage(Value[] fields) { + if (log.isDebugEnabled()) { + log.debug("S: RECORD %s", Arrays.toString(fields)); } ResponseHandler handler = handlers.peek(); - if ( handler == null ) - { - throw new IllegalStateException( "No handler exists to handle RECORD message with fields: " + Arrays.toString( fields ) ); + if (handler == null) { + throw new IllegalStateException( + "No handler exists to handle RECORD message with fields: " + Arrays.toString(fields)); } - handler.onRecord( fields ); + handler.onRecord(fields); } @Override - public void handleFailureMessage( String code, String message ) - { - log.debug( "S: FAILURE %s \"%s\"", code, message ); + public void handleFailureMessage(String code, String message) { + log.debug("S: FAILURE %s \"%s\"", code, message); - currentError = ErrorUtil.newNeo4jError( code, message ); + currentError = ErrorUtil.newNeo4jError(code, message); - if ( ErrorUtil.isFatal( currentError ) ) - { + if (ErrorUtil.isFatal(currentError)) { // we should not continue using channel after a fatal error // fire error event back to the pipeline and avoid sending RESET - channel.pipeline().fireExceptionCaught( currentError ); + channel.pipeline().fireExceptionCaught(currentError); return; } Throwable currentError = this.currentError; - if ( currentError instanceof AuthorizationExpiredException ) - { - authorizationStateListener( channel ).onExpired( (AuthorizationExpiredException) currentError, channel ); - } - else - { + if (currentError instanceof AuthorizationExpiredException) { + authorizationStateListener(channel).onExpired((AuthorizationExpiredException) currentError, channel); + } else { // write a RESET to "acknowledge" the failure - enqueue( new ResetResponseHandler( this ) ); - channel.writeAndFlush( RESET, channel.voidPromise() ); + enqueue(new ResetResponseHandler(this)); + channel.writeAndFlush(RESET, channel.voidPromise()); } - invokeBeforeLastHandlerHook( HandlerHook.MessageType.FAILURE ); + invokeBeforeLastHandlerHook(HandlerHook.MessageType.FAILURE); ResponseHandler handler = removeHandler(); - handler.onFailure( currentError ); + handler.onFailure(currentError); } @Override - public void handleIgnoredMessage() - { - log.debug( "S: IGNORED" ); + public void handleIgnoredMessage() { + log.debug("S: IGNORED"); ResponseHandler handler = removeHandler(); Throwable error; - if ( currentError != null ) - { + if (currentError != null) { error = currentError; - } - else - { - log.warn( "Received IGNORED message for handler %s but error is missing and RESET is not in progress. " + - "Current handlers %s", handler, handlers ); + } else { + log.warn( + "Received IGNORED message for handler %s but error is missing and RESET is not in progress. " + + "Current handlers %s", + handler, handlers); - error = new ClientException( "Database ignored the request" ); + error = new ClientException("Database ignored the request"); } - handler.onFailure( error ); + handler.onFailure(error); } - public void handleChannelInactive( Throwable cause ) - { + public void handleChannelInactive(Throwable cause) { // report issue if the connection has not been terminated as a result of a graceful shutdown request from its // parent pool - if ( !gracefullyClosed ) - { - handleChannelError( cause ); - } - else - { + if (!gracefullyClosed) { + handleChannelError(cause); + } else { channel.close(); } } - public void handleChannelError( Throwable error ) - { - if ( currentError != null ) - { - // we already have an error, this new error probably is caused by the existing one, thus we chain the new error on this current error - addSuppressed( currentError, error ); - } - else - { + public void handleChannelError(Throwable error) { + if (currentError != null) { + // we already have an error, this new error probably is caused by the existing one, thus we chain the new + // error on this current error + addSuppressed(currentError, error); + } else { currentError = error; } fatalErrorOccurred = true; - while ( !handlers.isEmpty() ) - { + while (!handlers.isEmpty()) { ResponseHandler handler = removeHandler(); - handler.onFailure( currentError ); + handler.onFailure(currentError); } - errorLog.traceOrDebug( "Closing channel because of a failure", error ); + errorLog.traceOrDebug("Closing channel because of a failure", error); channel.close(); } - public void clearCurrentError() - { + public void clearCurrentError() { currentError = null; } - public Throwable currentError() - { + public Throwable currentError() { return currentError; } - public boolean fatalErrorOccurred() - { + public boolean fatalErrorOccurred() { return fatalErrorOccurred; } - public void prepareToCloseChannel( ) - { + public void prepareToCloseChannel() { this.gracefullyClosed = true; } /** * Visible for testing */ - ResponseHandler autoReadManagingHandler() - { + ResponseHandler autoReadManagingHandler() { return autoReadManagingHandler; } - private ResponseHandler removeHandler() - { + private ResponseHandler removeHandler() { ResponseHandler handler = handlers.remove(); - if ( handler == autoReadManagingHandler ) - { + if (handler == autoReadManagingHandler) { // the auto-read managing handler is being removed // make sure this dispatcher does not hold on to a removed handler - updateAutoReadManagingHandler( null ); + updateAutoReadManagingHandler(null); } return handler; } - private void updateAutoReadManagingHandlerIfNeeded( ResponseHandler handler ) - { - if ( handler.canManageAutoRead() ) - { - updateAutoReadManagingHandler( handler ); + private void updateAutoReadManagingHandlerIfNeeded(ResponseHandler handler) { + if (handler.canManageAutoRead()) { + updateAutoReadManagingHandler(handler); } } - private void updateAutoReadManagingHandler( ResponseHandler newHandler ) - { - if ( autoReadManagingHandler != null ) - { + private void updateAutoReadManagingHandler(ResponseHandler newHandler) { + if (autoReadManagingHandler != null) { // there already exists a handler that manages channel's auto-read // make it stop because new managing handler is being added and there should only be a single such handler autoReadManagingHandler.disableAutoReadManagement(); // restore the default value of auto-read - channel.config().setAutoRead( true ); + channel.config().setAutoRead(true); } autoReadManagingHandler = newHandler; } - private void invokeBeforeLastHandlerHook( HandlerHook.MessageType messageType ) - { - if ( handlers.size() == 1 && beforeLastHandlerHook != null ) - { - beforeLastHandlerHook.run( messageType ); + private void invokeBeforeLastHandlerHook(HandlerHook.MessageType messageType) { + if (handlers.size() == 1 && beforeLastHandlerHook != null) { + beforeLastHandlerHook.run(messageType); } } - public interface HandlerHook - { - enum MessageType - { + public interface HandlerHook { + enum MessageType { SUCCESS, FAILURE } - void run( MessageType messageType ); + void run(MessageType messageType); } // For testing only - Logger getLog() - { + Logger getLog() { return log; } // For testing only - Logger getErrorLog() - { + Logger getErrorLog() { return errorLog; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageHandler.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageHandler.java index bfbd46b96b..4307d01db2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/InboundMessageHandler.java @@ -18,22 +18,20 @@ */ package org.neo4j.driver.internal.async.inbound; +import static io.netty.buffer.ByteBufUtil.hexDump; +import static java.util.Objects.requireNonNull; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; + import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.DecoderException; - -import org.neo4j.driver.internal.logging.ChannelActivityLogger; -import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; +import org.neo4j.driver.internal.logging.ChannelActivityLogger; +import org.neo4j.driver.internal.messaging.MessageFormat; -import static io.netty.buffer.ByteBufUtil.hexDump; -import static java.util.Objects.requireNonNull; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; - -public class InboundMessageHandler extends SimpleChannelInboundHandler -{ +public class InboundMessageHandler extends SimpleChannelInboundHandler { private final ByteBufInput input; private final MessageFormat.Reader reader; private final Logging logging; @@ -41,53 +39,43 @@ public class InboundMessageHandler extends SimpleChannelInboundHandler private InboundMessageDispatcher messageDispatcher; private Logger log; - public InboundMessageHandler( MessageFormat messageFormat, Logging logging ) - { + public InboundMessageHandler(MessageFormat messageFormat, Logging logging) { this.input = new ByteBufInput(); - this.reader = messageFormat.newReader( input ); + this.reader = messageFormat.newReader(input); this.logging = logging; } @Override - public void handlerAdded( ChannelHandlerContext ctx ) - { - messageDispatcher = requireNonNull( messageDispatcher( ctx.channel() ) ); - log = new ChannelActivityLogger( ctx.channel(), logging, getClass() ); + public void handlerAdded(ChannelHandlerContext ctx) { + messageDispatcher = requireNonNull(messageDispatcher(ctx.channel())); + log = new ChannelActivityLogger(ctx.channel(), logging, getClass()); } @Override - public void handlerRemoved( ChannelHandlerContext ctx ) - { + public void handlerRemoved(ChannelHandlerContext ctx) { messageDispatcher = null; log = null; } @Override - protected void channelRead0( ChannelHandlerContext ctx, ByteBuf msg ) - { - if ( messageDispatcher.fatalErrorOccurred() ) - { - log.warn( "Message ignored because of the previous fatal error. Channel will be closed. Message:\n%s", - hexDump( msg ) ); + protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) { + if (messageDispatcher.fatalErrorOccurred()) { + log.warn( + "Message ignored because of the previous fatal error. Channel will be closed. Message:\n%s", + hexDump(msg)); return; } - if ( log.isTraceEnabled() ) - { - log.trace( "S: %s", hexDump( msg ) ); + if (log.isTraceEnabled()) { + log.trace("S: %s", hexDump(msg)); } - input.start( msg ); - try - { - reader.read( messageDispatcher ); - } - catch ( Throwable error ) - { - throw new DecoderException( "Failed to read inbound message:\n" + hexDump( msg ) + "\n", error ); - } - finally - { + input.start(msg); + try { + reader.read(messageDispatcher); + } catch (Throwable error) { + throw new DecoderException("Failed to read inbound message:\n" + hexDump(msg) + "\n", error); + } finally { input.stop(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/MessageDecoder.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/MessageDecoder.java index c8b9a1078d..fe279b22c5 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/inbound/MessageDecoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/MessageDecoder.java @@ -21,37 +21,30 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; - import java.util.List; -public class MessageDecoder extends ByteToMessageDecoder -{ +public class MessageDecoder extends ByteToMessageDecoder { private static final Cumulator DEFAULT_CUMULATOR = determineDefaultCumulator(); private boolean readMessageBoundary; - public MessageDecoder() - { - setCumulator( DEFAULT_CUMULATOR ); + public MessageDecoder() { + setCumulator(DEFAULT_CUMULATOR); } @Override - public void channelRead( ChannelHandlerContext ctx, Object msg ) throws Exception - { - if ( msg instanceof ByteBuf ) - { + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (msg instanceof ByteBuf) { // on every read check if input buffer is empty or not // if it is empty then it's a message boundary and full message is in the buffer readMessageBoundary = ((ByteBuf) msg).readableBytes() == 0; } - super.channelRead( ctx, msg ); + super.channelRead(ctx, msg); } @Override - protected void decode( ChannelHandlerContext ctx, ByteBuf in, List out ) - { - if ( readMessageBoundary ) - { + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + if (readMessageBoundary) { // now we have a complete message in the input buffer // increment ref count of the buffer and create it's duplicate that shares the content @@ -59,20 +52,18 @@ protected void decode( ChannelHandlerContext ctx, ByteBuf in, List out ) ByteBuf messageBuf = in.retainedDuplicate(); // signal that whole message was read by making input buffer seem like it was fully read/consumed - in.readerIndex( in.readableBytes() ); + in.readerIndex(in.readableBytes()); // pass the full message to the next handler in the pipeline - out.add( messageBuf ); + out.add(messageBuf); readMessageBoundary = false; } } - private static Cumulator determineDefaultCumulator() - { - String value = System.getProperty( "messageDecoderCumulator", "" ); - if ( "merge".equals( value ) ) - { + private static Cumulator determineDefaultCumulator() { + String value = System.getProperty("messageDecoderCumulator", ""); + if ("merge".equals(value)) { return MERGE_CUMULATOR; } return COMPOSITE_CUMULATOR; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/outbound/ChunkAwareByteBufOutput.java b/driver/src/main/java/org/neo4j/driver/internal/async/outbound/ChunkAwareByteBufOutput.java index 1d87da52b5..b5c0f58430 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/outbound/ChunkAwareByteBufOutput.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/outbound/ChunkAwareByteBufOutput.java @@ -18,42 +18,36 @@ */ package org.neo4j.driver.internal.async.outbound; -import io.netty.buffer.ByteBuf; - -import org.neo4j.driver.internal.async.connection.BoltProtocolUtil; -import org.neo4j.driver.internal.packstream.PackOutput; - import static java.util.Objects.requireNonNull; import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.CHUNK_HEADER_SIZE_BYTES; import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.DEFAULT_MAX_OUTBOUND_CHUNK_SIZE_BYTES; -public class ChunkAwareByteBufOutput implements PackOutput -{ +import io.netty.buffer.ByteBuf; +import org.neo4j.driver.internal.async.connection.BoltProtocolUtil; +import org.neo4j.driver.internal.packstream.PackOutput; + +public class ChunkAwareByteBufOutput implements PackOutput { private final int maxChunkSize; private ByteBuf buf; private int currentChunkStartIndex; private int currentChunkSize; - public ChunkAwareByteBufOutput() - { - this( DEFAULT_MAX_OUTBOUND_CHUNK_SIZE_BYTES ); + public ChunkAwareByteBufOutput() { + this(DEFAULT_MAX_OUTBOUND_CHUNK_SIZE_BYTES); } - ChunkAwareByteBufOutput( int maxChunkSize ) - { - this.maxChunkSize = verifyMaxChunkSize( maxChunkSize ); + ChunkAwareByteBufOutput(int maxChunkSize) { + this.maxChunkSize = verifyMaxChunkSize(maxChunkSize); } - public void start( ByteBuf newBuf ) - { + public void start(ByteBuf newBuf) { assertNotStarted(); - buf = requireNonNull( newBuf ); - startNewChunk( 0 ); + buf = requireNonNull(newBuf); + startNewChunk(0); } - public void stop() - { + public void stop() { writeChunkSizeHeader(); buf = null; currentChunkStartIndex = 0; @@ -61,28 +55,25 @@ public void stop() } @Override - public PackOutput writeByte( byte value ) - { - ensureCanFitInCurrentChunk( 1 ); - buf.writeByte( value ); + public PackOutput writeByte(byte value) { + ensureCanFitInCurrentChunk(1); + buf.writeByte(value); currentChunkSize += 1; return this; } @Override - public PackOutput writeBytes( byte[] data ) - { + public PackOutput writeBytes(byte[] data) { int offset = 0; int length = data.length; - while ( offset < length ) - { + while (offset < length) { // Ensure there is an open chunk, and that it has at least one byte of space left - ensureCanFitInCurrentChunk( 1 ); + ensureCanFitInCurrentChunk(1); // Write as much as we can into the current chunk - int amountToWrite = Math.min( availableBytesInCurrentChunk(), length - offset ); + int amountToWrite = Math.min(availableBytesInCurrentChunk(), length - offset); - buf.writeBytes( data, offset, amountToWrite ); + buf.writeBytes(data, offset, amountToWrite); currentChunkSize += amountToWrite; offset += amountToWrite; } @@ -90,83 +81,70 @@ public PackOutput writeBytes( byte[] data ) } @Override - public PackOutput writeShort( short value ) - { - ensureCanFitInCurrentChunk( 2 ); - buf.writeShort( value ); + public PackOutput writeShort(short value) { + ensureCanFitInCurrentChunk(2); + buf.writeShort(value); currentChunkSize += 2; return this; } @Override - public PackOutput writeInt( int value ) - { - ensureCanFitInCurrentChunk( 4 ); - buf.writeInt( value ); + public PackOutput writeInt(int value) { + ensureCanFitInCurrentChunk(4); + buf.writeInt(value); currentChunkSize += 4; return this; } @Override - public PackOutput writeLong( long value ) - { - ensureCanFitInCurrentChunk( 8 ); - buf.writeLong( value ); + public PackOutput writeLong(long value) { + ensureCanFitInCurrentChunk(8); + buf.writeLong(value); currentChunkSize += 8; return this; } @Override - public PackOutput writeDouble( double value ) - { - ensureCanFitInCurrentChunk( 8 ); - buf.writeDouble( value ); + public PackOutput writeDouble(double value) { + ensureCanFitInCurrentChunk(8); + buf.writeDouble(value); currentChunkSize += 8; return this; } - private void ensureCanFitInCurrentChunk( int numberOfBytes ) - { + private void ensureCanFitInCurrentChunk(int numberOfBytes) { int targetChunkSize = currentChunkSize + numberOfBytes; - if ( targetChunkSize > maxChunkSize ) - { + if (targetChunkSize > maxChunkSize) { writeChunkSizeHeader(); - startNewChunk( buf.writerIndex() ); + startNewChunk(buf.writerIndex()); } } - private void startNewChunk( int index ) - { + private void startNewChunk(int index) { currentChunkStartIndex = index; - BoltProtocolUtil.writeEmptyChunkHeader( buf ); + BoltProtocolUtil.writeEmptyChunkHeader(buf); currentChunkSize = CHUNK_HEADER_SIZE_BYTES; } - private void writeChunkSizeHeader() - { + private void writeChunkSizeHeader() { // go to the beginning of the chunk and write the size header int chunkBodySize = currentChunkSize - CHUNK_HEADER_SIZE_BYTES; - BoltProtocolUtil.writeChunkHeader( buf, currentChunkStartIndex, chunkBodySize ); + BoltProtocolUtil.writeChunkHeader(buf, currentChunkStartIndex, chunkBodySize); } - private int availableBytesInCurrentChunk() - { + private int availableBytesInCurrentChunk() { return maxChunkSize - currentChunkSize; } - private void assertNotStarted() - { - if ( buf != null ) - { - throw new IllegalStateException( "Already started" ); + private void assertNotStarted() { + if (buf != null) { + throw new IllegalStateException("Already started"); } } - private static int verifyMaxChunkSize( int maxChunkSize ) - { - if ( maxChunkSize <= 0 ) - { - throw new IllegalArgumentException( "Max chunk size should be > 0, given: " + maxChunkSize ); + private static int verifyMaxChunkSize(int maxChunkSize) { + if (maxChunkSize <= 0) { + throw new IllegalArgumentException("Max chunk size should be > 0, given: " + maxChunkSize); } return maxChunkSize; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/outbound/OutboundMessageHandler.java b/driver/src/main/java/org/neo4j/driver/internal/async/outbound/OutboundMessageHandler.java index 91f0141477..fb73c1a24c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/outbound/OutboundMessageHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/outbound/OutboundMessageHandler.java @@ -18,24 +18,21 @@ */ package org.neo4j.driver.internal.async.outbound; +import static io.netty.buffer.ByteBufUtil.hexDump; + import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.EncoderException; import io.netty.handler.codec.MessageToMessageEncoder; - import java.util.List; - +import org.neo4j.driver.Logger; +import org.neo4j.driver.Logging; import org.neo4j.driver.internal.async.connection.BoltProtocolUtil; import org.neo4j.driver.internal.logging.ChannelActivityLogger; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageFormat; -import org.neo4j.driver.Logger; -import org.neo4j.driver.Logging; -import static io.netty.buffer.ByteBufUtil.hexDump; - -public class OutboundMessageHandler extends MessageToMessageEncoder -{ +public class OutboundMessageHandler extends MessageToMessageEncoder { public static final String NAME = OutboundMessageHandler.class.getSimpleName(); private final ChunkAwareByteBufOutput output; private final MessageFormat.Writer writer; @@ -43,51 +40,43 @@ public class OutboundMessageHandler extends MessageToMessageEncoder private Logger log; - public OutboundMessageHandler( MessageFormat messageFormat, Logging logging ) - { + public OutboundMessageHandler(MessageFormat messageFormat, Logging logging) { this.output = new ChunkAwareByteBufOutput(); - this.writer = messageFormat.newWriter( output ); + this.writer = messageFormat.newWriter(output); this.logging = logging; } @Override - public void handlerAdded( ChannelHandlerContext ctx ) - { - log = new ChannelActivityLogger( ctx.channel(), logging, getClass() ); + public void handlerAdded(ChannelHandlerContext ctx) { + log = new ChannelActivityLogger(ctx.channel(), logging, getClass()); } @Override - public void handlerRemoved( ChannelHandlerContext ctx ) - { + public void handlerRemoved(ChannelHandlerContext ctx) { log = null; } @Override - protected void encode( ChannelHandlerContext ctx, Message msg, List out ) - { - log.debug( "C: %s", msg ); + protected void encode(ChannelHandlerContext ctx, Message msg, List out) { + log.debug("C: %s", msg); ByteBuf messageBuf = ctx.alloc().ioBuffer(); - output.start( messageBuf ); - try - { - writer.write( msg ); + output.start(messageBuf); + try { + writer.write(msg); output.stop(); - } - catch ( Throwable error ) - { + } catch (Throwable error) { output.stop(); // release buffer because it will not get added to the out list and no other handler is going to handle it messageBuf.release(); - throw new EncoderException( "Failed to write outbound message: " + msg, error ); + throw new EncoderException("Failed to write outbound message: " + msg, error); } - if ( log.isTraceEnabled() ) - { - log.trace( "C: %s", hexDump( messageBuf ) ); + if (log.isTraceEnabled()) { + log.trace("C: %s", hexDump(messageBuf)); } - BoltProtocolUtil.writeMessageBoundary( messageBuf ); - out.add( messageBuf ); + BoltProtocolUtil.writeMessageBoundary(messageBuf); + out.add(messageBuf); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionFactory.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionFactory.java index 15aa7ece11..92811bbc72 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionFactory.java @@ -19,10 +19,8 @@ package org.neo4j.driver.internal.async.pool; import io.netty.channel.Channel; - import org.neo4j.driver.internal.spi.Connection; -public interface ConnectionFactory -{ - Connection createConnection( Channel channel, ExtendedChannelPool pool ); +public interface ConnectionFactory { + Connection createConnection(Channel channel, ExtendedChannelPool pool); } 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 db46e716a8..a6eb929554 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 @@ -18,10 +18,16 @@ */ package org.neo4j.driver.internal.async.pool; +import static java.lang.String.format; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setAuthorizationStateListener; +import static org.neo4j.driver.internal.util.Futures.combineErrors; +import static org.neo4j.driver.internal.util.Futures.completeWithNullIfNoError; +import static org.neo4j.driver.internal.util.LockUtil.executeWithLock; +import static org.neo4j.driver.internal.util.LockUtil.executeWithLockAsync; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; - import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -34,7 +40,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.exceptions.ClientException; @@ -49,15 +54,7 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.net.ServerAddress; -import static java.lang.String.format; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setAuthorizationStateListener; -import static org.neo4j.driver.internal.util.Futures.combineErrors; -import static org.neo4j.driver.internal.util.Futures.completeWithNullIfNoError; -import static org.neo4j.driver.internal.util.LockUtil.executeWithLock; -import static org.neo4j.driver.internal.util.LockUtil.executeWithLockAsync; - -public class ConnectionPoolImpl implements ConnectionPool -{ +public class ConnectionPoolImpl implements ConnectionPool { private final ChannelConnector connector; private final Bootstrap bootstrap; private final NettyChannelTracker nettyChannelTracker; @@ -68,279 +65,270 @@ public class ConnectionPoolImpl implements ConnectionPool private final boolean ownsEventLoopGroup; private final ReadWriteLock addressToPoolLock = new ReentrantReadWriteLock(); - private final Map addressToPool = new HashMap<>(); + private final Map addressToPool = new HashMap<>(); private final AtomicBoolean closed = new AtomicBoolean(); private final CompletableFuture closeFuture = new CompletableFuture<>(); private final ConnectionFactory connectionFactory; - public ConnectionPoolImpl( ChannelConnector connector, Bootstrap bootstrap, PoolSettings settings, MetricsListener metricsListener, Logging logging, - Clock clock, boolean ownsEventLoopGroup ) - { - this( connector, bootstrap, new NettyChannelTracker( metricsListener, bootstrap.config().group().next(), logging ), - new NettyChannelHealthChecker( settings, clock, logging ), settings, metricsListener, logging, - clock, ownsEventLoopGroup, new NetworkConnectionFactory( clock, metricsListener, logging ) ); + public ConnectionPoolImpl( + ChannelConnector connector, + Bootstrap bootstrap, + PoolSettings settings, + MetricsListener metricsListener, + Logging logging, + Clock clock, + boolean ownsEventLoopGroup) { + this( + connector, + bootstrap, + new NettyChannelTracker( + metricsListener, bootstrap.config().group().next(), logging), + new NettyChannelHealthChecker(settings, clock, logging), + settings, + metricsListener, + logging, + clock, + ownsEventLoopGroup, + new NetworkConnectionFactory(clock, metricsListener, logging)); } - protected ConnectionPoolImpl( ChannelConnector connector, Bootstrap bootstrap, NettyChannelTracker nettyChannelTracker, - NettyChannelHealthChecker nettyChannelHealthChecker, PoolSettings settings, - MetricsListener metricsListener, Logging logging, Clock clock, boolean ownsEventLoopGroup, - ConnectionFactory connectionFactory ) - { + protected ConnectionPoolImpl( + ChannelConnector connector, + Bootstrap bootstrap, + NettyChannelTracker nettyChannelTracker, + NettyChannelHealthChecker nettyChannelHealthChecker, + PoolSettings settings, + MetricsListener metricsListener, + Logging logging, + Clock clock, + boolean ownsEventLoopGroup, + ConnectionFactory connectionFactory) { this.connector = connector; this.bootstrap = bootstrap; this.nettyChannelTracker = nettyChannelTracker; this.channelHealthChecker = nettyChannelHealthChecker; this.settings = settings; this.metricsListener = metricsListener; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); this.ownsEventLoopGroup = ownsEventLoopGroup; this.connectionFactory = connectionFactory; } @Override - public CompletionStage acquire( BoltServerAddress address ) - { - log.trace( "Acquiring a connection from pool towards %s", address ); + public CompletionStage acquire(BoltServerAddress address) { + log.trace("Acquiring a connection from pool towards %s", address); assertNotClosed(); - ExtendedChannelPool pool = getOrCreatePool( address ); + ExtendedChannelPool pool = getOrCreatePool(address); ListenerEvent acquireEvent = metricsListener.createListenerEvent(); - metricsListener.beforeAcquiringOrCreating( pool.id(), acquireEvent ); + metricsListener.beforeAcquiringOrCreating(pool.id(), acquireEvent); CompletionStage channelFuture = pool.acquire(); - return channelFuture.handle( ( channel, error ) -> - { - try - { - processAcquisitionError( pool, address, error ); - assertNotClosed( address, channel, pool ); - setAuthorizationStateListener( channel, channelHealthChecker ); - Connection connection = connectionFactory.createConnection( channel, pool ); + return channelFuture.handle((channel, error) -> { + try { + processAcquisitionError(pool, address, error); + assertNotClosed(address, channel, pool); + setAuthorizationStateListener(channel, channelHealthChecker); + Connection connection = connectionFactory.createConnection(channel, pool); - metricsListener.afterAcquiredOrCreated( pool.id(), acquireEvent ); + metricsListener.afterAcquiredOrCreated(pool.id(), acquireEvent); return connection; + } finally { + metricsListener.afterAcquiringOrCreating(pool.id()); } - finally - { - metricsListener.afterAcquiringOrCreating( pool.id() ); - } - } ); + }); } @Override - public void retainAll( Set addressesToRetain ) - { - executeWithLock( addressToPoolLock.writeLock(), () -> - { - Iterator> entryIterator = addressToPool.entrySet().iterator(); - while ( entryIterator.hasNext() ) - { - Map.Entry entry = entryIterator.next(); + public void retainAll(Set addressesToRetain) { + executeWithLock(addressToPoolLock.writeLock(), () -> { + Iterator> entryIterator = + addressToPool.entrySet().iterator(); + while (entryIterator.hasNext()) { + Map.Entry entry = entryIterator.next(); BoltServerAddress address = entry.getKey(); - if ( !addressesToRetain.contains( address ) ) - { - int activeChannels = nettyChannelTracker.inUseChannelCount( address ); - if ( activeChannels == 0 ) - { + if (!addressesToRetain.contains(address)) { + int activeChannels = nettyChannelTracker.inUseChannelCount(address); + if (activeChannels == 0) { // address is not present in updated routing table and has no active connections // it's now safe to terminate corresponding connection pool and forget about it ExtendedChannelPool pool = entry.getValue(); entryIterator.remove(); - if ( pool != null ) - { - log.info( "Closing connection pool towards %s, it has no active connections " + - "and is not in the routing table registry.", address ); - closePoolInBackground( address, pool ); + if (pool != null) { + log.info( + "Closing connection pool towards %s, it has no active connections " + + "and is not in the routing table registry.", + address); + closePoolInBackground(address, pool); } } } } - } ); + }); } @Override - public int inUseConnections( ServerAddress address ) - { - return nettyChannelTracker.inUseChannelCount( address ); + public int inUseConnections(ServerAddress address) { + return nettyChannelTracker.inUseChannelCount(address); } @Override - public int idleConnections( ServerAddress address ) - { - return nettyChannelTracker.idleChannelCount( address ); + public int idleConnections(ServerAddress address) { + return nettyChannelTracker.idleChannelCount(address); } @Override - public CompletionStage close() - { - if ( closed.compareAndSet( false, true ) ) - { + public CompletionStage close() { + if (closed.compareAndSet(false, true)) { nettyChannelTracker.prepareToCloseChannels(); - executeWithLockAsync( addressToPoolLock.writeLock(), - () -> - { - // We can only shutdown event loop group when all netty pools are fully closed, - // otherwise the netty pools might missing threads (from event loop group) to execute clean ups. - return closeAllPools().whenComplete( - ( ignored, pollCloseError ) -> - { - addressToPool.clear(); - if ( !ownsEventLoopGroup ) - { - completeWithNullIfNoError( closeFuture, pollCloseError ); - } - else - { - shutdownEventLoopGroup( pollCloseError ); - } - } ); - } ); + executeWithLockAsync(addressToPoolLock.writeLock(), () -> { + // We can only shutdown event loop group when all netty pools are fully closed, + // otherwise the netty pools might missing threads (from event loop group) to execute clean ups. + return closeAllPools().whenComplete((ignored, pollCloseError) -> { + addressToPool.clear(); + if (!ownsEventLoopGroup) { + completeWithNullIfNoError(closeFuture, pollCloseError); + } else { + shutdownEventLoopGroup(pollCloseError); + } + }); + }); } return closeFuture; } @Override - public boolean isOpen( BoltServerAddress address ) - { - return executeWithLock( addressToPoolLock.readLock(), () -> addressToPool.containsKey( address ) ); + public boolean isOpen(BoltServerAddress address) { + return executeWithLock(addressToPoolLock.readLock(), () -> addressToPool.containsKey(address)); } @Override - public String toString() - { - return executeWithLock( addressToPoolLock.readLock(), () -> "ConnectionPoolImpl{" + "pools=" + addressToPool + '}' ); + public String toString() { + return executeWithLock( + addressToPoolLock.readLock(), () -> "ConnectionPoolImpl{" + "pools=" + addressToPool + '}'); } - private void processAcquisitionError( ExtendedChannelPool pool, BoltServerAddress serverAddress, Throwable error ) - { - Throwable cause = Futures.completionExceptionCause( error ); - if ( cause != null ) - { - if ( cause instanceof TimeoutException ) - { + private void processAcquisitionError(ExtendedChannelPool pool, BoltServerAddress serverAddress, Throwable error) { + Throwable cause = Futures.completionExceptionCause(error); + if (cause != null) { + if (cause instanceof TimeoutException) { // NettyChannelPool returns future failed with TimeoutException if acquire operation takes more than // configured time, translate this exception to a prettier one and re-throw - metricsListener.afterTimedOutToAcquireOrCreate( pool.id() ); + metricsListener.afterTimedOutToAcquireOrCreate(pool.id()); throw new ClientException( - "Unable to acquire connection from the pool within configured maximum time of " + - settings.connectionAcquisitionTimeout() + "ms" ); - } - else if ( pool.isClosed() ) - { - // There is a race condition where a thread tries to acquire a connection while the pool is closed by another concurrent thread. - // Treat as failed to obtain connection for a direct driver. For a routing driver, this error should be retried. - throw new ServiceUnavailableException( format( "Connection pool for server %s is closed while acquiring a connection.", serverAddress ), - cause ); - } - else - { + "Unable to acquire connection from the pool within configured maximum time of " + + settings.connectionAcquisitionTimeout() + "ms"); + } else if (pool.isClosed()) { + // There is a race condition where a thread tries to acquire a connection while the pool is closed by + // another concurrent thread. + // Treat as failed to obtain connection for a direct driver. For a routing driver, this error should be + // retried. + throw new ServiceUnavailableException( + format("Connection pool for server %s is closed while acquiring a connection.", serverAddress), + cause); + } else { // some unknown error happened during connection acquisition, propagate it - throw new CompletionException( cause ); + throw new CompletionException(cause); } } } - private void assertNotClosed() - { - if ( closed.get() ) - { - throw new IllegalStateException( CONNECTION_POOL_CLOSED_ERROR_MESSAGE ); + private void assertNotClosed() { + if (closed.get()) { + throw new IllegalStateException(CONNECTION_POOL_CLOSED_ERROR_MESSAGE); } } - private void assertNotClosed( BoltServerAddress address, Channel channel, ExtendedChannelPool pool ) - { - if ( closed.get() ) - { - pool.release( channel ); - closePoolInBackground( address, pool ); - executeWithLock( addressToPoolLock.writeLock(), () -> addressToPool.remove( address ) ); + private void assertNotClosed(BoltServerAddress address, Channel channel, ExtendedChannelPool pool) { + if (closed.get()) { + pool.release(channel); + closePoolInBackground(address, pool); + executeWithLock(addressToPoolLock.writeLock(), () -> addressToPool.remove(address)); assertNotClosed(); } } // for testing only - ExtendedChannelPool getPool( BoltServerAddress address ) - { - return executeWithLock( addressToPoolLock.readLock(), () -> addressToPool.get( address ) ); + ExtendedChannelPool getPool(BoltServerAddress address) { + return executeWithLock(addressToPoolLock.readLock(), () -> addressToPool.get(address)); } - ExtendedChannelPool newPool( BoltServerAddress address ) - { - return new NettyChannelPool( address, connector, bootstrap, nettyChannelTracker, channelHealthChecker, settings.connectionAcquisitionTimeout(), - settings.maxConnectionPoolSize() ); + ExtendedChannelPool newPool(BoltServerAddress address) { + return new NettyChannelPool( + address, + connector, + bootstrap, + nettyChannelTracker, + channelHealthChecker, + settings.connectionAcquisitionTimeout(), + settings.maxConnectionPoolSize()); } - private ExtendedChannelPool getOrCreatePool( BoltServerAddress address ) - { - ExtendedChannelPool existingPool = executeWithLock( addressToPoolLock.readLock(), () -> addressToPool.get( address ) ); + private ExtendedChannelPool getOrCreatePool(BoltServerAddress address) { + ExtendedChannelPool existingPool = + executeWithLock(addressToPoolLock.readLock(), () -> addressToPool.get(address)); return existingPool != null - ? existingPool - : executeWithLock( addressToPoolLock.writeLock(), - () -> - { - ExtendedChannelPool pool = addressToPool.get( address ); - if ( pool == null ) - { - pool = newPool( address ); - // before the connection pool is added I can register the metrics for the pool. - metricsListener.registerPoolMetrics( pool.id(), address, () -> this.inUseConnections( address ), () -> this.idleConnections( address ) ); - addressToPool.put( address, pool ); - } - return pool; - } ); + ? existingPool + : executeWithLock(addressToPoolLock.writeLock(), () -> { + ExtendedChannelPool pool = addressToPool.get(address); + if (pool == null) { + pool = newPool(address); + // before the connection pool is added I can register the metrics for the pool. + metricsListener.registerPoolMetrics( + pool.id(), + address, + () -> this.inUseConnections(address), + () -> this.idleConnections(address)); + addressToPool.put(address, pool); + } + return pool; + }); } - private CompletionStage closePool( ExtendedChannelPool pool ) - { - return pool.close().whenComplete( ( ignored, error ) -> - // after the connection pool is removed/close, I can remove its metrics. - metricsListener.removePoolMetrics( pool.id() ) ); + private CompletionStage closePool(ExtendedChannelPool pool) { + return pool.close() + .whenComplete((ignored, error) -> + // after the connection pool is removed/close, I can remove its metrics. + metricsListener.removePoolMetrics(pool.id())); } - private void closePoolInBackground( BoltServerAddress address, ExtendedChannelPool pool ) - { + private void closePoolInBackground(BoltServerAddress address, ExtendedChannelPool pool) { // Close in the background - closePool( pool ).whenComplete( ( ignored, error ) -> { - if ( error != null ) - { - log.warn( format( "An error occurred while closing connection pool towards %s.", address ), error ); + closePool(pool).whenComplete((ignored, error) -> { + if (error != null) { + log.warn(format("An error occurred while closing connection pool towards %s.", address), error); } - } ); + }); } - private EventLoopGroup eventLoopGroup() - { + private EventLoopGroup eventLoopGroup() { return bootstrap.config().group(); } - private void shutdownEventLoopGroup( Throwable pollCloseError ) - { + private void shutdownEventLoopGroup(Throwable pollCloseError) { // This is an attempt to speed up the shut down procedure of the driver - // This timeout is needed for `closePoolInBackground` to finish background job, especially for races between `acquire` and `close`. - eventLoopGroup().shutdownGracefully( 200, 15_000, TimeUnit.MILLISECONDS ); - - Futures.asCompletionStage( eventLoopGroup().terminationFuture() ) - .whenComplete( ( ignore, eventLoopGroupTerminationError ) -> { - CompletionException combinedErrors = combineErrors( pollCloseError, eventLoopGroupTerminationError ); - completeWithNullIfNoError( closeFuture, combinedErrors ); - } ); + // This timeout is needed for `closePoolInBackground` to finish background job, especially for races between + // `acquire` and `close`. + eventLoopGroup().shutdownGracefully(200, 15_000, TimeUnit.MILLISECONDS); + + Futures.asCompletionStage(eventLoopGroup().terminationFuture()) + .whenComplete((ignore, eventLoopGroupTerminationError) -> { + CompletionException combinedErrors = combineErrors(pollCloseError, eventLoopGroupTerminationError); + completeWithNullIfNoError(closeFuture, combinedErrors); + }); } - private CompletableFuture closeAllPools() - { - return CompletableFuture.allOf( - addressToPool.entrySet().stream() - .map( entry -> - { - BoltServerAddress address = entry.getKey(); - ExtendedChannelPool pool = entry.getValue(); - log.info( "Closing connection pool towards %s", address ); - // Wait for all pools to be closed. - return closePool( pool ).toCompletableFuture(); - } ) - .toArray( CompletableFuture[]::new ) ); + private CompletableFuture closeAllPools() { + return CompletableFuture.allOf(addressToPool.entrySet().stream() + .map(entry -> { + BoltServerAddress address = entry.getKey(); + ExtendedChannelPool pool = entry.getValue(); + log.info("Closing connection pool towards %s", address); + // Wait for all pools to be closed. + return closePool(pool).toCompletableFuture(); + }) + .toArray(CompletableFuture[]::new)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ExtendedChannelPool.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ExtendedChannelPool.java index fe6b800c3f..ec3c541480 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ExtendedChannelPool.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ExtendedChannelPool.java @@ -19,14 +19,12 @@ package org.neo4j.driver.internal.async.pool; import io.netty.channel.Channel; - import java.util.concurrent.CompletionStage; -public interface ExtendedChannelPool -{ +public interface ExtendedChannelPool { CompletionStage acquire(); - CompletionStage release( Channel channel ); + CompletionStage release(Channel channel); boolean isClosed(); 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 f337f01deb..b5e4c5ef34 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 @@ -18,14 +18,16 @@ */ package org.neo4j.driver.internal.async.pool; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.creationTimestamp; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.lastUsedTimestamp; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; + import io.netty.channel.Channel; import io.netty.channel.pool.ChannelHealthChecker; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Promise; - import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.exceptions.AuthorizationExpiredException; @@ -34,72 +36,61 @@ import org.neo4j.driver.internal.messaging.request.ResetMessage; import org.neo4j.driver.internal.util.Clock; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.creationTimestamp; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.lastUsedTimestamp; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; - -public class NettyChannelHealthChecker implements ChannelHealthChecker, AuthorizationStateListener -{ +public class NettyChannelHealthChecker implements ChannelHealthChecker, AuthorizationStateListener { private final PoolSettings poolSettings; private final Clock clock; private final Logging logging; private final Logger log; private final AtomicReference> minCreationTimestampMillisOpt; - public NettyChannelHealthChecker( PoolSettings poolSettings, Clock clock, Logging logging ) - { + public NettyChannelHealthChecker(PoolSettings poolSettings, Clock clock, Logging logging) { this.poolSettings = poolSettings; this.clock = clock; this.logging = logging; - this.log = logging.getLog( getClass() ); - this.minCreationTimestampMillisOpt = new AtomicReference<>( Optional.empty() ); + this.log = logging.getLog(getClass()); + this.minCreationTimestampMillisOpt = new AtomicReference<>(Optional.empty()); } @Override - public Future isHealthy( Channel channel ) - { - if ( isTooOld( channel ) ) - { - return channel.eventLoop().newSucceededFuture( Boolean.FALSE ); + public Future isHealthy(Channel channel) { + if (isTooOld(channel)) { + return channel.eventLoop().newSucceededFuture(Boolean.FALSE); } - if ( hasBeenIdleForTooLong( channel ) ) - { - return ping( channel ); + if (hasBeenIdleForTooLong(channel)) { + return ping(channel); } - return ACTIVE.isHealthy( channel ); + return ACTIVE.isHealthy(channel); } @Override - public void onExpired( AuthorizationExpiredException e, Channel channel ) - { - long ts = creationTimestamp( channel ); + public void onExpired(AuthorizationExpiredException e, Channel channel) { + long ts = creationTimestamp(channel); // Override current value ONLY if the new one is greater - minCreationTimestampMillisOpt.getAndUpdate( prev -> Optional.of( prev.filter( prevTs -> ts <= prevTs ).orElse( ts ) ) ); + minCreationTimestampMillisOpt.getAndUpdate( + prev -> Optional.of(prev.filter(prevTs -> ts <= prevTs).orElse(ts))); } - private boolean isTooOld( Channel channel ) - { - long creationTimestampMillis = creationTimestamp( channel ); + private boolean isTooOld(Channel channel) { + long creationTimestampMillis = creationTimestamp(channel); Optional minCreationTimestampMillisOpt = this.minCreationTimestampMillisOpt.get(); - if ( minCreationTimestampMillisOpt.isPresent() && creationTimestampMillis <= minCreationTimestampMillisOpt.get() ) - { - log.trace( "The channel %s is marked for closure as its creation timestamp is older than or equal to the acceptable minimum timestamp: %s <= %s", - channel, creationTimestampMillis, minCreationTimestampMillisOpt.get() ); + if (minCreationTimestampMillisOpt.isPresent() + && creationTimestampMillis <= minCreationTimestampMillisOpt.get()) { + log.trace( + "The channel %s is marked for closure as its creation timestamp is older than or equal to the acceptable minimum timestamp: %s <= %s", + channel, creationTimestampMillis, minCreationTimestampMillisOpt.get()); return true; - } - else if ( poolSettings.maxConnectionLifetimeEnabled() ) - { + } else if (poolSettings.maxConnectionLifetimeEnabled()) { long currentTimestampMillis = clock.millis(); long ageMillis = currentTimestampMillis - creationTimestampMillis; long maxAgeMillis = poolSettings.maxConnectionLifetime(); boolean tooOld = ageMillis > maxAgeMillis; - if ( tooOld ) - { - log.trace( "Failed acquire channel %s from the pool because it is too old: %s > %s", - channel, ageMillis, maxAgeMillis ); + if (tooOld) { + log.trace( + "Failed acquire channel %s from the pool because it is too old: %s > %s", + channel, ageMillis, maxAgeMillis); } return tooOld; @@ -107,19 +98,15 @@ else if ( poolSettings.maxConnectionLifetimeEnabled() ) return false; } - private boolean hasBeenIdleForTooLong( Channel channel ) - { - if ( poolSettings.idleTimeBeforeConnectionTestEnabled() ) - { - Long lastUsedTimestamp = lastUsedTimestamp( channel ); - if ( lastUsedTimestamp != null ) - { + private boolean hasBeenIdleForTooLong(Channel channel) { + if (poolSettings.idleTimeBeforeConnectionTestEnabled()) { + Long lastUsedTimestamp = lastUsedTimestamp(channel); + if (lastUsedTimestamp != null) { long idleTime = clock.millis() - lastUsedTimestamp; boolean idleTooLong = idleTime > poolSettings.idleTimeBeforeConnectionTest(); - if ( idleTooLong ) - { - log.trace( "Channel %s has been idle for %s and needs a ping", channel, idleTime ); + if (idleTooLong) { + log.trace("Channel %s has been idle for %s and needs a ping", channel, idleTime); } return idleTooLong; @@ -128,11 +115,10 @@ private boolean hasBeenIdleForTooLong( Channel channel ) return false; } - private Future ping( Channel channel ) - { + private Future ping(Channel channel) { Promise result = channel.eventLoop().newPromise(); - messageDispatcher( channel ).enqueue( new PingResponseHandler( result, channel, logging ) ); - channel.writeAndFlush( ResetMessage.RESET, channel.voidPromise() ); + messageDispatcher(channel).enqueue(new PingResponseHandler(result, channel, logging)); + channel.writeAndFlush(ResetMessage.RESET, channel.voidPromise()); return result; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelPool.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelPool.java index 8abdb5b30b..31bf01c427 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelPool.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelPool.java @@ -18,27 +18,24 @@ */ package org.neo4j.driver.internal.async.pool; +import static java.util.Objects.requireNonNull; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setPoolId; +import static org.neo4j.driver.internal.util.Futures.asCompletionStage; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelPromise; import io.netty.channel.pool.ChannelHealthChecker; import io.netty.channel.pool.FixedChannelPool; - import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicBoolean; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.connection.ChannelConnector; import org.neo4j.driver.internal.metrics.ListenerEvent; -import static java.util.Objects.requireNonNull; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setPoolId; -import static org.neo4j.driver.internal.util.Futures.asCompletionStage; - -public class NettyChannelPool implements ExtendedChannelPool -{ +public class NettyChannelPool implements ExtendedChannelPool { /** * Unlimited amount of parties are allowed to request channels from the pool. */ @@ -49,85 +46,85 @@ public class NettyChannelPool implements ExtendedChannelPool private static final boolean RELEASE_HEALTH_CHECK = false; private final FixedChannelPool delegate; - private final AtomicBoolean closed = new AtomicBoolean( false ); + private final AtomicBoolean closed = new AtomicBoolean(false); private final String id; private final CompletableFuture closeFuture = new CompletableFuture<>(); - NettyChannelPool( BoltServerAddress address, ChannelConnector connector, Bootstrap bootstrap, NettyChannelTracker handler, - ChannelHealthChecker healthCheck, long acquireTimeoutMillis, int maxConnections ) - { - requireNonNull( address ); - requireNonNull( connector ); - requireNonNull( handler ); - this.id = poolId( address ); - this.delegate = new FixedChannelPool( bootstrap, handler, healthCheck, FixedChannelPool.AcquireTimeoutAction.FAIL, acquireTimeoutMillis, maxConnections, - MAX_PENDING_ACQUIRES, RELEASE_HEALTH_CHECK ) - { - @Override - protected ChannelFuture connectChannel( Bootstrap bootstrap ) - { - ListenerEvent creatingEvent = handler.channelCreating( id ); - ChannelFuture connectedChannelFuture = connector.connect( address, bootstrap ); - Channel channel = connectedChannelFuture.channel(); - // This ensures that handler.channelCreated is called before SimpleChannelPool calls handler.channelAcquired - ChannelPromise trackedChannelFuture = channel.newPromise(); - connectedChannelFuture.addListener( - future -> - { - if ( future.isSuccess() ) - { + NettyChannelPool( + BoltServerAddress address, + ChannelConnector connector, + Bootstrap bootstrap, + NettyChannelTracker handler, + ChannelHealthChecker healthCheck, + long acquireTimeoutMillis, + int maxConnections) { + requireNonNull(address); + requireNonNull(connector); + requireNonNull(handler); + this.id = poolId(address); + this.delegate = + new FixedChannelPool( + bootstrap, + handler, + healthCheck, + FixedChannelPool.AcquireTimeoutAction.FAIL, + acquireTimeoutMillis, + maxConnections, + MAX_PENDING_ACQUIRES, + RELEASE_HEALTH_CHECK) { + @Override + protected ChannelFuture connectChannel(Bootstrap bootstrap) { + ListenerEvent creatingEvent = handler.channelCreating(id); + ChannelFuture connectedChannelFuture = connector.connect(address, bootstrap); + Channel channel = connectedChannelFuture.channel(); + // This ensures that handler.channelCreated is called before SimpleChannelPool calls + // handler.channelAcquired + ChannelPromise trackedChannelFuture = channel.newPromise(); + connectedChannelFuture.addListener(future -> { + if (future.isSuccess()) { // notify pool handler about a successful connection - setPoolId( channel, id ); - handler.channelCreated( channel, creatingEvent ); + setPoolId(channel, id); + handler.channelCreated(channel, creatingEvent); trackedChannelFuture.setSuccess(); + } else { + handler.channelFailedToCreate(id); + trackedChannelFuture.setFailure(future.cause()); } - else - { - handler.channelFailedToCreate( id ); - trackedChannelFuture.setFailure( future.cause() ); - } - } ); - return trackedChannelFuture; - } - }; + }); + return trackedChannelFuture; + } + }; } @Override - public CompletionStage close() - { - if ( closed.compareAndSet( false, true ) ) - { - asCompletionStage( delegate.closeAsync(), closeFuture ); + public CompletionStage close() { + if (closed.compareAndSet(false, true)) { + asCompletionStage(delegate.closeAsync(), closeFuture); } return closeFuture; } @Override - public CompletionStage acquire() - { - return asCompletionStage( delegate.acquire() ); + public CompletionStage acquire() { + return asCompletionStage(delegate.acquire()); } @Override - public CompletionStage release( Channel channel ) - { - return asCompletionStage( delegate.release( channel ) ); + public CompletionStage release(Channel channel) { + return asCompletionStage(delegate.release(channel)); } @Override - public boolean isClosed() - { + public boolean isClosed() { return closed.get(); } @Override - public String id() - { + public String id() { return this.id; } - private String poolId( BoltServerAddress serverAddress ) - { - return String.format( "%s:%d-%d", serverAddress.host(), serverAddress.port(), this.hashCode() ); + private String poolId(BoltServerAddress serverAddress) { + return String.format("%s:%d-%d", serverAddress.host(), serverAddress.port(), this.hashCode()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java index 44bde86033..4876ce3d78 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java @@ -18,19 +18,20 @@ */ package org.neo4j.driver.internal.async.pool; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.poolId; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.serverAddress; + import io.netty.channel.Channel; import io.netty.channel.ChannelFutureListener; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.channel.pool.ChannelPoolHandler; import io.netty.util.concurrent.EventExecutor; - import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Supplier; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BoltServerAddress; @@ -39,185 +40,152 @@ import org.neo4j.driver.internal.metrics.MetricsListener; import org.neo4j.driver.net.ServerAddress; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.poolId; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.serverAddress; - -public class NettyChannelTracker implements ChannelPoolHandler -{ +public class NettyChannelTracker implements ChannelPoolHandler { private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private final Lock read = lock.readLock(); private final Lock write = lock.writeLock(); - private final Map addressToInUseChannelCount = new HashMap<>(); - private final Map addressToIdleChannelCount = new HashMap<>(); + private final Map addressToInUseChannelCount = new HashMap<>(); + private final Map addressToIdleChannelCount = new HashMap<>(); private final Logger log; private final MetricsListener metricsListener; - private final ChannelFutureListener closeListener = future -> channelClosed( future.channel() ); + private final ChannelFutureListener closeListener = future -> channelClosed(future.channel()); private final ChannelGroup allChannels; - public NettyChannelTracker( MetricsListener metricsListener, EventExecutor eventExecutor, Logging logging ) - { - this( metricsListener, new DefaultChannelGroup( "all-connections", eventExecutor ), logging ); + public NettyChannelTracker(MetricsListener metricsListener, EventExecutor eventExecutor, Logging logging) { + this(metricsListener, new DefaultChannelGroup("all-connections", eventExecutor), logging); } - public NettyChannelTracker( MetricsListener metricsListener, ChannelGroup channels, Logging logging ) - { + public NettyChannelTracker(MetricsListener metricsListener, ChannelGroup channels, Logging logging) { this.metricsListener = metricsListener; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); this.allChannels = channels; } - private void doInWriteLock( Runnable work ) - { - try - { + private void doInWriteLock(Runnable work) { + try { write.lock(); work.run(); - } - finally - { + } finally { write.unlock(); } } - private T retrieveInReadLock( Supplier work ) - { - try - { + private T retrieveInReadLock(Supplier work) { + try { read.lock(); return work.get(); - } - finally - { + } finally { read.unlock(); } } @Override - public void channelReleased( Channel channel ) - { - doInWriteLock( () -> - { - decrementInUse( channel ); - incrementIdle( channel ); - channel.closeFuture().addListener( closeListener ); - } ); + public void channelReleased(Channel channel) { + doInWriteLock(() -> { + decrementInUse(channel); + incrementIdle(channel); + channel.closeFuture().addListener(closeListener); + }); - log.debug( "Channel [0x%s] released back to the pool", channel.id() ); + log.debug("Channel [0x%s] released back to the pool", channel.id()); } @Override - public void channelAcquired( Channel channel ) - { - doInWriteLock( () -> - { - incrementInUse( channel ); - decrementIdle( channel ); - channel.closeFuture().removeListener( closeListener ); - } ); + public void channelAcquired(Channel channel) { + doInWriteLock(() -> { + incrementInUse(channel); + decrementIdle(channel); + channel.closeFuture().removeListener(closeListener); + }); - log.debug( "Channel [0x%s] acquired from the pool. Local address: %s, remote address: %s", channel.id(), channel.localAddress(), - channel.remoteAddress() ); + log.debug( + "Channel [0x%s] acquired from the pool. Local address: %s, remote address: %s", + channel.id(), channel.localAddress(), channel.remoteAddress()); } @Override - public void channelCreated( Channel channel ) - { - throw new IllegalStateException( "Untraceable channel created." ); + public void channelCreated(Channel channel) { + throw new IllegalStateException("Untraceable channel created."); } - public void channelCreated( Channel channel, ListenerEvent creatingEvent ) - { + public void channelCreated(Channel channel, ListenerEvent creatingEvent) { // when it is created, we count it as idle as it has not been acquired out of the pool - doInWriteLock( () -> incrementIdle( channel ) ); + doInWriteLock(() -> incrementIdle(channel)); - metricsListener.afterCreated( poolId( channel ), creatingEvent ); - allChannels.add( channel ); - log.debug( "Channel [0x%s] created. Local address: %s, remote address: %s", channel.id(), channel.localAddress(), channel.remoteAddress() ); + metricsListener.afterCreated(poolId(channel), creatingEvent); + allChannels.add(channel); + log.debug( + "Channel [0x%s] created. Local address: %s, remote address: %s", + channel.id(), channel.localAddress(), channel.remoteAddress()); } - public ListenerEvent channelCreating( String poolId ) - { + public ListenerEvent channelCreating(String poolId) { ListenerEvent creatingEvent = metricsListener.createListenerEvent(); - metricsListener.beforeCreating( poolId, creatingEvent ); + metricsListener.beforeCreating(poolId, creatingEvent); return creatingEvent; } - public void channelFailedToCreate( String poolId ) - { - metricsListener.afterFailedToCreate( poolId ); + public void channelFailedToCreate(String poolId) { + metricsListener.afterFailedToCreate(poolId); } - public void channelClosed( Channel channel ) - { - doInWriteLock( () -> decrementIdle( channel ) ); - metricsListener.afterClosed( poolId( channel ) ); + public void channelClosed(Channel channel) { + doInWriteLock(() -> decrementIdle(channel)); + metricsListener.afterClosed(poolId(channel)); } - public int inUseChannelCount( ServerAddress address ) - { - return retrieveInReadLock( () -> addressToInUseChannelCount.getOrDefault( address, 0 ) ); + public int inUseChannelCount(ServerAddress address) { + return retrieveInReadLock(() -> addressToInUseChannelCount.getOrDefault(address, 0)); } - public int idleChannelCount( ServerAddress address ) - { - return retrieveInReadLock( () -> addressToIdleChannelCount.getOrDefault( address, 0 ) ); + public int idleChannelCount(ServerAddress address) { + return retrieveInReadLock(() -> addressToIdleChannelCount.getOrDefault(address, 0)); } - public void prepareToCloseChannels() - { - for ( Channel channel : allChannels ) - { - BoltProtocol protocol = BoltProtocol.forChannel( channel ); - try - { - protocol.prepareToCloseChannel( channel ); - } - catch ( Throwable e ) - { + public void prepareToCloseChannels() { + for (Channel channel : allChannels) { + BoltProtocol protocol = BoltProtocol.forChannel(channel); + try { + protocol.prepareToCloseChannel(channel); + } catch (Throwable e) { // only logging it - log.debug( "Failed to prepare to close Channel %s due to error %s. " + - "It is safe to ignore this error as the channel will be closed despite if it is successfully prepared to close or not.", channel, - e.getMessage() ); + log.debug( + "Failed to prepare to close Channel %s due to error %s. " + + "It is safe to ignore this error as the channel will be closed despite if it is successfully prepared to close or not.", + channel, e.getMessage()); } } } - private void incrementInUse( Channel channel ) - { - increment( channel, addressToInUseChannelCount ); + private void incrementInUse(Channel channel) { + increment(channel, addressToInUseChannelCount); } - private void decrementInUse( Channel channel ) - { - BoltServerAddress address = serverAddress( channel ); - if ( !addressToInUseChannelCount.containsKey( address ) ) - { - throw new IllegalStateException( "No count exists for address '" + address + "' in the 'in use' count" ); + private void decrementInUse(Channel channel) { + BoltServerAddress address = serverAddress(channel); + if (!addressToInUseChannelCount.containsKey(address)) { + throw new IllegalStateException("No count exists for address '" + address + "' in the 'in use' count"); } - Integer count = addressToInUseChannelCount.get( address ); - addressToInUseChannelCount.put( address, count - 1 ); + Integer count = addressToInUseChannelCount.get(address); + addressToInUseChannelCount.put(address, count - 1); } - private void incrementIdle( Channel channel ) - { - increment( channel, addressToIdleChannelCount ); + private void incrementIdle(Channel channel) { + increment(channel, addressToIdleChannelCount); } - private void decrementIdle( Channel channel ) - { - BoltServerAddress address = serverAddress( channel ); - if ( !addressToIdleChannelCount.containsKey( address ) ) - { - throw new IllegalStateException( "No count exists for address '" + address + "' in the 'idle' count" ); + private void decrementIdle(Channel channel) { + BoltServerAddress address = serverAddress(channel); + if (!addressToIdleChannelCount.containsKey(address)) { + throw new IllegalStateException("No count exists for address '" + address + "' in the 'idle' count"); } - Integer count = addressToIdleChannelCount.get( address ); - addressToIdleChannelCount.put( address, count - 1 ); + Integer count = addressToIdleChannelCount.get(address); + addressToIdleChannelCount.put(address, count - 1); } - private void increment( Channel channel, Map countMap ) - { - ServerAddress address = serverAddress( channel ); - Integer count = countMap.computeIfAbsent( address, k -> 0 ); - countMap.put( address, count + 1 ); + private void increment(Channel channel, Map countMap) { + ServerAddress address = serverAddress(channel); + Integer count = countMap.computeIfAbsent(address, k -> 0); + countMap.put(address, count + 1); } } 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 1a3404e950..288eb717ac 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,29 +19,25 @@ package org.neo4j.driver.internal.async.pool; import io.netty.channel.Channel; - 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 -{ +public class NetworkConnectionFactory implements ConnectionFactory { private final Clock clock; private final MetricsListener metricsListener; private final Logging logging; - public NetworkConnectionFactory( Clock clock, MetricsListener metricsListener, Logging logging ) - { + public NetworkConnectionFactory(Clock clock, MetricsListener metricsListener, Logging logging) { this.clock = clock; this.metricsListener = metricsListener; this.logging = logging; } @Override - public Connection createConnection( Channel channel, ExtendedChannelPool pool ) - { - return new NetworkConnection( channel, pool, clock, metricsListener, logging ); + public Connection createConnection(Channel channel, ExtendedChannelPool pool) { + return new NetworkConnection(channel, pool, clock, metricsListener, logging); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/PoolSettings.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/PoolSettings.java index 8bc838cac6..6ac5b1b5c7 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/PoolSettings.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/PoolSettings.java @@ -20,56 +20,51 @@ import java.util.concurrent.TimeUnit; -public class PoolSettings -{ +public class PoolSettings { public static final int NOT_CONFIGURED = -1; public static final int DEFAULT_MAX_CONNECTION_POOL_SIZE = 100; public static final long DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST = NOT_CONFIGURED; - public static final long DEFAULT_MAX_CONNECTION_LIFETIME = TimeUnit.HOURS.toMillis( 1 ); - public static final long DEFAULT_CONNECTION_ACQUISITION_TIMEOUT = TimeUnit.SECONDS.toMillis( 60 ); + public static final long DEFAULT_MAX_CONNECTION_LIFETIME = TimeUnit.HOURS.toMillis(1); + public static final long DEFAULT_CONNECTION_ACQUISITION_TIMEOUT = TimeUnit.SECONDS.toMillis(60); private final int maxConnectionPoolSize; private final long connectionAcquisitionTimeout; private final long maxConnectionLifetime; private final long idleTimeBeforeConnectionTest; - public PoolSettings( int maxConnectionPoolSize, long connectionAcquisitionTimeout, - long maxConnectionLifetime, long idleTimeBeforeConnectionTest ) - { + public PoolSettings( + int maxConnectionPoolSize, + long connectionAcquisitionTimeout, + long maxConnectionLifetime, + long idleTimeBeforeConnectionTest) { this.maxConnectionPoolSize = maxConnectionPoolSize; this.connectionAcquisitionTimeout = connectionAcquisitionTimeout; this.maxConnectionLifetime = maxConnectionLifetime; this.idleTimeBeforeConnectionTest = idleTimeBeforeConnectionTest; } - public long idleTimeBeforeConnectionTest() - { + public long idleTimeBeforeConnectionTest() { return idleTimeBeforeConnectionTest; } - public boolean idleTimeBeforeConnectionTestEnabled() - { + public boolean idleTimeBeforeConnectionTestEnabled() { return idleTimeBeforeConnectionTest >= 0; } - public long maxConnectionLifetime() - { + public long maxConnectionLifetime() { return maxConnectionLifetime; } - public boolean maxConnectionLifetimeEnabled() - { + public boolean maxConnectionLifetimeEnabled() { return maxConnectionLifetime > 0; } - public int maxConnectionPoolSize() - { + public int maxConnectionPoolSize() { return maxConnectionPoolSize; } - public long connectionAcquisitionTimeout() - { + public long connectionAcquisitionTimeout() { return connectionAcquisitionTimeout; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterComposition.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterComposition.java index 4083fff4c8..ace8add911 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterComposition.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterComposition.java @@ -22,15 +22,14 @@ import java.util.Objects; import java.util.Set; import java.util.function.Function; - import org.neo4j.driver.Record; import org.neo4j.driver.Value; import org.neo4j.driver.internal.BoltServerAddress; -public final class ClusterComposition -{ +public final class ClusterComposition { private static final long MAX_TTL = Long.MAX_VALUE / 1000L; - private static final Function OF_BoltServerAddress = value -> new BoltServerAddress( value.asString() ); + private static final Function OF_BoltServerAddress = + value -> new BoltServerAddress(value.asString()); private final Set readers; private final Set writers; @@ -38,8 +37,7 @@ public final class ClusterComposition private final long expirationTimestamp; private final String databaseName; - private ClusterComposition( long expirationTimestamp, String databaseName ) - { + private ClusterComposition(long expirationTimestamp, String databaseName) { this.readers = new LinkedHashSet<>(); this.writers = new LinkedHashSet<>(); this.routers = new LinkedHashSet<>(); @@ -55,126 +53,106 @@ public ClusterComposition( Set readers, Set writers, Set routers, - String databaseName ) - { - this( expirationTimestamp, databaseName ); - this.readers.addAll( readers ); - this.writers.addAll( writers ); - this.routers.addAll( routers ); + String databaseName) { + this(expirationTimestamp, databaseName); + this.readers.addAll(readers); + this.writers.addAll(writers); + this.routers.addAll(routers); } - public boolean hasWriters() - { + public boolean hasWriters() { return !writers.isEmpty(); } - public boolean hasRoutersAndReaders() - { + public boolean hasRoutersAndReaders() { return !routers.isEmpty() && !readers.isEmpty(); } - public Set readers() - { - return new LinkedHashSet<>( readers ); + public Set readers() { + return new LinkedHashSet<>(readers); } - public Set writers() - { - return new LinkedHashSet<>( writers ); + public Set writers() { + return new LinkedHashSet<>(writers); } - public Set routers() - { - return new LinkedHashSet<>( routers ); + public Set routers() { + return new LinkedHashSet<>(routers); } - public long expirationTimestamp() - { + public long expirationTimestamp() { return this.expirationTimestamp; } - public String databaseName() - { + public String databaseName() { return databaseName; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } ClusterComposition that = (ClusterComposition) o; - return expirationTimestamp == that.expirationTimestamp && - Objects.equals( databaseName, that.databaseName ) && - Objects.equals( readers, that.readers ) && - Objects.equals( writers, that.writers ) && - Objects.equals( routers, that.routers ); + return expirationTimestamp == that.expirationTimestamp + && Objects.equals(databaseName, that.databaseName) + && Objects.equals(readers, that.readers) + && Objects.equals(writers, that.writers) + && Objects.equals(routers, that.routers); } @Override - public int hashCode() - { - return Objects.hash( readers, writers, routers, expirationTimestamp, databaseName ); + public int hashCode() { + return Objects.hash(readers, writers, routers, expirationTimestamp, databaseName); } @Override - public String toString() - { - return "ClusterComposition{" + - "readers=" + readers + - ", writers=" + writers + - ", routers=" + routers + - ", expirationTimestamp=" + expirationTimestamp + - ", databaseName=" + databaseName + - '}'; + public String toString() { + return "ClusterComposition{" + "readers=" + + readers + ", writers=" + + writers + ", routers=" + + routers + ", expirationTimestamp=" + + expirationTimestamp + ", databaseName=" + + databaseName + '}'; } - public static ClusterComposition parse( Record record, long now ) - { - if ( record == null ) - { + public static ClusterComposition parse(Record record, long now) { + if (record == null) { return null; } - final ClusterComposition result = new ClusterComposition( expirationTimestamp( now, record ), record.get( "db" ).asString( null ) ); - record.get( "servers" ).asList( (Function) value -> - { - result.servers( value.get( "role" ).asString() ) - .addAll( value.get( "addresses" ).asList( OF_BoltServerAddress ) ); + final ClusterComposition result = new ClusterComposition( + expirationTimestamp(now, record), record.get("db").asString(null)); + record.get("servers").asList((Function) value -> { + result.servers(value.get("role").asString()) + .addAll(value.get("addresses").asList(OF_BoltServerAddress)); return null; - } ); + }); return result; } - private static long expirationTimestamp( long now, Record record ) - { - long ttl = record.get( "ttl" ).asLong(); + private static long expirationTimestamp(long now, Record record) { + long ttl = record.get("ttl").asLong(); long expirationTimestamp = now + ttl * 1000; - if ( ttl < 0 || ttl >= MAX_TTL || expirationTimestamp < 0 ) - { + if (ttl < 0 || ttl >= MAX_TTL || expirationTimestamp < 0) { expirationTimestamp = Long.MAX_VALUE; } return expirationTimestamp; } - private Set servers( String role ) - { - switch ( role ) - { - case "READ": - return readers; - case "WRITE": - return writers; - case "ROUTE": - return routers; - default: - throw new IllegalArgumentException( "invalid server role: " + role ); + private Set servers(String role) { + switch (role) { + case "READ": + return readers; + case "WRITE": + return writers; + case "ROUTE": + return routers; + default: + throw new IllegalArgumentException("invalid server role: " + role); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterCompositionLookupResult.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterCompositionLookupResult.java index a374918089..d3681de5a2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterCompositionLookupResult.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterCompositionLookupResult.java @@ -20,33 +20,28 @@ import java.util.Optional; import java.util.Set; - import org.neo4j.driver.internal.BoltServerAddress; -public class ClusterCompositionLookupResult -{ +public class ClusterCompositionLookupResult { private final ClusterComposition composition; private final Set resolvedInitialRouters; - public ClusterCompositionLookupResult( ClusterComposition composition ) - { - this( composition, null ); + public ClusterCompositionLookupResult(ClusterComposition composition) { + this(composition, null); } - public ClusterCompositionLookupResult( ClusterComposition composition, Set resolvedInitialRouters ) - { + public ClusterCompositionLookupResult( + ClusterComposition composition, Set resolvedInitialRouters) { this.composition = composition; this.resolvedInitialRouters = resolvedInitialRouters; } - public ClusterComposition getClusterComposition() - { + public ClusterComposition getClusterComposition() { return composition; } - public Optional> getResolvedInitialRouters() - { - return Optional.ofNullable( resolvedInitialRouters ); + public Optional> getResolvedInitialRouters() { + return Optional.ofNullable(resolvedInitialRouters); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterCompositionProvider.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterCompositionProvider.java index e71f800cd5..e9b34b23ed 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterCompositionProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/ClusterCompositionProvider.java @@ -19,12 +19,11 @@ package org.neo4j.driver.internal.cluster; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.internal.DatabaseName; import org.neo4j.driver.internal.spi.Connection; -public interface ClusterCompositionProvider -{ - CompletionStage getClusterComposition( Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser ); +public interface ClusterCompositionProvider { + CompletionStage getClusterComposition( + Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser); } 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 15c015d013..43f91237be 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 @@ -18,6 +18,10 @@ */ package org.neo4j.driver.internal.cluster; +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static org.neo4j.driver.internal.util.LockUtil.executeWithLock; + import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -27,18 +31,12 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; import java.util.stream.Stream; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DatabaseName; import org.neo4j.driver.internal.util.Clock; -import static java.lang.String.format; -import static java.util.Arrays.asList; -import static org.neo4j.driver.internal.util.LockUtil.executeWithLock; - -public class ClusterRoutingTable implements RoutingTable -{ +public class ClusterRoutingTable implements RoutingTable { private static final int MIN_ROUTERS = 1; private final ReadWriteLock tableLock = new ReentrantReadWriteLock(); @@ -52,176 +50,157 @@ public class ClusterRoutingTable implements RoutingTable private List writers = Collections.emptyList(); private List routers = Collections.emptyList(); - public ClusterRoutingTable( DatabaseName ofDatabase, Clock clock, BoltServerAddress... routingAddresses ) - { - this( ofDatabase, clock ); - routers = Collections.unmodifiableList( asList( routingAddresses ) ); + public ClusterRoutingTable(DatabaseName ofDatabase, Clock clock, BoltServerAddress... routingAddresses) { + this(ofDatabase, clock); + routers = Collections.unmodifiableList(asList(routingAddresses)); } - private ClusterRoutingTable( DatabaseName ofDatabase, Clock clock ) - { + private ClusterRoutingTable(DatabaseName ofDatabase, Clock clock) { this.databaseName = ofDatabase; this.clock = clock; this.expirationTimestamp = clock.millis() - 1; } @Override - public boolean isStaleFor( AccessMode mode ) - { - return executeWithLock( tableLock.readLock(), () -> - expirationTimestamp < clock.millis() || - routers.size() < MIN_ROUTERS || - mode == AccessMode.READ && readers.size() == 0 || - mode == AccessMode.WRITE && writers.size() == 0 ); + public boolean isStaleFor(AccessMode mode) { + return executeWithLock( + tableLock.readLock(), + () -> expirationTimestamp < clock.millis() + || routers.size() < MIN_ROUTERS + || mode == AccessMode.READ && readers.size() == 0 + || mode == AccessMode.WRITE && writers.size() == 0); } @Override - public boolean hasBeenStaleFor( long extraTime ) - { - long totalTime = executeWithLock( tableLock.readLock(), () -> expirationTimestamp ) + extraTime; - if ( totalTime < 0 ) - { + public boolean hasBeenStaleFor(long extraTime) { + long totalTime = executeWithLock(tableLock.readLock(), () -> expirationTimestamp) + extraTime; + if (totalTime < 0) { totalTime = Long.MAX_VALUE; } return totalTime < clock.millis(); } @Override - public void update( ClusterComposition cluster ) - { - executeWithLock( tableLock.writeLock(), () -> - { + public void update(ClusterComposition cluster) { + executeWithLock(tableLock.writeLock(), () -> { expirationTimestamp = cluster.expirationTimestamp(); - readers = newWithReusedAddresses( readers, disused, cluster.readers() ); - writers = newWithReusedAddresses( writers, disused, cluster.writers() ); - routers = newWithReusedAddresses( routers, disused, cluster.routers() ); + readers = newWithReusedAddresses(readers, disused, cluster.readers()); + writers = newWithReusedAddresses(writers, disused, cluster.writers()); + routers = newWithReusedAddresses(routers, disused, cluster.routers()); disused.clear(); preferInitialRouter = !cluster.hasWriters(); - } ); + }); } @Override - public void forget( BoltServerAddress address ) - { - executeWithLock( tableLock.writeLock(), () -> - { - routers = newWithoutAddressIfPresent( routers, address ); - readers = newWithoutAddressIfPresent( readers, address ); - writers = newWithoutAddressIfPresent( writers, address ); - disused.add( address ); - } ); + public void forget(BoltServerAddress address) { + executeWithLock(tableLock.writeLock(), () -> { + routers = newWithoutAddressIfPresent(routers, address); + readers = newWithoutAddressIfPresent(readers, address); + writers = newWithoutAddressIfPresent(writers, address); + disused.add(address); + }); } @Override - public List readers() - { - return executeWithLock( tableLock.readLock(), () -> readers ); + public List readers() { + return executeWithLock(tableLock.readLock(), () -> readers); } @Override - public List writers() - { - return executeWithLock( tableLock.readLock(), () -> writers ); + public List writers() { + return executeWithLock(tableLock.readLock(), () -> writers); } @Override - public List routers() - { - return executeWithLock( tableLock.readLock(), () -> routers ); + public List routers() { + return executeWithLock(tableLock.readLock(), () -> routers); } @Override - public Set servers() - { - return executeWithLock( tableLock.readLock(), () -> - { + public Set servers() { + return executeWithLock(tableLock.readLock(), () -> { Set servers = new HashSet<>(); - servers.addAll( readers ); - servers.addAll( writers ); - servers.addAll( routers ); - servers.addAll( disused ); + servers.addAll(readers); + servers.addAll(writers); + servers.addAll(routers); + servers.addAll(disused); return servers; - } ); + }); } @Override - public DatabaseName database() - { + public DatabaseName database() { return databaseName; } @Override - public void forgetWriter( BoltServerAddress toRemove ) - { - executeWithLock( tableLock.writeLock(), () -> - { - writers = newWithoutAddressIfPresent( writers, toRemove ); - disused.add( toRemove ); - } ); + public void forgetWriter(BoltServerAddress toRemove) { + executeWithLock(tableLock.writeLock(), () -> { + writers = newWithoutAddressIfPresent(writers, toRemove); + disused.add(toRemove); + }); } @Override - public void replaceRouterIfPresent( BoltServerAddress oldRouter, BoltServerAddress newRouter ) - { - executeWithLock( tableLock.writeLock(), () -> routers = newWithAddressReplacedIfPresent( routers, oldRouter, newRouter ) ); + public void replaceRouterIfPresent(BoltServerAddress oldRouter, BoltServerAddress newRouter) { + executeWithLock( + tableLock.writeLock(), () -> routers = newWithAddressReplacedIfPresent(routers, oldRouter, newRouter)); } @Override - public boolean preferInitialRouter() - { - return executeWithLock( tableLock.readLock(), () -> preferInitialRouter ); + public boolean preferInitialRouter() { + return executeWithLock(tableLock.readLock(), () -> preferInitialRouter); } @Override - public long expirationTimestamp() - { - return executeWithLock( tableLock.readLock(), () -> expirationTimestamp ); + public long expirationTimestamp() { + return executeWithLock(tableLock.readLock(), () -> expirationTimestamp); } @Override - public String toString() - { - return executeWithLock( tableLock.readLock(), () -> - format( "Ttl %s, currentTime %s, routers %s, writers %s, readers %s, database '%s'", - expirationTimestamp, clock.millis(), routers, writers, readers, databaseName.description() ) ); - } - - private List newWithoutAddressIfPresent( List addresses, BoltServerAddress addressToSkip ) - { - List newList = new ArrayList<>( addresses.size() ); - for ( BoltServerAddress address : addresses ) - { - if ( !address.equals( addressToSkip ) ) - { - newList.add( address ); + public String toString() { + return executeWithLock( + tableLock.readLock(), + () -> format( + "Ttl %s, currentTime %s, routers %s, writers %s, readers %s, database '%s'", + expirationTimestamp, clock.millis(), routers, writers, readers, databaseName.description())); + } + + private List newWithoutAddressIfPresent( + List addresses, BoltServerAddress addressToSkip) { + List newList = new ArrayList<>(addresses.size()); + for (BoltServerAddress address : addresses) { + if (!address.equals(addressToSkip)) { + newList.add(address); } } - return Collections.unmodifiableList( newList ); + return Collections.unmodifiableList(newList); } - private List newWithAddressReplacedIfPresent( List addresses, BoltServerAddress oldAddress, - BoltServerAddress newAddress ) - { - List newList = new ArrayList<>( addresses.size() ); - for ( BoltServerAddress address : addresses ) - { - newList.add( address.equals( oldAddress ) ? newAddress : address ); + private List newWithAddressReplacedIfPresent( + List addresses, BoltServerAddress oldAddress, BoltServerAddress newAddress) { + List newList = new ArrayList<>(addresses.size()); + for (BoltServerAddress address : addresses) { + newList.add(address.equals(oldAddress) ? newAddress : address); } - return Collections.unmodifiableList( newList ); + return Collections.unmodifiableList(newList); } - private List newWithReusedAddresses( List currentAddresses, Set disusedAddresses, - Set newAddresses ) - { - List newList = Stream.concat( currentAddresses.stream(), disusedAddresses.stream() ) - .filter( address -> newAddresses.remove( toBoltServerAddress( address ) ) ) - .collect( Collectors.toCollection( () -> new ArrayList<>( newAddresses.size() ) ) ); - newList.addAll( newAddresses ); - return Collections.unmodifiableList( newList ); + private List newWithReusedAddresses( + List currentAddresses, + Set disusedAddresses, + Set newAddresses) { + List newList = Stream.concat(currentAddresses.stream(), disusedAddresses.stream()) + .filter(address -> newAddresses.remove(toBoltServerAddress(address))) + .collect(Collectors.toCollection(() -> new ArrayList<>(newAddresses.size()))); + newList.addAll(newAddresses); + return Collections.unmodifiableList(newList); } - private BoltServerAddress toBoltServerAddress( BoltServerAddress address ) - { - return BoltServerAddress.class.equals( address.getClass() ) ? address : new BoltServerAddress( address.host(), address.port() ); + private BoltServerAddress toBoltServerAddress(BoltServerAddress address) { + return BoltServerAddress.class.equals(address.getClass()) + ? address + : new BoltServerAddress(address.host(), address.port()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/IdentityResolver.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/IdentityResolver.java index bfbe071f38..26bcc15308 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/IdentityResolver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/IdentityResolver.java @@ -18,24 +18,19 @@ */ package org.neo4j.driver.internal.cluster; -import java.util.Set; +import static java.util.Collections.singleton; +import java.util.Set; import org.neo4j.driver.net.ServerAddress; import org.neo4j.driver.net.ServerAddressResolver; -import static java.util.Collections.singleton; - -public class IdentityResolver implements ServerAddressResolver -{ +public class IdentityResolver implements ServerAddressResolver { public static final IdentityResolver IDENTITY_RESOLVER = new IdentityResolver(); - private IdentityResolver() - { - } + private IdentityResolver() {} @Override - public Set resolve( ServerAddress initialRouter ) - { - return singleton( initialRouter ); + public Set resolve(ServerAddress initialRouter) { + return singleton(initialRouter); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/MultiDatabasesRoutingProcedureRunner.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/MultiDatabasesRoutingProcedureRunner.java index 43a054a227..e20e4b9016 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/MultiDatabasesRoutingProcedureRunner.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/MultiDatabasesRoutingProcedureRunner.java @@ -18,8 +18,10 @@ */ package org.neo4j.driver.internal.cluster; -import java.util.HashMap; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.systemDatabase; +import java.util.HashMap; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -31,42 +33,34 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.ServerVersion; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.systemDatabase; - - /** * This implementation of the {@link RoutingProcedureRunner} works with multi database versions of Neo4j calling * the procedure `dbms.routing.getRoutingTable` */ -public class MultiDatabasesRoutingProcedureRunner extends SingleDatabaseRoutingProcedureRunner -{ +public class MultiDatabasesRoutingProcedureRunner extends SingleDatabaseRoutingProcedureRunner { static final String DATABASE_NAME = "database"; - static final String MULTI_DB_GET_ROUTING_TABLE = String.format( "CALL dbms.routing.getRoutingTable($%s, $%s)", ROUTING_CONTEXT, DATABASE_NAME ); + static final String MULTI_DB_GET_ROUTING_TABLE = + String.format("CALL dbms.routing.getRoutingTable($%s, $%s)", ROUTING_CONTEXT, DATABASE_NAME); - public MultiDatabasesRoutingProcedureRunner( RoutingContext context ) - { - super( context ); + public MultiDatabasesRoutingProcedureRunner(RoutingContext context) { + super(context); } @Override - BookmarkHolder bookmarkHolder( Bookmark bookmark ) - { - return new ReadOnlyBookmarkHolder( bookmark ); + BookmarkHolder bookmarkHolder(Bookmark bookmark) { + return new ReadOnlyBookmarkHolder(bookmark); } @Override - Query procedureQuery(ServerVersion serverVersion, DatabaseName databaseName ) - { - HashMap map = new HashMap<>(); - map.put( ROUTING_CONTEXT, value( context.toMap() ) ); - map.put( DATABASE_NAME, value( (Object) databaseName.databaseName().orElse( null ) ) ); - return new Query( MULTI_DB_GET_ROUTING_TABLE, value( map ) ); + Query procedureQuery(ServerVersion serverVersion, DatabaseName databaseName) { + HashMap map = new HashMap<>(); + map.put(ROUTING_CONTEXT, value(context.toMap())); + map.put(DATABASE_NAME, value((Object) databaseName.databaseName().orElse(null))); + return new Query(MULTI_DB_GET_ROUTING_TABLE, value(map)); } @Override - DirectConnection connection( Connection connection ) - { - return new DirectConnection( connection, systemDatabase(), AccessMode.READ, null ); + DirectConnection connection(Connection connection) { + return new DirectConnection(connection, systemDatabase(), AccessMode.READ, null); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java index abd5ddc784..49b7e54338 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/Rediscovery.java @@ -21,7 +21,6 @@ import java.net.UnknownHostException; import java.util.List; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.spi.ConnectionPool; @@ -29,8 +28,7 @@ /** * Provides cluster composition lookup capabilities and initial router address resolution. */ -public interface Rediscovery -{ +public interface Rediscovery { /** * Fetches cluster composition using the provided routing table. *

@@ -42,8 +40,8 @@ public interface Rediscovery * @param impersonatedUser the impersonated user for cluster composition lookup, should be {@code null} for non-impersonated requests * @return cluster composition lookup result */ - CompletionStage lookupClusterComposition( RoutingTable routingTable, ConnectionPool connectionPool, Bookmark bookmark, - String impersonatedUser ); + CompletionStage lookupClusterComposition( + RoutingTable routingTable, ConnectionPool connectionPool, Bookmark bookmark, String impersonatedUser); List resolve() throws UnknownHostException; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java index 368711e036..1827a75a67 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RediscoveryImpl.java @@ -18,8 +18,14 @@ */ package org.neo4j.driver.internal.cluster; -import io.netty.util.concurrent.EventExecutorGroup; +import static java.lang.String.format; +import static java.util.Collections.emptySet; +import static java.util.Objects.requireNonNull; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; +import io.netty.util.concurrent.EventExecutorGroup; import java.net.UnknownHostException; import java.util.Collection; import java.util.HashSet; @@ -30,7 +36,6 @@ import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeUnit; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; @@ -49,20 +54,14 @@ import org.neo4j.driver.net.ServerAddress; import org.neo4j.driver.net.ServerAddressResolver; -import static java.lang.String.format; -import static java.util.Collections.emptySet; -import static java.util.Objects.requireNonNull; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; - -public class RediscoveryImpl implements Rediscovery -{ - private static final String NO_ROUTERS_AVAILABLE = "Could not perform discovery for database '%s'. No routing server available."; +public class RediscoveryImpl implements Rediscovery { + private static final String NO_ROUTERS_AVAILABLE = + "Could not perform discovery for database '%s'. No routing server available."; private static final String RECOVERABLE_ROUTING_ERROR = "Failed to update routing table with server '%s'."; - private static final String RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER = "Received a recoverable discovery error with server '%s', " + - "will continue discovery with other routing servers if available. " + - "Complete failure is reported separately from this entry."; + private static final String RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER = + "Received a recoverable discovery error with server '%s', " + + "will continue discovery with other routing servers if available. " + + "Complete failure is reported separately from this entry."; private static final String INVALID_BOOKMARK_CODE = "Neo.ClientError.Transaction.InvalidBookmark"; private static final String INVALID_BOOKMARK_MIXTURE_CODE = "Neo.ClientError.Transaction.InvalidBookmarkMixture"; @@ -74,16 +73,21 @@ public class RediscoveryImpl implements Rediscovery private final EventExecutorGroup eventExecutorGroup; private final DomainNameResolver domainNameResolver; - public RediscoveryImpl( BoltServerAddress initialRouter, RoutingSettings settings, ClusterCompositionProvider provider, - EventExecutorGroup eventExecutorGroup, ServerAddressResolver resolver, Logging logging, DomainNameResolver domainNameResolver ) - { + public RediscoveryImpl( + BoltServerAddress initialRouter, + RoutingSettings settings, + ClusterCompositionProvider provider, + EventExecutorGroup eventExecutorGroup, + ServerAddressResolver resolver, + Logging logging, + DomainNameResolver domainNameResolver) { this.initialRouter = initialRouter; this.settings = settings; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); this.provider = provider; this.resolver = resolver; this.eventExecutorGroup = eventExecutorGroup; - this.domainNameResolver = requireNonNull( domainNameResolver ); + this.domainNameResolver = requireNonNull(domainNameResolver); } /** @@ -95,295 +99,284 @@ public RediscoveryImpl( BoltServerAddress initialRouter, RoutingSettings setting * @return new cluster composition and an optional set of resolved initial router addresses. */ @Override - public CompletionStage lookupClusterComposition( RoutingTable routingTable, ConnectionPool connectionPool, - Bookmark bookmark, String impersonatedUser ) - { + public CompletionStage lookupClusterComposition( + RoutingTable routingTable, ConnectionPool connectionPool, Bookmark bookmark, String impersonatedUser) { CompletableFuture result = new CompletableFuture<>(); // if we failed discovery, we will chain all errors into this one. - ServiceUnavailableException baseError = new ServiceUnavailableException( String.format( NO_ROUTERS_AVAILABLE, routingTable.database().description() ) ); - lookupClusterComposition( routingTable, connectionPool, 0, 0, result, bookmark, impersonatedUser, baseError ); + ServiceUnavailableException baseError = new ServiceUnavailableException( + String.format(NO_ROUTERS_AVAILABLE, routingTable.database().description())); + lookupClusterComposition(routingTable, connectionPool, 0, 0, result, bookmark, impersonatedUser, baseError); return result; } - private void lookupClusterComposition( RoutingTable routingTable, ConnectionPool pool, int failures, long previousDelay, - CompletableFuture result, Bookmark bookmark, String impersonatedUser, - Throwable baseError ) - { - lookup( routingTable, pool, bookmark, impersonatedUser, baseError ) - .whenComplete( - ( compositionLookupResult, completionError ) -> - { - Throwable error = Futures.completionExceptionCause( completionError ); - if ( error != null ) - { - result.completeExceptionally( error ); - } - else if ( compositionLookupResult != null ) - { - result.complete( compositionLookupResult ); - } - else - { - int newFailures = failures + 1; - if ( newFailures >= settings.maxRoutingFailures() ) - { - // now we throw our saved error out - result.completeExceptionally( baseError ); - } - else - { - long nextDelay = Math.max( settings.retryTimeoutDelay(), previousDelay * 2 ); - log.info( "Unable to fetch new routing table, will try again in " + nextDelay + "ms" ); - eventExecutorGroup.next().schedule( - () -> lookupClusterComposition( routingTable, pool, newFailures, nextDelay, result, bookmark, impersonatedUser, - baseError ), - nextDelay, TimeUnit.MILLISECONDS - ); - } - } - } ); + private void lookupClusterComposition( + RoutingTable routingTable, + ConnectionPool pool, + int failures, + long previousDelay, + CompletableFuture result, + Bookmark bookmark, + String impersonatedUser, + Throwable baseError) { + lookup(routingTable, pool, bookmark, impersonatedUser, baseError) + .whenComplete((compositionLookupResult, completionError) -> { + Throwable error = Futures.completionExceptionCause(completionError); + if (error != null) { + result.completeExceptionally(error); + } else if (compositionLookupResult != null) { + result.complete(compositionLookupResult); + } else { + int newFailures = failures + 1; + if (newFailures >= settings.maxRoutingFailures()) { + // now we throw our saved error out + result.completeExceptionally(baseError); + } else { + long nextDelay = Math.max(settings.retryTimeoutDelay(), previousDelay * 2); + log.info("Unable to fetch new routing table, will try again in " + nextDelay + "ms"); + eventExecutorGroup + .next() + .schedule( + () -> lookupClusterComposition( + routingTable, + pool, + newFailures, + nextDelay, + result, + bookmark, + impersonatedUser, + baseError), + nextDelay, + TimeUnit.MILLISECONDS); + } + } + }); } - private CompletionStage lookup( RoutingTable routingTable, ConnectionPool connectionPool, Bookmark bookmark, - String impersonatedUser, Throwable baseError ) - { + private CompletionStage lookup( + RoutingTable routingTable, + ConnectionPool connectionPool, + Bookmark bookmark, + String impersonatedUser, + Throwable baseError) { CompletionStage compositionStage; - if ( routingTable.preferInitialRouter() ) - { - compositionStage = lookupOnInitialRouterThenOnKnownRouters( routingTable, connectionPool, bookmark, impersonatedUser, baseError ); - } - else - { - compositionStage = lookupOnKnownRoutersThenOnInitialRouter( routingTable, connectionPool, bookmark, impersonatedUser, baseError ); + if (routingTable.preferInitialRouter()) { + compositionStage = lookupOnInitialRouterThenOnKnownRouters( + routingTable, connectionPool, bookmark, impersonatedUser, baseError); + } else { + compositionStage = lookupOnKnownRoutersThenOnInitialRouter( + routingTable, connectionPool, bookmark, impersonatedUser, baseError); } return compositionStage; } - private CompletionStage lookupOnKnownRoutersThenOnInitialRouter( RoutingTable routingTable, ConnectionPool connectionPool, - Bookmark bookmark, String impersonatedUser, - Throwable baseError ) - { + private CompletionStage lookupOnKnownRoutersThenOnInitialRouter( + RoutingTable routingTable, + ConnectionPool connectionPool, + Bookmark bookmark, + String impersonatedUser, + Throwable baseError) { Set seenServers = new HashSet<>(); - return lookupOnKnownRouters( routingTable, connectionPool, seenServers, bookmark, impersonatedUser, baseError ) - .thenCompose( - compositionLookupResult -> - { - if ( compositionLookupResult != null ) - { - return completedFuture( - compositionLookupResult ); - } - return lookupOnInitialRouter( routingTable, connectionPool, seenServers, bookmark, impersonatedUser, baseError ); - } ); + return lookupOnKnownRouters(routingTable, connectionPool, seenServers, bookmark, impersonatedUser, baseError) + .thenCompose(compositionLookupResult -> { + if (compositionLookupResult != null) { + return completedFuture(compositionLookupResult); + } + return lookupOnInitialRouter( + routingTable, connectionPool, seenServers, bookmark, impersonatedUser, baseError); + }); } - private CompletionStage lookupOnInitialRouterThenOnKnownRouters( RoutingTable routingTable, ConnectionPool connectionPool, - Bookmark bookmark, String impersonatedUser, - Throwable baseError ) - { + private CompletionStage lookupOnInitialRouterThenOnKnownRouters( + RoutingTable routingTable, + ConnectionPool connectionPool, + Bookmark bookmark, + String impersonatedUser, + Throwable baseError) { Set seenServers = emptySet(); - return lookupOnInitialRouter( routingTable, connectionPool, seenServers, bookmark, impersonatedUser, baseError ) - .thenCompose( - compositionLookupResult -> - { - if ( compositionLookupResult != null ) - { - return completedFuture( - compositionLookupResult ); - } - return lookupOnKnownRouters( routingTable, connectionPool, new HashSet<>(), bookmark, impersonatedUser, baseError ); - } ); + return lookupOnInitialRouter(routingTable, connectionPool, seenServers, bookmark, impersonatedUser, baseError) + .thenCompose(compositionLookupResult -> { + if (compositionLookupResult != null) { + return completedFuture(compositionLookupResult); + } + return lookupOnKnownRouters( + routingTable, connectionPool, new HashSet<>(), bookmark, impersonatedUser, baseError); + }); } - private CompletionStage lookupOnKnownRouters( RoutingTable routingTable, ConnectionPool connectionPool, - Set seenServers, Bookmark bookmark, - String impersonatedUser, Throwable baseError ) - { + private CompletionStage lookupOnKnownRouters( + RoutingTable routingTable, + ConnectionPool connectionPool, + Set seenServers, + Bookmark bookmark, + String impersonatedUser, + Throwable baseError) { CompletableFuture result = completedWithNull(); - for ( BoltServerAddress address : routingTable.routers() ) - { - result = result - .thenCompose( - composition -> - { - if ( composition != null ) - { - return completedFuture( composition ); - } - else - { - return lookupOnRouter( address, true, routingTable, connectionPool, seenServers, bookmark, impersonatedUser, baseError ); - } - } ); + for (BoltServerAddress address : routingTable.routers()) { + result = result.thenCompose(composition -> { + if (composition != null) { + return completedFuture(composition); + } else { + return lookupOnRouter( + address, + true, + routingTable, + connectionPool, + seenServers, + bookmark, + impersonatedUser, + baseError); + } + }); } - return result.thenApply( composition -> composition != null ? new ClusterCompositionLookupResult( composition ) : null ); + return result.thenApply( + composition -> composition != null ? new ClusterCompositionLookupResult(composition) : null); } - private CompletionStage lookupOnInitialRouter( RoutingTable routingTable, ConnectionPool connectionPool, - Set seenServers, Bookmark bookmark, - String impersonatedUser, Throwable baseError ) - { + private CompletionStage lookupOnInitialRouter( + RoutingTable routingTable, + ConnectionPool connectionPool, + Set seenServers, + Bookmark bookmark, + String impersonatedUser, + Throwable baseError) { List resolvedRouters; - try - { + try { resolvedRouters = resolve(); + } catch (Throwable error) { + return failedFuture(error); } - catch ( Throwable error ) - { - return failedFuture( error ); - } - Set resolvedRouterSet = new HashSet<>( resolvedRouters ); - resolvedRouters.removeAll( seenServers ); + Set resolvedRouterSet = new HashSet<>(resolvedRouters); + resolvedRouters.removeAll(seenServers); CompletableFuture result = completedWithNull(); - for ( BoltServerAddress address : resolvedRouters ) - { - result = result.thenCompose( - composition -> - { - if ( composition != null ) - { - return completedFuture( composition ); - } - return lookupOnRouter( address, false, routingTable, connectionPool, null, bookmark, impersonatedUser, baseError ); - } ); + for (BoltServerAddress address : resolvedRouters) { + result = result.thenCompose(composition -> { + if (composition != null) { + return completedFuture(composition); + } + return lookupOnRouter( + address, false, routingTable, connectionPool, null, bookmark, impersonatedUser, baseError); + }); } - return result.thenApply( composition -> composition != null ? new ClusterCompositionLookupResult( composition, resolvedRouterSet ) : null ); + return result.thenApply(composition -> + composition != null ? new ClusterCompositionLookupResult(composition, resolvedRouterSet) : null); } - private CompletionStage lookupOnRouter( BoltServerAddress routerAddress, boolean resolveAddress, RoutingTable routingTable, - ConnectionPool connectionPool, Set seenServers, Bookmark bookmark, - String impersonatedUser, Throwable baseError ) - { - CompletableFuture addressFuture = CompletableFuture.completedFuture( routerAddress ); + private CompletionStage lookupOnRouter( + BoltServerAddress routerAddress, + boolean resolveAddress, + RoutingTable routingTable, + ConnectionPool connectionPool, + Set seenServers, + Bookmark bookmark, + String impersonatedUser, + Throwable baseError) { + CompletableFuture addressFuture = CompletableFuture.completedFuture(routerAddress); return addressFuture - .thenApply( address -> resolveAddress ? resolveByDomainNameOrThrowCompletionException( address, routingTable ) : address ) - .thenApply( address -> addAndReturn( seenServers, address ) ) - .thenCompose( connectionPool::acquire ) - .thenApply( connection -> ImpersonationUtil.ensureImpersonationSupport( connection, impersonatedUser ) ) - .thenCompose( connection -> provider.getClusterComposition( connection, routingTable.database(), bookmark, impersonatedUser ) ) - .handle( ( response, error ) -> - { - Throwable cause = Futures.completionExceptionCause( error ); - if ( cause != null ) - { - return handleRoutingProcedureError( cause, routingTable, routerAddress, baseError ); - } - else - { - return response; - } - } ); + .thenApply(address -> + resolveAddress ? resolveByDomainNameOrThrowCompletionException(address, routingTable) : address) + .thenApply(address -> addAndReturn(seenServers, address)) + .thenCompose(connectionPool::acquire) + .thenApply(connection -> ImpersonationUtil.ensureImpersonationSupport(connection, impersonatedUser)) + .thenCompose(connection -> + provider.getClusterComposition(connection, routingTable.database(), bookmark, impersonatedUser)) + .handle((response, error) -> { + Throwable cause = Futures.completionExceptionCause(error); + if (cause != null) { + return handleRoutingProcedureError(cause, routingTable, routerAddress, baseError); + } else { + return response; + } + }); } - private ClusterComposition handleRoutingProcedureError( Throwable error, RoutingTable routingTable, - BoltServerAddress routerAddress, Throwable baseError ) - { - if ( mustAbortDiscovery( error ) ) - { - throw new CompletionException( error ); + private ClusterComposition handleRoutingProcedureError( + Throwable error, RoutingTable routingTable, BoltServerAddress routerAddress, Throwable baseError) { + if (mustAbortDiscovery(error)) { + throw new CompletionException(error); } // Retriable error happened during discovery. - DiscoveryException discoveryError = new DiscoveryException( format( RECOVERABLE_ROUTING_ERROR, routerAddress ), error ); - Futures.combineErrors( baseError, discoveryError ); // we record each failure here - String warningMessage = format( RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER, routerAddress ); - log.warn( warningMessage ); - log.debug( warningMessage, discoveryError ); - routingTable.forget( routerAddress ); + DiscoveryException discoveryError = + new DiscoveryException(format(RECOVERABLE_ROUTING_ERROR, routerAddress), error); + Futures.combineErrors(baseError, discoveryError); // we record each failure here + String warningMessage = format(RECOVERABLE_DISCOVERY_ERROR_WITH_SERVER, routerAddress); + log.warn(warningMessage); + log.debug(warningMessage, discoveryError); + routingTable.forget(routerAddress); return null; } - private boolean mustAbortDiscovery( Throwable throwable ) - { + private boolean mustAbortDiscovery(Throwable throwable) { boolean abort = false; - if ( !(throwable instanceof AuthorizationExpiredException) && throwable instanceof SecurityException ) - { + if (!(throwable instanceof AuthorizationExpiredException) && throwable instanceof SecurityException) { abort = true; - } - else if ( throwable instanceof FatalDiscoveryException ) - { + } else if (throwable instanceof FatalDiscoveryException) { abort = true; - } - else if ( throwable instanceof IllegalStateException && ConnectionPool.CONNECTION_POOL_CLOSED_ERROR_MESSAGE.equals( throwable.getMessage() ) ) - { + } else if (throwable instanceof IllegalStateException + && ConnectionPool.CONNECTION_POOL_CLOSED_ERROR_MESSAGE.equals(throwable.getMessage())) { abort = true; - } - else if ( throwable instanceof ClientException ) - { + } else if (throwable instanceof ClientException) { String code = ((ClientException) throwable).code(); - abort = INVALID_BOOKMARK_CODE.equals( code ) || INVALID_BOOKMARK_MIXTURE_CODE.equals( code ); + abort = INVALID_BOOKMARK_CODE.equals(code) || INVALID_BOOKMARK_MIXTURE_CODE.equals(code); } return abort; } @Override - public List resolve() throws UnknownHostException - { + public List resolve() throws UnknownHostException { List resolvedAddresses = new LinkedList<>(); UnknownHostException exception = null; - for ( ServerAddress serverAddress : resolver.resolve( initialRouter ) ) - { - try - { - resolveAllByDomainName( serverAddress ).unicastStream().forEach( resolvedAddresses::add ); - } - catch ( UnknownHostException e ) - { - if ( exception == null ) - { + for (ServerAddress serverAddress : resolver.resolve(initialRouter)) { + try { + resolveAllByDomainName(serverAddress).unicastStream().forEach(resolvedAddresses::add); + } catch (UnknownHostException e) { + if (exception == null) { exception = e; - } - else - { - exception.addSuppressed( e ); + } else { + exception.addSuppressed(e); } } } // give up only if there are no addresses to work with at all - if ( resolvedAddresses.isEmpty() && exception != null ) - { + if (resolvedAddresses.isEmpty() && exception != null) { throw exception; } return resolvedAddresses; } - private T addAndReturn( Collection collection, T element ) - { - if ( collection != null ) - { - collection.add( element ); + private T addAndReturn(Collection collection, T element) { + if (collection != null) { + collection.add(element); } return element; } - private BoltServerAddress resolveByDomainNameOrThrowCompletionException( BoltServerAddress address, RoutingTable routingTable ) - { - try - { - ResolvedBoltServerAddress resolvedAddress = resolveAllByDomainName( address ); - routingTable.replaceRouterIfPresent( address, resolvedAddress ); - return resolvedAddress.unicastStream() - .findFirst() - .orElseThrow( - () -> new IllegalStateException( - "Unexpected condition, the ResolvedBoltServerAddress must always have at least one unicast address" ) ); - } - catch ( Throwable e ) - { - throw new CompletionException( e ); + private BoltServerAddress resolveByDomainNameOrThrowCompletionException( + BoltServerAddress address, RoutingTable routingTable) { + try { + ResolvedBoltServerAddress resolvedAddress = resolveAllByDomainName(address); + routingTable.replaceRouterIfPresent(address, resolvedAddress); + return resolvedAddress + .unicastStream() + .findFirst() + .orElseThrow( + () -> new IllegalStateException( + "Unexpected condition, the ResolvedBoltServerAddress must always have at least one unicast address")); + } catch (Throwable e) { + throw new CompletionException(e); } } - private ResolvedBoltServerAddress resolveAllByDomainName( ServerAddress address ) throws UnknownHostException - { - return new ResolvedBoltServerAddress( address.host(), address.port(), domainNameResolver.resolve( address.host() ) ); + private ResolvedBoltServerAddress resolveAllByDomainName(ServerAddress address) throws UnknownHostException { + return new ResolvedBoltServerAddress( + address.host(), address.port(), domainNameResolver.resolve(address.host())); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunner.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunner.java index 095944b069..9b57d1db27 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunner.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunner.java @@ -18,6 +18,8 @@ */ package org.neo4j.driver.internal.cluster; +import static java.util.Collections.singletonList; + import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -25,7 +27,6 @@ import java.util.concurrent.CompletionStage; import java.util.function.Supplier; import java.util.stream.Collectors; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -39,61 +40,57 @@ import org.neo4j.driver.internal.messaging.request.RouteMessage; import org.neo4j.driver.internal.spi.Connection; -import static java.util.Collections.singletonList; - /** * This implementation of the {@link RoutingProcedureRunner} access the routing procedure * through the bolt's ROUTE message. */ -public class RouteMessageRoutingProcedureRunner implements RoutingProcedureRunner -{ - private final Map routingContext; - private final Supplier>> createCompletableFuture; +public class RouteMessageRoutingProcedureRunner implements RoutingProcedureRunner { + private final Map routingContext; + private final Supplier>> createCompletableFuture; - public RouteMessageRoutingProcedureRunner( RoutingContext routingContext ) - { - this( routingContext, CompletableFuture::new ); + public RouteMessageRoutingProcedureRunner(RoutingContext routingContext) { + this(routingContext, CompletableFuture::new); } - protected RouteMessageRoutingProcedureRunner( RoutingContext routingContext, Supplier>> createCompletableFuture ) - { - this.routingContext = routingContext - .toMap() - .entrySet() - .stream() - .collect( Collectors.toMap( Map.Entry::getKey, entry -> Values.value( entry.getValue() ) ) ); + protected RouteMessageRoutingProcedureRunner( + RoutingContext routingContext, Supplier>> createCompletableFuture) { + this.routingContext = routingContext.toMap().entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, entry -> Values.value(entry.getValue()))); this.createCompletableFuture = createCompletableFuture; } @Override - public CompletionStage run( Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser ) - { - CompletableFuture> completableFuture = createCompletableFuture.get(); + public CompletionStage run( + Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser) { + CompletableFuture> completableFuture = createCompletableFuture.get(); - DirectConnection directConnection = toDirectConnection( connection, databaseName, impersonatedUser ); - directConnection.writeAndFlush( new RouteMessage( routingContext, bookmark, databaseName.databaseName().orElse( null ), impersonatedUser ), - new RouteMessageResponseHandler( completableFuture ) ); + DirectConnection directConnection = toDirectConnection(connection, databaseName, impersonatedUser); + directConnection.writeAndFlush( + new RouteMessage( + routingContext, bookmark, databaseName.databaseName().orElse(null), impersonatedUser), + new RouteMessageResponseHandler(completableFuture)); return completableFuture - .thenApply( routingTable -> new RoutingProcedureResponse( getQuery( databaseName ), singletonList( toRecord( routingTable ) ) ) ) - .exceptionally( throwable -> new RoutingProcedureResponse( getQuery( databaseName ), throwable.getCause() ) ) - .thenCompose( routingProcedureResponse -> directConnection.release().thenApply( ignore -> routingProcedureResponse ) ); + .thenApply(routingTable -> + new RoutingProcedureResponse(getQuery(databaseName), singletonList(toRecord(routingTable)))) + .exceptionally(throwable -> new RoutingProcedureResponse(getQuery(databaseName), throwable.getCause())) + .thenCompose(routingProcedureResponse -> + directConnection.release().thenApply(ignore -> routingProcedureResponse)); } - private Record toRecord( Map routingTable ) - { - return new InternalRecord( new ArrayList<>( routingTable.keySet() ), routingTable.values().toArray( new Value[0] ) ); + private Record toRecord(Map routingTable) { + return new InternalRecord( + new ArrayList<>(routingTable.keySet()), routingTable.values().toArray(new Value[0])); } - private DirectConnection toDirectConnection( Connection connection, DatabaseName databaseName, String impersonatedUser ) - { - return new DirectConnection( connection, databaseName, AccessMode.READ, impersonatedUser ); + private DirectConnection toDirectConnection( + Connection connection, DatabaseName databaseName, String impersonatedUser) { + return new DirectConnection(connection, databaseName, AccessMode.READ, impersonatedUser); } - private Query getQuery( DatabaseName databaseName ) - { - Map params = new HashMap<>(); - params.put( "routingContext", routingContext ); - params.put( "databaseName", databaseName.databaseName().orElse( null ) ); - return new Query( "ROUTE $routingContext $databaseName", params ); + private Query getQuery(DatabaseName databaseName) { + Map params = new HashMap<>(); + params.put("routingContext", routingContext); + params.put("databaseName", databaseName.databaseName().orElse(null)); + return new Query("ROUTE $routingContext $databaseName", params); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingContext.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingContext.java index 87aed3897f..cfb295c572 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingContext.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingContext.java @@ -18,118 +18,97 @@ */ package org.neo4j.driver.internal.cluster; +import static java.util.Collections.emptyMap; +import static java.util.Collections.unmodifiableMap; + import java.net.URI; import java.util.HashMap; import java.util.Map; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.Scheme; -import static java.util.Collections.emptyMap; -import static java.util.Collections.unmodifiableMap; - -public class RoutingContext -{ +public class RoutingContext { public static final RoutingContext EMPTY = new RoutingContext(); private static final String ROUTING_ADDRESS_KEY = "address"; - private final Map context; + private final Map context; private final boolean isServerRoutingEnabled; - private RoutingContext() - { + private RoutingContext() { this.isServerRoutingEnabled = true; this.context = emptyMap(); } - public RoutingContext( URI uri ) - { - this.isServerRoutingEnabled = Scheme.isRoutingScheme( uri.getScheme() ); - this.context = unmodifiableMap( parseParameters( uri ) ); + public RoutingContext(URI uri) { + this.isServerRoutingEnabled = Scheme.isRoutingScheme(uri.getScheme()); + this.context = unmodifiableMap(parseParameters(uri)); } - public boolean isDefined() - { + public boolean isDefined() { return context.size() > 1; } - public Map toMap() - { + public Map toMap() { return context; } - public boolean isServerRoutingEnabled() - { + public boolean isServerRoutingEnabled() { return isServerRoutingEnabled; } @Override - public String toString() - { + public String toString() { return "RoutingContext" + context + " isServerRoutingEnabled=" + isServerRoutingEnabled; } - private static Map parseParameters( URI uri ) - { + private static Map parseParameters(URI uri) { String query = uri.getQuery(); String address; - if ( uri.getPort() == -1 ) - { - address = String.format( "%s:%s", uri.getHost(), BoltServerAddress.DEFAULT_PORT ); - } - else - { - address = String.format( "%s:%s", uri.getHost(), uri.getPort() ); + if (uri.getPort() == -1) { + address = String.format("%s:%s", uri.getHost(), BoltServerAddress.DEFAULT_PORT); + } else { + address = String.format("%s:%s", uri.getHost(), uri.getPort()); } - Map parameters = new HashMap<>(); - parameters.put( ROUTING_ADDRESS_KEY, address ); + Map parameters = new HashMap<>(); + parameters.put(ROUTING_ADDRESS_KEY, address); - if ( query == null || query.isEmpty() ) - { + if (query == null || query.isEmpty()) { return parameters; } - String[] pairs = query.split( "&" ); - for ( String pair : pairs ) - { - String[] keyValue = pair.split( "=" ); - if ( keyValue.length != 2 ) - { - throw new IllegalArgumentException( - "Invalid parameters: '" + pair + "' in URI '" + uri + "'" ); + String[] pairs = query.split("&"); + for (String pair : pairs) { + String[] keyValue = pair.split("="); + if (keyValue.length != 2) { + throw new IllegalArgumentException("Invalid parameters: '" + pair + "' in URI '" + uri + "'"); } - String previousValue = parameters.put( trimAndVerifyKey( keyValue[0], "key", uri ), - trimAndVerify( keyValue[1], "value", uri ) ); - if ( previousValue != null ) - { + String previousValue = + parameters.put(trimAndVerifyKey(keyValue[0], "key", uri), trimAndVerify(keyValue[1], "value", uri)); + if (previousValue != null) { throw new IllegalArgumentException( - "Duplicated query parameters with key '" + previousValue + "' in URI '" + uri + "'" ); + "Duplicated query parameters with key '" + previousValue + "' in URI '" + uri + "'"); } } return parameters; } - private static String trimAndVerifyKey( String s, String key, URI uri ) - { - String trimmed = trimAndVerify( s, key, uri ); + private static String trimAndVerifyKey(String s, String key, URI uri) { + String trimmed = trimAndVerify(s, key, uri); - if (trimmed.equals( ROUTING_ADDRESS_KEY )) - { - throw new IllegalArgumentException( "The key 'address' is reserved for routing context."); + if (trimmed.equals(ROUTING_ADDRESS_KEY)) { + throw new IllegalArgumentException("The key 'address' is reserved for routing context."); } return trimmed; } - private static String trimAndVerify( String string, String name, URI uri ) - { + private static String trimAndVerify(String string, String name, URI uri) { String result = string.trim(); - if ( result.isEmpty() ) - { - throw new IllegalArgumentException( "Illegal empty " + name + " in URI query '" + uri + "'" ); + if (result.isEmpty()) { + throw new IllegalArgumentException("Illegal empty " + name + " in URI query '" + uri + "'"); } return result; } 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 84ae9577cb..d5fd12cd3b 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 @@ -18,10 +18,13 @@ */ package org.neo4j.driver.internal.cluster; +import static java.lang.String.format; +import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsMultiDatabase; +import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsRouteMessage; + import java.util.List; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; import org.neo4j.driver.Record; @@ -31,12 +34,7 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.Clock; -import static java.lang.String.format; -import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsMultiDatabase; -import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsRouteMessage; - -public class RoutingProcedureClusterCompositionProvider implements ClusterCompositionProvider -{ +public class RoutingProcedureClusterCompositionProvider implements ClusterCompositionProvider { private static final String PROTOCOL_ERROR_MESSAGE = "Failed to parse '%s' result received from server due to "; private final Clock clock; @@ -44,16 +42,19 @@ public class RoutingProcedureClusterCompositionProvider implements ClusterCompos private final RoutingProcedureRunner multiDatabaseRoutingProcedureRunner; private final RoutingProcedureRunner routeMessageRoutingProcedureRunner; - public RoutingProcedureClusterCompositionProvider( Clock clock, RoutingContext routingContext ) - { - this( clock, new SingleDatabaseRoutingProcedureRunner( routingContext ), new MultiDatabasesRoutingProcedureRunner( routingContext ), - new RouteMessageRoutingProcedureRunner( routingContext ) ); + public RoutingProcedureClusterCompositionProvider(Clock clock, RoutingContext routingContext) { + this( + clock, + new SingleDatabaseRoutingProcedureRunner(routingContext), + new MultiDatabasesRoutingProcedureRunner(routingContext), + new RouteMessageRoutingProcedureRunner(routingContext)); } - RoutingProcedureClusterCompositionProvider( Clock clock, SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner, - MultiDatabasesRoutingProcedureRunner multiDatabaseRoutingProcedureRunner, - RouteMessageRoutingProcedureRunner routeMessageRoutingProcedureRunner ) - { + RoutingProcedureClusterCompositionProvider( + Clock clock, + SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner, + MultiDatabasesRoutingProcedureRunner multiDatabaseRoutingProcedureRunner, + RouteMessageRoutingProcedureRunner routeMessageRoutingProcedureRunner) { this.clock = clock; this.singleDatabaseRoutingProcedureRunner = singleDatabaseRoutingProcedureRunner; this.multiDatabaseRoutingProcedureRunner = multiDatabaseRoutingProcedureRunner; @@ -61,35 +62,28 @@ public RoutingProcedureClusterCompositionProvider( Clock clock, RoutingContext r } @Override - public CompletionStage getClusterComposition( Connection connection, DatabaseName databaseName, Bookmark bookmark, - String impersonatedUser ) - { + public CompletionStage getClusterComposition( + Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser) { RoutingProcedureRunner runner; - if ( supportsRouteMessage( connection ) ) - { + if (supportsRouteMessage(connection)) { runner = routeMessageRoutingProcedureRunner; - } - else if ( supportsMultiDatabase( connection ) ) - { + } else if (supportsMultiDatabase(connection)) { runner = multiDatabaseRoutingProcedureRunner; - } - else - { + } else { runner = singleDatabaseRoutingProcedureRunner; } - return runner.run( connection, databaseName, bookmark, impersonatedUser ) - .thenApply( this::processRoutingResponse ); + return runner.run(connection, databaseName, bookmark, impersonatedUser).thenApply(this::processRoutingResponse); } - private ClusterComposition processRoutingResponse( RoutingProcedureResponse response ) - { - if ( !response.isSuccess() ) - { - throw new CompletionException( format( - "Failed to run '%s' on server. Please make sure that there is a Neo4j server or cluster up running.", - invokedProcedureString( response ) ), response.error() ); + private ClusterComposition processRoutingResponse(RoutingProcedureResponse response) { + if (!response.isSuccess()) { + throw new CompletionException( + format( + "Failed to run '%s' on server. Please make sure that there is a Neo4j server or cluster up running.", + invokedProcedureString(response)), + response.error()); } List records = response.records(); @@ -97,40 +91,35 @@ private ClusterComposition processRoutingResponse( RoutingProcedureResponse resp long now = clock.millis(); // the record size is wrong - if ( records.size() != 1 ) - { - throw new ProtocolException( format( + if (records.size() != 1) { + throw new ProtocolException(format( PROTOCOL_ERROR_MESSAGE + "records received '%s' is too few or too many.", - invokedProcedureString( response ), records.size() ) ); + invokedProcedureString(response), + records.size())); } // failed to parse the record ClusterComposition cluster; - try - { - cluster = ClusterComposition.parse( records.get( 0 ), now ); - } - catch ( ValueException e ) - { - throw new ProtocolException( format( - PROTOCOL_ERROR_MESSAGE + "unparsable record received.", - invokedProcedureString( response ) ), e ); + try { + cluster = ClusterComposition.parse(records.get(0), now); + } catch (ValueException e) { + throw new ProtocolException( + format(PROTOCOL_ERROR_MESSAGE + "unparsable record received.", invokedProcedureString(response)), + e); } // the cluster result is not a legal reply - if ( !cluster.hasRoutersAndReaders() ) - { - throw new ProtocolException( format( + if (!cluster.hasRoutersAndReaders()) { + throw new ProtocolException(format( PROTOCOL_ERROR_MESSAGE + "no router or reader found in response.", - invokedProcedureString( response ) ) ); + invokedProcedureString(response))); } // all good return cluster; } - private static String invokedProcedureString( RoutingProcedureResponse response ) - { + private static String invokedProcedureString(RoutingProcedureResponse response) { Query query = response.procedure(); return query.text() + " " + query.parameters(); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureResponse.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureResponse.java index fd8d17a290..68895eeb00 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureResponse.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureResponse.java @@ -19,57 +19,46 @@ package org.neo4j.driver.internal.cluster; import java.util.List; - import org.neo4j.driver.Query; import org.neo4j.driver.Record; -public class RoutingProcedureResponse -{ +public class RoutingProcedureResponse { private final Query procedure; private final List records; private final Throwable error; - public RoutingProcedureResponse(Query procedure, List records ) - { - this( procedure, records, null ); + public RoutingProcedureResponse(Query procedure, List records) { + this(procedure, records, null); } - public RoutingProcedureResponse(Query procedure, Throwable error ) - { - this( procedure, null, error ); + public RoutingProcedureResponse(Query procedure, Throwable error) { + this(procedure, null, error); } - private RoutingProcedureResponse(Query procedure, List records, Throwable error ) - { + private RoutingProcedureResponse(Query procedure, List records, Throwable error) { this.procedure = procedure; this.records = records; this.error = error; } - public boolean isSuccess() - { + public boolean isSuccess() { return records != null; } - public Query procedure() - { + public Query procedure() { return procedure; } - public List records() - { - if ( !isSuccess() ) - { - throw new IllegalStateException( "Can't access records of a failed result", error ); + public List records() { + if (!isSuccess()) { + throw new IllegalStateException("Can't access records of a failed result", error); } return records; } - public Throwable error() - { - if ( isSuccess() ) - { - throw new IllegalStateException( "Can't access error of a succeeded result " + records ); + public Throwable error() { + if (isSuccess()) { + throw new IllegalStateException("Can't access error of a succeeded result " + records); } return error; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureRunner.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureRunner.java index c91be6fb7a..dee0699b42 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureRunner.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingProcedureRunner.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.cluster; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.internal.DatabaseName; import org.neo4j.driver.internal.spi.Connection; @@ -27,8 +26,7 @@ /** * Interface which defines the standard way to get the routing table */ -public interface RoutingProcedureRunner -{ +public interface RoutingProcedureRunner { /** * Run the calls to the server * @@ -38,5 +36,6 @@ public interface RoutingProcedureRunner * @param impersonatedUser The impersonated user, should be {@code null} for non-impersonated requests * @return The routing table */ - CompletionStage run( Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser ); + CompletionStage run( + Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingSettings.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingSettings.java index 605df0cc2c..31f0d44ded 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingSettings.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingSettings.java @@ -20,51 +20,48 @@ import static java.util.concurrent.TimeUnit.SECONDS; -public class RoutingSettings -{ - public static final long STALE_ROUTING_TABLE_PURGE_DELAY_MS = SECONDS.toMillis( 30 ); - public static final RoutingSettings DEFAULT = new RoutingSettings( 1, SECONDS.toMillis( 5 ), STALE_ROUTING_TABLE_PURGE_DELAY_MS ); +public class RoutingSettings { + public static final long STALE_ROUTING_TABLE_PURGE_DELAY_MS = SECONDS.toMillis(30); + public static final RoutingSettings DEFAULT = + new RoutingSettings(1, SECONDS.toMillis(5), STALE_ROUTING_TABLE_PURGE_DELAY_MS); private final int maxRoutingFailures; private final long retryTimeoutDelay; private final RoutingContext routingContext; private final long routingTablePurgeDelayMs; - public RoutingSettings( int maxRoutingFailures, long retryTimeoutDelay, long routingTablePurgeDelayMs ) - { - this( maxRoutingFailures, retryTimeoutDelay, routingTablePurgeDelayMs, RoutingContext.EMPTY ); + public RoutingSettings(int maxRoutingFailures, long retryTimeoutDelay, long routingTablePurgeDelayMs) { + this(maxRoutingFailures, retryTimeoutDelay, routingTablePurgeDelayMs, RoutingContext.EMPTY); } - public RoutingSettings( int maxRoutingFailures, long retryTimeoutDelay, long routingTablePurgeDelayMs, RoutingContext routingContext ) - { + public RoutingSettings( + int maxRoutingFailures, + long retryTimeoutDelay, + long routingTablePurgeDelayMs, + RoutingContext routingContext) { this.maxRoutingFailures = maxRoutingFailures; this.retryTimeoutDelay = retryTimeoutDelay; this.routingContext = routingContext; this.routingTablePurgeDelayMs = routingTablePurgeDelayMs; } - public RoutingSettings withRoutingContext( RoutingContext newRoutingContext ) - { - return new RoutingSettings( maxRoutingFailures, retryTimeoutDelay, routingTablePurgeDelayMs, newRoutingContext ); + public RoutingSettings withRoutingContext(RoutingContext newRoutingContext) { + return new RoutingSettings(maxRoutingFailures, retryTimeoutDelay, routingTablePurgeDelayMs, newRoutingContext); } - public int maxRoutingFailures() - { + public int maxRoutingFailures() { return maxRoutingFailures; } - public long retryTimeoutDelay() - { + public long retryTimeoutDelay() { return retryTimeoutDelay; } - public RoutingContext routingContext() - { + public RoutingContext routingContext() { return routingContext; } - public long routingTablePurgeDelayMs() - { + public long routingTablePurgeDelayMs() { return routingTablePurgeDelayMs; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTable.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTable.java index a7afbece63..e2107c8334 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTable.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTable.java @@ -20,20 +20,18 @@ import java.util.List; import java.util.Set; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DatabaseName; -public interface RoutingTable -{ - boolean isStaleFor( AccessMode mode ); +public interface RoutingTable { + boolean isStaleFor(AccessMode mode); - boolean hasBeenStaleFor( long staleRoutingTableTimeout ); + boolean hasBeenStaleFor(long staleRoutingTableTimeout); - void update( ClusterComposition cluster ); + void update(ClusterComposition cluster); - void forget( BoltServerAddress address ); + void forget(BoltServerAddress address); /** * Returns an immutable list of reader addresses. @@ -47,7 +45,6 @@ public interface RoutingTable * * @return the immutable list of write addresses. */ - List writers(); /** @@ -55,7 +52,6 @@ public interface RoutingTable * * @return the immutable list of router addresses. */ - List routers(); /** @@ -67,9 +63,9 @@ public interface RoutingTable DatabaseName database(); - void forgetWriter( BoltServerAddress toRemove ); + void forgetWriter(BoltServerAddress toRemove); - void replaceRouterIfPresent( BoltServerAddress oldRouter, BoltServerAddress newRouter ); + void replaceRouterIfPresent(BoltServerAddress oldRouter, BoltServerAddress newRouter); boolean preferInitialRouter(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandler.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandler.java index f9b01206f4..ed64f9d185 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandler.java @@ -20,20 +20,18 @@ import java.util.Set; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.RoutingErrorHandler; import org.neo4j.driver.internal.async.ConnectionContext; -public interface RoutingTableHandler extends RoutingErrorHandler -{ +public interface RoutingTableHandler extends RoutingErrorHandler { Set servers(); boolean isRoutingTableAged(); - CompletionStage ensureRoutingTable( ConnectionContext context ); + CompletionStage ensureRoutingTable(ConnectionContext context); - CompletionStage updateRoutingTable( ClusterCompositionLookupResult compositionLookupResult ); + CompletionStage updateRoutingTable(ClusterCompositionLookupResult compositionLookupResult); RoutingTable routingTable(); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerImpl.java index 99c6dbfdf5..2e1c3ac576 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerImpl.java @@ -18,12 +18,13 @@ */ package org.neo4j.driver.internal.cluster; +import static java.util.concurrent.CompletableFuture.completedFuture; + import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BoltServerAddress; @@ -32,10 +33,7 @@ import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.internal.util.Futures; -import static java.util.concurrent.CompletableFuture.completedFuture; - -public class RoutingTableHandlerImpl implements RoutingTableHandler -{ +public class RoutingTableHandlerImpl implements RoutingTableHandler { private final RoutingTable routingTable; private final DatabaseName databaseName; private final RoutingTableRegistry routingTableRegistry; @@ -46,151 +44,135 @@ public class RoutingTableHandlerImpl implements RoutingTableHandler private final long routingTablePurgeDelayMs; private final Set resolvedInitialRouters = new HashSet<>(); - public RoutingTableHandlerImpl( RoutingTable routingTable, Rediscovery rediscovery, ConnectionPool connectionPool, - RoutingTableRegistry routingTableRegistry, - Logging logging, long routingTablePurgeDelayMs ) - { + public RoutingTableHandlerImpl( + RoutingTable routingTable, + Rediscovery rediscovery, + ConnectionPool connectionPool, + RoutingTableRegistry routingTableRegistry, + Logging logging, + long routingTablePurgeDelayMs) { this.routingTable = routingTable; this.databaseName = routingTable.database(); this.rediscovery = rediscovery; this.connectionPool = connectionPool; this.routingTableRegistry = routingTableRegistry; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); this.routingTablePurgeDelayMs = routingTablePurgeDelayMs; } @Override - public void onConnectionFailure( BoltServerAddress address ) - { + public void onConnectionFailure(BoltServerAddress address) { // remove server from the routing table, to prevent concurrent threads from making connections to this address - routingTable.forget( address ); + routingTable.forget(address); } @Override - public void onWriteFailure( BoltServerAddress address ) - { - routingTable.forgetWriter( address ); + public void onWriteFailure(BoltServerAddress address) { + routingTable.forgetWriter(address); } @Override - public synchronized CompletionStage ensureRoutingTable( ConnectionContext context ) - { - if ( refreshRoutingTableFuture != null ) - { + public synchronized CompletionStage ensureRoutingTable(ConnectionContext context) { + if (refreshRoutingTableFuture != null) { // refresh is already happening concurrently, just use it's result return refreshRoutingTableFuture; - } - else if ( routingTable.isStaleFor( context.mode() ) ) - { + } else if (routingTable.isStaleFor(context.mode())) { // existing routing table is not fresh and should be updated - log.debug( "Routing table for database '%s' is stale. %s", databaseName.description(), routingTable ); + log.debug("Routing table for database '%s' is stale. %s", databaseName.description(), routingTable); CompletableFuture resultFuture = new CompletableFuture<>(); refreshRoutingTableFuture = resultFuture; - rediscovery.lookupClusterComposition( routingTable, connectionPool, context.rediscoveryBookmark(), null ) - .whenComplete( ( composition, completionError ) -> - { - Throwable error = Futures.completionExceptionCause( completionError ); - if ( error != null ) - { - clusterCompositionLookupFailed( error ); - } - else - { - freshClusterCompositionFetched( composition ); - } - } ); + rediscovery + .lookupClusterComposition(routingTable, connectionPool, context.rediscoveryBookmark(), null) + .whenComplete((composition, completionError) -> { + Throwable error = Futures.completionExceptionCause(completionError); + if (error != null) { + clusterCompositionLookupFailed(error); + } else { + freshClusterCompositionFetched(composition); + } + }); return resultFuture; - } - else - { + } else { // existing routing table is fresh, use it - return completedFuture( routingTable ); + return completedFuture(routingTable); } } @Override - public synchronized CompletionStage updateRoutingTable( ClusterCompositionLookupResult compositionLookupResult ) - { - if ( refreshRoutingTableFuture != null ) - { + public synchronized CompletionStage updateRoutingTable( + ClusterCompositionLookupResult compositionLookupResult) { + if (refreshRoutingTableFuture != null) { // refresh is already happening concurrently, just use its result return refreshRoutingTableFuture; - } - else - { - if ( compositionLookupResult.getClusterComposition().expirationTimestamp() < routingTable.expirationTimestamp() ) - { - return completedFuture( routingTable ); + } else { + if (compositionLookupResult.getClusterComposition().expirationTimestamp() + < routingTable.expirationTimestamp()) { + return completedFuture(routingTable); } CompletableFuture resultFuture = new CompletableFuture<>(); refreshRoutingTableFuture = resultFuture; - freshClusterCompositionFetched( compositionLookupResult ); + freshClusterCompositionFetched(compositionLookupResult); return resultFuture; } } - private synchronized void freshClusterCompositionFetched( ClusterCompositionLookupResult compositionLookupResult ) - { - try - { - log.debug( "Fetched cluster composition for database '%s'. %s", databaseName.description(), compositionLookupResult.getClusterComposition() ); - routingTable.update( compositionLookupResult.getClusterComposition() ); + private synchronized void freshClusterCompositionFetched(ClusterCompositionLookupResult compositionLookupResult) { + try { + log.debug( + "Fetched cluster composition for database '%s'. %s", + databaseName.description(), compositionLookupResult.getClusterComposition()); + routingTable.update(compositionLookupResult.getClusterComposition()); routingTableRegistry.removeAged(); Set addressesToRetain = new LinkedHashSet<>(); routingTableRegistry.allServers().stream() - .flatMap( BoltServerAddress::unicastStream ) - .forEach( addressesToRetain::add ); - compositionLookupResult.getResolvedInitialRouters().ifPresent( - addresses -> - { - resolvedInitialRouters.clear(); - resolvedInitialRouters.addAll( addresses ); - } ); - addressesToRetain.addAll( resolvedInitialRouters ); - connectionPool.retainAll( addressesToRetain ); - - log.debug( "Updated routing table for database '%s'. %s", databaseName.description(), routingTable ); + .flatMap(BoltServerAddress::unicastStream) + .forEach(addressesToRetain::add); + compositionLookupResult.getResolvedInitialRouters().ifPresent(addresses -> { + resolvedInitialRouters.clear(); + resolvedInitialRouters.addAll(addresses); + }); + addressesToRetain.addAll(resolvedInitialRouters); + connectionPool.retainAll(addressesToRetain); + + log.debug("Updated routing table for database '%s'. %s", databaseName.description(), routingTable); CompletableFuture routingTableFuture = refreshRoutingTableFuture; refreshRoutingTableFuture = null; - routingTableFuture.complete( routingTable ); - } - catch ( Throwable error ) - { - clusterCompositionLookupFailed( error ); + routingTableFuture.complete(routingTable); + } catch (Throwable error) { + clusterCompositionLookupFailed(error); } } - private synchronized void clusterCompositionLookupFailed( Throwable error ) - { - log.error( String.format( "Failed to update routing table for database '%s'. Current routing table: %s.", databaseName.description(), routingTable ), - error ); - routingTableRegistry.remove( databaseName ); + private synchronized void clusterCompositionLookupFailed(Throwable error) { + log.error( + String.format( + "Failed to update routing table for database '%s'. Current routing table: %s.", + databaseName.description(), routingTable), + error); + routingTableRegistry.remove(databaseName); CompletableFuture routingTableFuture = refreshRoutingTableFuture; refreshRoutingTableFuture = null; - routingTableFuture.completeExceptionally( error ); + routingTableFuture.completeExceptionally(error); } // This method cannot be synchronized as it will be visited by all routing table handler's threads concurrently @Override - public Set servers() - { + public Set servers() { return routingTable.servers(); } // This method cannot be synchronized as it will be visited by all routing table handler's threads concurrently @Override - public boolean isRoutingTableAged() - { - return refreshRoutingTableFuture == null && routingTable.hasBeenStaleFor( routingTablePurgeDelayMs ); + public boolean isRoutingTableAged() { + return refreshRoutingTableFuture == null && routingTable.hasBeenStaleFor(routingTablePurgeDelayMs); } - public RoutingTable routingTable() - { + public RoutingTable routingTable() { return routingTable; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableRegistry.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableRegistry.java index f023f0e1c0..6d11d4218d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableRegistry.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableRegistry.java @@ -21,7 +21,6 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DatabaseName; import org.neo4j.driver.internal.async.ConnectionContext; @@ -30,14 +29,13 @@ * A generic interface to access all routing tables as a whole. * It also provides methods to obtain a routing table or manage a routing table for a specified database. */ -public interface RoutingTableRegistry -{ +public interface RoutingTableRegistry { /** * Ensures the routing table for the database with given access mode. * For server version lower than 4.0, the database name will be ignored while refreshing routing table. * @return The future of a new routing table handler. */ - CompletionStage ensureRoutingTable( ConnectionContext context ); + CompletionStage ensureRoutingTable(ConnectionContext context); /** * @return all servers in the registry @@ -47,7 +45,7 @@ public interface RoutingTableRegistry /** * Removes a routing table of the given database from registry. */ - void remove( DatabaseName databaseName ); + void remove(DatabaseName databaseName); /** * Removes all routing tables that has been not used for a long time. @@ -60,5 +58,5 @@ public interface RoutingTableRegistry * @param databaseName the database name * @return the routing table handler for the requested database name */ - Optional getRoutingTableHandler( DatabaseName databaseName ); + Optional getRoutingTableHandler(DatabaseName databaseName); } 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 06544a0a05..44fb810650 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 @@ -18,6 +18,8 @@ */ package org.neo4j.driver.internal.cluster; +import static org.neo4j.driver.internal.async.ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER; + import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -29,7 +31,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReference; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BoltServerAddress; @@ -40,123 +41,114 @@ import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.Futures; -import static org.neo4j.driver.internal.async.ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER; - -public class RoutingTableRegistryImpl implements RoutingTableRegistry -{ - private final ConcurrentMap routingTableHandlers; - private final Map> principalToDatabaseNameStage; +public class RoutingTableRegistryImpl implements RoutingTableRegistry { + private final ConcurrentMap routingTableHandlers; + private final Map> principalToDatabaseNameStage; private final RoutingTableHandlerFactory factory; private final Logger log; private final Clock clock; private final ConnectionPool connectionPool; private final Rediscovery rediscovery; - public RoutingTableRegistryImpl( ConnectionPool connectionPool, Rediscovery rediscovery, Clock clock, Logging logging, long routingTablePurgeDelayMs ) - { - this( new ConcurrentHashMap<>(), new RoutingTableHandlerFactory( connectionPool, rediscovery, clock, logging, routingTablePurgeDelayMs ), clock, - connectionPool, rediscovery, logging ); + public RoutingTableRegistryImpl( + ConnectionPool connectionPool, + Rediscovery rediscovery, + Clock clock, + Logging logging, + long routingTablePurgeDelayMs) { + this( + new ConcurrentHashMap<>(), + new RoutingTableHandlerFactory(connectionPool, rediscovery, clock, logging, routingTablePurgeDelayMs), + clock, + connectionPool, + rediscovery, + logging); } - RoutingTableRegistryImpl( ConcurrentMap routingTableHandlers, RoutingTableHandlerFactory factory, Clock clock, - ConnectionPool connectionPool, Rediscovery rediscovery, Logging logging ) - { + RoutingTableRegistryImpl( + ConcurrentMap routingTableHandlers, + RoutingTableHandlerFactory factory, + Clock clock, + ConnectionPool connectionPool, + Rediscovery rediscovery, + Logging logging) { this.factory = factory; this.routingTableHandlers = routingTableHandlers; this.principalToDatabaseNameStage = new HashMap<>(); this.clock = clock; this.connectionPool = connectionPool; this.rediscovery = rediscovery; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); } @Override - public CompletionStage ensureRoutingTable( ConnectionContext context ) - { - return ensureDatabaseNameIsCompleted( context ) - .thenCompose( ctxAndHandler -> - { - ConnectionContext completedContext = ctxAndHandler.getContext(); - RoutingTableHandler handler = ctxAndHandler.getHandler() != null - ? ctxAndHandler.getHandler() - : getOrCreate( Futures.joinNowOrElseThrow( completedContext.databaseNameFuture(), - PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER ) ); - return handler.ensureRoutingTable( completedContext ) - .thenApply( ignored -> handler ); - } ); + public CompletionStage ensureRoutingTable(ConnectionContext context) { + return ensureDatabaseNameIsCompleted(context).thenCompose(ctxAndHandler -> { + ConnectionContext completedContext = ctxAndHandler.getContext(); + RoutingTableHandler handler = ctxAndHandler.getHandler() != null + ? ctxAndHandler.getHandler() + : getOrCreate(Futures.joinNowOrElseThrow( + completedContext.databaseNameFuture(), PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER)); + return handler.ensureRoutingTable(completedContext).thenApply(ignored -> handler); + }); } - private CompletionStage ensureDatabaseNameIsCompleted( ConnectionContext context ) - { + private CompletionStage ensureDatabaseNameIsCompleted(ConnectionContext context) { CompletionStage contextAndHandlerStage; CompletableFuture contextDatabaseNameFuture = context.databaseNameFuture(); - if ( contextDatabaseNameFuture.isDone() ) - { - contextAndHandlerStage = CompletableFuture.completedFuture( new ConnectionContextAndHandler( context, null ) ); - } - else - { - synchronized ( this ) - { - if ( contextDatabaseNameFuture.isDone() ) - { - contextAndHandlerStage = CompletableFuture.completedFuture( new ConnectionContextAndHandler( context, null ) ); - } - else - { + if (contextDatabaseNameFuture.isDone()) { + contextAndHandlerStage = CompletableFuture.completedFuture(new ConnectionContextAndHandler(context, null)); + } else { + synchronized (this) { + if (contextDatabaseNameFuture.isDone()) { + contextAndHandlerStage = + CompletableFuture.completedFuture(new ConnectionContextAndHandler(context, null)); + } else { String impersonatedUser = context.impersonatedUser(); - Principal principal = new Principal( impersonatedUser ); - CompletionStage databaseNameStage = principalToDatabaseNameStage.get( principal ); + Principal principal = new Principal(impersonatedUser); + CompletionStage databaseNameStage = principalToDatabaseNameStage.get(principal); AtomicReference handlerRef = new AtomicReference<>(); - if ( databaseNameStage == null ) - { + if (databaseNameStage == null) { CompletableFuture databaseNameFuture = new CompletableFuture<>(); - principalToDatabaseNameStage.put( principal, databaseNameFuture ); + principalToDatabaseNameStage.put(principal, databaseNameFuture); databaseNameStage = databaseNameFuture; - ClusterRoutingTable routingTable = new ClusterRoutingTable( DatabaseNameUtil.defaultDatabase(), clock ); - rediscovery.lookupClusterComposition( routingTable, connectionPool, context.rediscoveryBookmark(), impersonatedUser ) - .thenCompose( - compositionLookupResult -> - { - DatabaseName databaseName = - DatabaseNameUtil.database( compositionLookupResult.getClusterComposition().databaseName() ); - RoutingTableHandler handler = getOrCreate( databaseName ); - handlerRef.set( handler ); - return handler.updateRoutingTable( compositionLookupResult ) - .thenApply( ignored -> databaseName ); - } ) - .whenComplete( ( databaseName, throwable ) -> - { - synchronized ( this ) - { - principalToDatabaseNameStage.remove( principal ); - } - } ) - .whenComplete( ( databaseName, throwable ) -> - { - if ( throwable != null ) - { - databaseNameFuture.completeExceptionally( throwable ); - } - else - { - databaseNameFuture.complete( databaseName ); - } - } ); + ClusterRoutingTable routingTable = + new ClusterRoutingTable(DatabaseNameUtil.defaultDatabase(), clock); + rediscovery + .lookupClusterComposition( + routingTable, connectionPool, context.rediscoveryBookmark(), impersonatedUser) + .thenCompose(compositionLookupResult -> { + DatabaseName databaseName = DatabaseNameUtil.database(compositionLookupResult + .getClusterComposition() + .databaseName()); + RoutingTableHandler handler = getOrCreate(databaseName); + handlerRef.set(handler); + return handler.updateRoutingTable(compositionLookupResult) + .thenApply(ignored -> databaseName); + }) + .whenComplete((databaseName, throwable) -> { + synchronized (this) { + principalToDatabaseNameStage.remove(principal); + } + }) + .whenComplete((databaseName, throwable) -> { + if (throwable != null) { + databaseNameFuture.completeExceptionally(throwable); + } else { + databaseNameFuture.complete(databaseName); + } + }); } - contextAndHandlerStage = databaseNameStage.thenApply( - databaseName -> - { - synchronized ( this ) - { - contextDatabaseNameFuture.complete( databaseName ); - } - return new ConnectionContextAndHandler( context, handlerRef.get() ); - } ); + contextAndHandlerStage = databaseNameStage.thenApply(databaseName -> { + synchronized (this) { + contextDatabaseNameFuture.complete(databaseName); + } + return new ConnectionContextAndHandler(context, handlerRef.get()); + }); } } } @@ -165,74 +157,65 @@ private CompletionStage ensureDatabaseNameIsComplet } @Override - public Set allServers() - { + public Set allServers() { // obviously we just had a snapshot of all servers in all routing tables // after we read it, the set could already be changed. Set servers = new HashSet<>(); - for ( RoutingTableHandler tableHandler : routingTableHandlers.values() ) - { - servers.addAll( tableHandler.servers() ); + for (RoutingTableHandler tableHandler : routingTableHandlers.values()) { + servers.addAll(tableHandler.servers()); } return servers; } @Override - public void remove( DatabaseName databaseName ) - { - routingTableHandlers.remove( databaseName ); - log.debug( "Routing table handler for database '%s' is removed.", databaseName.description() ); + public void remove(DatabaseName databaseName) { + routingTableHandlers.remove(databaseName); + log.debug("Routing table handler for database '%s' is removed.", databaseName.description()); } @Override - public void removeAged() - { - routingTableHandlers.forEach( - ( databaseName, handler ) -> - { - if ( handler.isRoutingTableAged() ) - { - log.info( - "Routing table handler for database '%s' is removed because it has not been used for a long time. Routing table: %s", - databaseName.description(), handler.routingTable() ); - routingTableHandlers.remove( databaseName ); - } - } ); + public void removeAged() { + routingTableHandlers.forEach((databaseName, handler) -> { + if (handler.isRoutingTableAged()) { + log.info( + "Routing table handler for database '%s' is removed because it has not been used for a long time. Routing table: %s", + databaseName.description(), handler.routingTable()); + routingTableHandlers.remove(databaseName); + } + }); } @Override - public Optional getRoutingTableHandler( DatabaseName databaseName ) - { - return Optional.ofNullable( routingTableHandlers.get( databaseName ) ); + public Optional getRoutingTableHandler(DatabaseName databaseName) { + return Optional.ofNullable(routingTableHandlers.get(databaseName)); } // For tests - public boolean contains( DatabaseName databaseName ) - { - return routingTableHandlers.containsKey( databaseName ); + public boolean contains(DatabaseName databaseName) { + return routingTableHandlers.containsKey(databaseName); } - private RoutingTableHandler getOrCreate( DatabaseName databaseName ) - { - return routingTableHandlers.computeIfAbsent( - databaseName, name -> - { - RoutingTableHandler handler = factory.newInstance( name, this ); - log.debug( "Routing table handler for database '%s' is added.", databaseName.description() ); - return handler; - } ); + private RoutingTableHandler getOrCreate(DatabaseName databaseName) { + return routingTableHandlers.computeIfAbsent(databaseName, name -> { + RoutingTableHandler handler = factory.newInstance(name, this); + log.debug("Routing table handler for database '%s' is added.", databaseName.description()); + return handler; + }); } - static class RoutingTableHandlerFactory - { + static class RoutingTableHandlerFactory { private final ConnectionPool connectionPool; private final Rediscovery rediscovery; private final Logging logging; private final Clock clock; private final long routingTablePurgeDelayMs; - RoutingTableHandlerFactory( ConnectionPool connectionPool, Rediscovery rediscovery, Clock clock, Logging logging, long routingTablePurgeDelayMs ) - { + RoutingTableHandlerFactory( + ConnectionPool connectionPool, + Rediscovery rediscovery, + Clock clock, + Logging logging, + long routingTablePurgeDelayMs) { this.connectionPool = connectionPool; this.rediscovery = rediscovery; this.clock = clock; @@ -240,62 +223,52 @@ static class RoutingTableHandlerFactory this.routingTablePurgeDelayMs = routingTablePurgeDelayMs; } - RoutingTableHandler newInstance( DatabaseName databaseName, RoutingTableRegistry allTables ) - { - ClusterRoutingTable routingTable = new ClusterRoutingTable( databaseName, clock ); - return new RoutingTableHandlerImpl( routingTable, rediscovery, connectionPool, allTables, logging, routingTablePurgeDelayMs ); + RoutingTableHandler newInstance(DatabaseName databaseName, RoutingTableRegistry allTables) { + ClusterRoutingTable routingTable = new ClusterRoutingTable(databaseName, clock); + return new RoutingTableHandlerImpl( + routingTable, rediscovery, connectionPool, allTables, logging, routingTablePurgeDelayMs); } } - private static class Principal - { + private static class Principal { private final String id; - private Principal( String id ) - { + private Principal(String id) { this.id = id; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } Principal principal = (Principal) o; - return Objects.equals( id, principal.id ); + return Objects.equals(id, principal.id); } @Override - public int hashCode() - { - return Objects.hash( id ); + public int hashCode() { + return Objects.hash(id); } } - private static class ConnectionContextAndHandler - { + private static class ConnectionContextAndHandler { private final ConnectionContext context; private final RoutingTableHandler handler; - private ConnectionContextAndHandler( ConnectionContext context, RoutingTableHandler handler ) - { + private ConnectionContextAndHandler(ConnectionContext context, RoutingTableHandler handler) { this.context = context; this.handler = handler; } - public ConnectionContext getContext() - { + public ConnectionContext getContext() { return context; } - public RoutingTableHandler getHandler() - { + public RoutingTableHandler getHandler() { return handler; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunner.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunner.java index 3be6f7fc3b..6b0d76586e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunner.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunner.java @@ -18,10 +18,13 @@ */ package org.neo4j.driver.internal.cluster; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; + import java.util.List; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -37,98 +40,82 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.internal.util.ServerVersion; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; - /** * This implementation of the {@link RoutingProcedureRunner} works with single database versions of Neo4j calling * the procedure `dbms.cluster.routing.getRoutingTable` */ -public class SingleDatabaseRoutingProcedureRunner implements RoutingProcedureRunner -{ +public class SingleDatabaseRoutingProcedureRunner implements RoutingProcedureRunner { static final String ROUTING_CONTEXT = "context"; static final String GET_ROUTING_TABLE = "CALL dbms.cluster.routing.getRoutingTable($" + ROUTING_CONTEXT + ")"; final RoutingContext context; - public SingleDatabaseRoutingProcedureRunner( RoutingContext context ) - { + public SingleDatabaseRoutingProcedureRunner(RoutingContext context) { this.context = context; } @Override - public CompletionStage run( Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser ) - { - DirectConnection delegate = connection( connection ); - Query procedure = procedureQuery( connection.serverVersion(), databaseName ); - BookmarkHolder bookmarkHolder = bookmarkHolder( bookmark ); - return runProcedure( delegate, procedure, bookmarkHolder ) - .thenCompose( records -> releaseConnection( delegate, records ) ) - .handle( ( records, error ) -> processProcedureResponse( procedure, records, error ) ); + public CompletionStage run( + Connection connection, DatabaseName databaseName, Bookmark bookmark, String impersonatedUser) { + DirectConnection delegate = connection(connection); + Query procedure = procedureQuery(connection.serverVersion(), databaseName); + BookmarkHolder bookmarkHolder = bookmarkHolder(bookmark); + return runProcedure(delegate, procedure, bookmarkHolder) + .thenCompose(records -> releaseConnection(delegate, records)) + .handle((records, error) -> processProcedureResponse(procedure, records, error)); } - DirectConnection connection( Connection connection ) - { - return new DirectConnection( connection, defaultDatabase(), AccessMode.WRITE, null ); + DirectConnection connection(Connection connection) { + return new DirectConnection(connection, defaultDatabase(), AccessMode.WRITE, null); } - Query procedureQuery(ServerVersion serverVersion, DatabaseName databaseName ) - { - if ( databaseName.databaseName().isPresent() ) - { - throw new FatalDiscoveryException( String.format( - "Refreshing routing table for multi-databases is not supported in server version lower than 4.0. " + - "Current server version: %s. Database name: '%s'", serverVersion, databaseName.description() ) ); + Query procedureQuery(ServerVersion serverVersion, DatabaseName databaseName) { + if (databaseName.databaseName().isPresent()) { + throw new FatalDiscoveryException(String.format( + "Refreshing routing table for multi-databases is not supported in server version lower than 4.0. " + + "Current server version: %s. Database name: '%s'", + serverVersion, databaseName.description())); } - return new Query( GET_ROUTING_TABLE, parameters( ROUTING_CONTEXT, context.toMap() ) ); + return new Query(GET_ROUTING_TABLE, parameters(ROUTING_CONTEXT, context.toMap())); } - BookmarkHolder bookmarkHolder( Bookmark ignored ) - { + BookmarkHolder bookmarkHolder(Bookmark ignored) { return BookmarkHolder.NO_OP; } - CompletionStage> runProcedure(Connection connection, Query procedure, BookmarkHolder bookmarkHolder ) - { - return connection.protocol() - .runInAutoCommitTransaction( connection, procedure, bookmarkHolder, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ) - .asyncResult().thenCompose( ResultCursor::listAsync ); + CompletionStage> runProcedure(Connection connection, Query procedure, BookmarkHolder bookmarkHolder) { + return connection + .protocol() + .runInAutoCommitTransaction( + connection, procedure, bookmarkHolder, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE) + .asyncResult() + .thenCompose(ResultCursor::listAsync); } - private CompletionStage> releaseConnection( Connection connection, List records ) - { + private CompletionStage> releaseConnection(Connection connection, List records) { // It is not strictly required to release connection after routing procedure invocation because it'll // be released by the PULL_ALL response handler after result is fully fetched. Such release will happen // in background. However, releasing it early as part of whole chain makes it easier to reason about // rediscovery in stub server tests. Some of them assume connections to instances not present in new // routing table will be closed immediately. - return connection.release().thenApply( ignore -> records ); + return connection.release().thenApply(ignore -> records); } - private static RoutingProcedureResponse processProcedureResponse(Query procedure, List records, - Throwable error ) - { - Throwable cause = Futures.completionExceptionCause( error ); - if ( cause != null ) - { - return handleError( procedure, cause ); - } - else - { - return new RoutingProcedureResponse( procedure, records ); + private static RoutingProcedureResponse processProcedureResponse( + Query procedure, List records, Throwable error) { + Throwable cause = Futures.completionExceptionCause(error); + if (cause != null) { + return handleError(procedure, cause); + } else { + return new RoutingProcedureResponse(procedure, records); } } - private static RoutingProcedureResponse handleError(Query procedure, Throwable error ) - { - if ( error instanceof ClientException ) - { - return new RoutingProcedureResponse( procedure, error ); - } - else - { - throw new CompletionException( error ); + private static RoutingProcedureResponse handleError(Query procedure, Throwable error) { + if (error instanceof ClientException) { + return new RoutingProcedureResponse(procedure, error); + } else { + throw new CompletionException(error); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LeastConnectedLoadBalancingStrategy.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LeastConnectedLoadBalancingStrategy.java index cdd32bffd2..0ba7974569 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LeastConnectedLoadBalancingStrategy.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LeastConnectedLoadBalancingStrategy.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.cluster.loadbalancing; import java.util.List; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BoltServerAddress; @@ -30,75 +29,64 @@ * start index for iteration in a round-robin fashion. This is done to prevent choosing same first address over and over when all addresses have the same amount * of active connections. */ -public class LeastConnectedLoadBalancingStrategy implements LoadBalancingStrategy -{ +public class LeastConnectedLoadBalancingStrategy implements LoadBalancingStrategy { private final RoundRobinArrayIndex readersIndex = new RoundRobinArrayIndex(); private final RoundRobinArrayIndex writersIndex = new RoundRobinArrayIndex(); private final ConnectionPool connectionPool; private final Logger log; - public LeastConnectedLoadBalancingStrategy( ConnectionPool connectionPool, Logging logging ) - { + public LeastConnectedLoadBalancingStrategy(ConnectionPool connectionPool, Logging logging) { this.connectionPool = connectionPool; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); } @Override - public BoltServerAddress selectReader( List knownReaders ) - { - return select( knownReaders, readersIndex, "reader" ); + public BoltServerAddress selectReader(List knownReaders) { + return select(knownReaders, readersIndex, "reader"); } @Override - public BoltServerAddress selectWriter( List knownWriters ) - { - return select( knownWriters, writersIndex, "writer" ); + public BoltServerAddress selectWriter(List knownWriters) { + return select(knownWriters, writersIndex, "writer"); } - private BoltServerAddress select( List addresses, RoundRobinArrayIndex addressesIndex, - String addressType ) - { + private BoltServerAddress select( + List addresses, RoundRobinArrayIndex addressesIndex, String addressType) { int size = addresses.size(); - if ( size == 0 ) - { - log.trace( "Unable to select %s, no known addresses given", addressType ); + if (size == 0) { + log.trace("Unable to select %s, no known addresses given", addressType); return null; } // choose start index for iteration in round-robin fashion - int startIndex = addressesIndex.next( size ); + int startIndex = addressesIndex.next(size); int index = startIndex; BoltServerAddress leastConnectedAddress = null; int leastActiveConnections = Integer.MAX_VALUE; // iterate over the array to find the least connected address - do - { - BoltServerAddress address = addresses.get( index ); - int activeConnections = connectionPool.inUseConnections( address ); + do { + BoltServerAddress address = addresses.get(index); + int activeConnections = connectionPool.inUseConnections(address); - if ( activeConnections < leastActiveConnections ) - { + if (activeConnections < leastActiveConnections) { leastConnectedAddress = address; leastActiveConnections = activeConnections; } // loop over to the start of the array when end is reached - if ( index == size - 1 ) - { + if (index == size - 1) { index = 0; - } - else - { + } else { index++; } - } - while ( index != startIndex ); + } while (index != startIndex); - log.trace( "Selected %s with address: '%s' and active connections: %s", - addressType, leastConnectedAddress, leastActiveConnections ); + log.trace( + "Selected %s with address: '%s' and active connections: %s", + addressType, leastConnectedAddress, leastActiveConnections); return leastConnectedAddress; } 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 10d5dc71b6..2993af41b1 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 @@ -18,13 +18,21 @@ */ package org.neo4j.driver.internal.cluster.loadbalancing; -import io.netty.util.concurrent.EventExecutorGroup; +import static java.lang.String.format; +import static java.util.Objects.requireNonNull; +import static org.neo4j.driver.internal.async.ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER; +import static org.neo4j.driver.internal.async.ImmutableConnectionContext.simple; +import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsMultiDatabase; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.completionExceptionCause; +import static org.neo4j.driver.internal.util.Futures.failedFuture; +import static org.neo4j.driver.internal.util.Futures.onErrorContinue; +import io.netty.util.concurrent.EventExecutorGroup; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; @@ -50,19 +58,9 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.net.ServerAddressResolver; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static org.neo4j.driver.internal.async.ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER; -import static org.neo4j.driver.internal.async.ImmutableConnectionContext.simple; -import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.supportsMultiDatabase; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.completionExceptionCause; -import static org.neo4j.driver.internal.util.Futures.failedFuture; -import static org.neo4j.driver.internal.util.Futures.onErrorContinue; - -public class LoadBalancer implements ConnectionProvider -{ - private static final String CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE = "Connection acquisition failed for all available addresses."; +public class LoadBalancer implements ConnectionProvider { + private static final String CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE = + "Connection acquisition failed for all available addresses."; private static final String CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE = "Failed to obtain connection towards %s server. Known routing table is: %s"; private static final String CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE = @@ -75,212 +73,242 @@ public class LoadBalancer implements ConnectionProvider private final Logger log; private final Rediscovery rediscovery; - public LoadBalancer( BoltServerAddress initialRouter, RoutingSettings settings, ConnectionPool connectionPool, - EventExecutorGroup eventExecutorGroup, Clock clock, Logging logging, - LoadBalancingStrategy loadBalancingStrategy, ServerAddressResolver resolver, DomainNameResolver domainNameResolver ) - { - this( connectionPool, createRediscovery( eventExecutorGroup, initialRouter, resolver, settings, clock, logging, requireNonNull( domainNameResolver ) ), - settings, loadBalancingStrategy, eventExecutorGroup, clock, logging ); + public LoadBalancer( + BoltServerAddress initialRouter, + RoutingSettings settings, + ConnectionPool connectionPool, + EventExecutorGroup eventExecutorGroup, + Clock clock, + Logging logging, + LoadBalancingStrategy loadBalancingStrategy, + ServerAddressResolver resolver, + DomainNameResolver domainNameResolver) { + this( + connectionPool, + createRediscovery( + eventExecutorGroup, + initialRouter, + resolver, + settings, + clock, + logging, + requireNonNull(domainNameResolver)), + settings, + loadBalancingStrategy, + eventExecutorGroup, + clock, + logging); } - private LoadBalancer( ConnectionPool connectionPool, Rediscovery rediscovery, RoutingSettings settings, LoadBalancingStrategy loadBalancingStrategy, - EventExecutorGroup eventExecutorGroup, Clock clock, Logging logging ) - { - this( connectionPool, createRoutingTables( connectionPool, rediscovery, settings, clock, logging ), rediscovery, loadBalancingStrategy, - eventExecutorGroup, logging ); + private LoadBalancer( + ConnectionPool connectionPool, + Rediscovery rediscovery, + RoutingSettings settings, + LoadBalancingStrategy loadBalancingStrategy, + EventExecutorGroup eventExecutorGroup, + Clock clock, + Logging logging) { + this( + connectionPool, + createRoutingTables(connectionPool, rediscovery, settings, clock, logging), + rediscovery, + loadBalancingStrategy, + eventExecutorGroup, + logging); } - LoadBalancer( ConnectionPool connectionPool, RoutingTableRegistry routingTables, Rediscovery rediscovery, LoadBalancingStrategy loadBalancingStrategy, - EventExecutorGroup eventExecutorGroup, Logging logging ) - { + LoadBalancer( + ConnectionPool connectionPool, + RoutingTableRegistry routingTables, + Rediscovery rediscovery, + LoadBalancingStrategy loadBalancingStrategy, + EventExecutorGroup eventExecutorGroup, + Logging logging) { this.connectionPool = connectionPool; this.routingTables = routingTables; this.rediscovery = rediscovery; this.loadBalancingStrategy = loadBalancingStrategy; this.eventExecutorGroup = eventExecutorGroup; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); } @Override - public CompletionStage acquireConnection( ConnectionContext context ) - { - return routingTables.ensureRoutingTable( context ) - .thenCompose( handler -> acquire( context.mode(), handler.routingTable() ) - .thenApply( connection -> new RoutingConnection( connection, - Futures.joinNowOrElseThrow( context.databaseNameFuture(), - PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER ), - context.mode(), context.impersonatedUser(), handler ) ) ); + public CompletionStage acquireConnection(ConnectionContext context) { + return routingTables.ensureRoutingTable(context).thenCompose(handler -> acquire( + context.mode(), handler.routingTable()) + .thenApply(connection -> new RoutingConnection( + connection, + Futures.joinNowOrElseThrow( + context.databaseNameFuture(), PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER), + context.mode(), + context.impersonatedUser(), + handler))); } @Override - public CompletionStage verifyConnectivity() - { - return this.supportsMultiDb().thenCompose( supports -> routingTables.ensureRoutingTable( simple( supports ) ) ).handle( ( ignored, error ) -> { - if ( error != null ) - { - Throwable cause = completionExceptionCause( error ); - if ( cause instanceof ServiceUnavailableException ) - { - throw Futures.asCompletionException( new ServiceUnavailableException( - "Unable to connect to database management service, ensure the database is running and that there is a working network connection to it.", - cause ) ); - } - throw Futures.asCompletionException( cause ); - } - return null; - } ); + public CompletionStage verifyConnectivity() { + return this.supportsMultiDb() + .thenCompose(supports -> routingTables.ensureRoutingTable(simple(supports))) + .handle((ignored, error) -> { + if (error != null) { + Throwable cause = completionExceptionCause(error); + if (cause instanceof ServiceUnavailableException) { + throw Futures.asCompletionException(new ServiceUnavailableException( + "Unable to connect to database management service, ensure the database is running and that there is a working network connection to it.", + cause)); + } + throw Futures.asCompletionException(cause); + } + return null; + }); } @Override - public CompletionStage close() - { + public CompletionStage close() { return connectionPool.close(); } @Override - public CompletionStage supportsMultiDb() - { + public CompletionStage supportsMultiDb() { List addresses; - try - { + try { addresses = rediscovery.resolve(); - } - catch ( Throwable error ) - { - return failedFuture( error ); + } catch (Throwable error) { + return failedFuture(error); } CompletableFuture result = completedWithNull(); - Throwable baseError = new ServiceUnavailableException( "Failed to perform multi-databases feature detection with the following servers: " + addresses ); + Throwable baseError = new ServiceUnavailableException( + "Failed to perform multi-databases feature detection with the following servers: " + addresses); - for ( BoltServerAddress address : addresses ) - { - result = onErrorContinue( result, baseError, completionError -> { + for (BoltServerAddress address : addresses) { + result = onErrorContinue(result, baseError, completionError -> { // We fail fast on security errors - Throwable error = completionExceptionCause( completionError ); - if ( error instanceof SecurityException ) - { - return failedFuture( error ); + Throwable error = completionExceptionCause(completionError); + if (error instanceof SecurityException) { + return failedFuture(error); } - return supportsMultiDb( address ); - } ); + return supportsMultiDb(address); + }); } - return onErrorContinue( result, baseError, completionError -> { - // If we failed with security errors, then we rethrow the security error out, otherwise we throw the chained errors. - Throwable error = completionExceptionCause( completionError ); - if ( error instanceof SecurityException ) - { - return failedFuture( error ); + return onErrorContinue(result, baseError, completionError -> { + // If we failed with security errors, then we rethrow the security error out, otherwise we throw the chained + // errors. + Throwable error = completionExceptionCause(completionError); + if (error instanceof SecurityException) { + return failedFuture(error); } - return failedFuture( baseError ); - } ); + return failedFuture(baseError); + }); } - public RoutingTableRegistry getRoutingTableRegistry() - { + public RoutingTableRegistry getRoutingTableRegistry() { return routingTables; } - private CompletionStage supportsMultiDb( BoltServerAddress address ) - { - return connectionPool.acquire( address ).thenCompose( - conn -> - { - boolean supportsMultiDatabase = supportsMultiDatabase( conn ); - return conn.release().thenApply( ignored -> supportsMultiDatabase ); - } ); + private CompletionStage supportsMultiDb(BoltServerAddress address) { + return connectionPool.acquire(address).thenCompose(conn -> { + boolean supportsMultiDatabase = supportsMultiDatabase(conn); + return conn.release().thenApply(ignored -> supportsMultiDatabase); + }); } - private CompletionStage acquire( AccessMode mode, RoutingTable routingTable ) - { + private CompletionStage acquire(AccessMode mode, RoutingTable routingTable) { CompletableFuture result = new CompletableFuture<>(); List attemptExceptions = new ArrayList<>(); - acquire( mode, routingTable, result, attemptExceptions ); + acquire(mode, routingTable, result, attemptExceptions); return result; } - private void acquire( AccessMode mode, RoutingTable routingTable, CompletableFuture result, List attemptErrors ) - { - List addresses = getAddressesByMode( mode, routingTable ); - BoltServerAddress address = selectAddress( mode, addresses ); + private void acquire( + AccessMode mode, + RoutingTable routingTable, + CompletableFuture result, + List attemptErrors) { + List addresses = getAddressesByMode(mode, routingTable); + BoltServerAddress address = selectAddress(mode, addresses); - if ( address == null ) - { - SessionExpiredException completionError = - new SessionExpiredException( format( CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE, mode, routingTable ) ); - attemptErrors.forEach( completionError::addSuppressed ); - log.error( CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE, completionError ); - result.completeExceptionally( completionError ); + if (address == null) { + SessionExpiredException completionError = new SessionExpiredException( + format(CONNECTION_ACQUISITION_COMPLETION_EXCEPTION_MESSAGE, mode, routingTable)); + attemptErrors.forEach(completionError::addSuppressed); + log.error(CONNECTION_ACQUISITION_COMPLETION_FAILURE_MESSAGE, completionError); + result.completeExceptionally(completionError); return; } - connectionPool.acquire( address ).whenComplete( ( connection, completionError ) -> - { - Throwable error = completionExceptionCause( completionError ); - if ( error != null ) - { - if ( error instanceof ServiceUnavailableException ) - { - String attemptMessage = format( CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE, address ); - log.warn( attemptMessage ); - log.debug( attemptMessage, error ); - attemptErrors.add( error ); - routingTable.forget( address ); - eventExecutorGroup.next().execute( () -> acquire( mode, routingTable, result, attemptErrors ) ); - } - else - { - result.completeExceptionally( error ); + connectionPool.acquire(address).whenComplete((connection, completionError) -> { + Throwable error = completionExceptionCause(completionError); + if (error != null) { + if (error instanceof ServiceUnavailableException) { + String attemptMessage = format(CONNECTION_ACQUISITION_ATTEMPT_FAILURE_MESSAGE, address); + log.warn(attemptMessage); + log.debug(attemptMessage, error); + attemptErrors.add(error); + routingTable.forget(address); + eventExecutorGroup.next().execute(() -> acquire(mode, routingTable, result, attemptErrors)); + } else { + result.completeExceptionally(error); } + } else { + result.complete(connection); } - else - { - result.complete( connection ); - } - } ); + }); } - private static List getAddressesByMode( AccessMode mode, RoutingTable routingTable ) - { - switch ( mode ) - { - case READ: - return routingTable.readers(); - case WRITE: - return routingTable.writers(); - default: - throw unknownMode( mode ); + private static List getAddressesByMode(AccessMode mode, RoutingTable routingTable) { + switch (mode) { + case READ: + return routingTable.readers(); + case WRITE: + return routingTable.writers(); + default: + throw unknownMode(mode); } } - private BoltServerAddress selectAddress( AccessMode mode, List addresses ) - { - switch ( mode ) - { - case READ: - return loadBalancingStrategy.selectReader( addresses ); - case WRITE: - return loadBalancingStrategy.selectWriter( addresses ); - default: - throw unknownMode( mode ); + private BoltServerAddress selectAddress(AccessMode mode, List addresses) { + switch (mode) { + case READ: + return loadBalancingStrategy.selectReader(addresses); + case WRITE: + return loadBalancingStrategy.selectWriter(addresses); + default: + throw unknownMode(mode); } } - private static RoutingTableRegistry createRoutingTables( ConnectionPool connectionPool, Rediscovery rediscovery, RoutingSettings settings, Clock clock, - Logging logging ) - { - return new RoutingTableRegistryImpl( connectionPool, rediscovery, clock, logging, settings.routingTablePurgeDelayMs() ); + private static RoutingTableRegistry createRoutingTables( + ConnectionPool connectionPool, + Rediscovery rediscovery, + RoutingSettings settings, + Clock clock, + Logging logging) { + return new RoutingTableRegistryImpl( + connectionPool, rediscovery, clock, logging, settings.routingTablePurgeDelayMs()); } - private static Rediscovery createRediscovery( EventExecutorGroup eventExecutorGroup, BoltServerAddress initialRouter, ServerAddressResolver resolver, - RoutingSettings settings, Clock clock, Logging logging, DomainNameResolver domainNameResolver ) - { - ClusterCompositionProvider clusterCompositionProvider = new RoutingProcedureClusterCompositionProvider( clock, settings.routingContext() ); - return new RediscoveryImpl( initialRouter, settings, clusterCompositionProvider, eventExecutorGroup, resolver, logging, domainNameResolver ); + private static Rediscovery createRediscovery( + EventExecutorGroup eventExecutorGroup, + BoltServerAddress initialRouter, + ServerAddressResolver resolver, + RoutingSettings settings, + Clock clock, + Logging logging, + DomainNameResolver domainNameResolver) { + ClusterCompositionProvider clusterCompositionProvider = + new RoutingProcedureClusterCompositionProvider(clock, settings.routingContext()); + return new RediscoveryImpl( + initialRouter, + settings, + clusterCompositionProvider, + eventExecutorGroup, + resolver, + logging, + domainNameResolver); } - private static RuntimeException unknownMode( AccessMode mode ) - { - return new IllegalArgumentException( "Mode '" + mode + "' is not supported" ); + private static RuntimeException unknownMode(AccessMode mode) { + return new IllegalArgumentException("Mode '" + mode + "' is not supported"); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancingStrategy.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancingStrategy.java index d05189e79c..c91d15addd 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancingStrategy.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancingStrategy.java @@ -19,21 +19,19 @@ package org.neo4j.driver.internal.cluster.loadbalancing; import java.util.List; - import org.neo4j.driver.internal.BoltServerAddress; /** * A facility to select most appropriate reader or writer among the given addresses for request processing. */ -public interface LoadBalancingStrategy -{ +public interface LoadBalancingStrategy { /** * Select most appropriate read address from the given array of addresses. * * @param knownReaders array of all known readers. * @return most appropriate reader or {@code null} if it can't be selected. */ - BoltServerAddress selectReader( List knownReaders ); + BoltServerAddress selectReader(List knownReaders); /** * Select most appropriate write address from the given array of addresses. @@ -41,5 +39,5 @@ public interface LoadBalancingStrategy * @param knownWriters array of all known writers. * @return most appropriate writer or {@code null} if it can't be selected. */ - BoltServerAddress selectWriter( List knownWriters ); + BoltServerAddress selectWriter(List knownWriters); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinArrayIndex.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinArrayIndex.java index e555aab58d..6e9892b07b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinArrayIndex.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinArrayIndex.java @@ -20,33 +20,27 @@ import java.util.concurrent.atomic.AtomicInteger; -public class RoundRobinArrayIndex -{ +public class RoundRobinArrayIndex { private final AtomicInteger offset; - RoundRobinArrayIndex() - { - this( 0 ); + RoundRobinArrayIndex() { + this(0); } // only for testing - RoundRobinArrayIndex( int initialOffset ) - { - this.offset = new AtomicInteger( initialOffset ); + RoundRobinArrayIndex(int initialOffset) { + this.offset = new AtomicInteger(initialOffset); } - public int next( int arrayLength ) - { - if ( arrayLength == 0 ) - { + public int next(int arrayLength) { + if (arrayLength == 0) { return -1; } int nextOffset; - while ( (nextOffset = offset.getAndIncrement()) < 0 ) - { + while ((nextOffset = offset.getAndIncrement()) < 0) { // overflow, try resetting back to zero - offset.compareAndSet( nextOffset + 1, 0 ); + offset.compareAndSet(nextOffset + 1, 0); } return nextOffset % arrayLength; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursor.java b/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursor.java index 20e39c34cc..f1c4cc5741 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursor.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursor.java @@ -19,11 +19,9 @@ package org.neo4j.driver.internal.cursor; import java.util.concurrent.CompletableFuture; - import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.internal.FailableCursor; -public interface AsyncResultCursor extends ResultCursor, FailableCursor -{ +public interface AsyncResultCursor extends ResultCursor, FailableCursor { CompletableFuture mapSuccessfulRunCompletionAsync(); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursorImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursorImpl.java index ac98460198..98fdf0b4b8 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursorImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursorImpl.java @@ -23,7 +23,6 @@ import java.util.concurrent.CompletionStage; import java.util.function.Consumer; import java.util.function.Function; - import org.neo4j.driver.Record; import org.neo4j.driver.exceptions.NoSuchRecordException; import org.neo4j.driver.internal.handlers.PullAllResponseHandler; @@ -31,137 +30,109 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.summary.ResultSummary; -public class AsyncResultCursorImpl implements AsyncResultCursor -{ +public class AsyncResultCursorImpl implements AsyncResultCursor { private final Throwable runError; private final RunResponseHandler runHandler; private final PullAllResponseHandler pullAllHandler; - public AsyncResultCursorImpl( Throwable runError, RunResponseHandler runHandler, PullAllResponseHandler pullAllHandler ) - { + public AsyncResultCursorImpl( + Throwable runError, RunResponseHandler runHandler, PullAllResponseHandler pullAllHandler) { this.runError = runError; this.runHandler = runHandler; this.pullAllHandler = pullAllHandler; } @Override - public List keys() - { + public List keys() { return runHandler.queryKeys().keys(); } @Override - public CompletionStage consumeAsync() - { + public CompletionStage consumeAsync() { return pullAllHandler.consumeAsync(); } @Override - public CompletionStage nextAsync() - { + public CompletionStage nextAsync() { return pullAllHandler.nextAsync(); } @Override - public CompletionStage peekAsync() - { + public CompletionStage peekAsync() { return pullAllHandler.peekAsync(); } @Override - public CompletionStage singleAsync() - { - return nextAsync().thenCompose( firstRecord -> - { - if ( firstRecord == null ) - { - throw new NoSuchRecordException( - "Cannot retrieve a single record, because this result is empty." ); + public CompletionStage singleAsync() { + return nextAsync().thenCompose(firstRecord -> { + if (firstRecord == null) { + throw new NoSuchRecordException("Cannot retrieve a single record, because this result is empty."); } - return nextAsync().thenApply( secondRecord -> - { - if ( secondRecord != null ) - { - throw new NoSuchRecordException( - "Expected a result with a single record, but this result " + - "contains at least one more. Ensure your query returns only " + - "one record." ); + return nextAsync().thenApply(secondRecord -> { + if (secondRecord != null) { + throw new NoSuchRecordException("Expected a result with a single record, but this result " + + "contains at least one more. Ensure your query returns only " + + "one record."); } return firstRecord; - } ); - } ); + }); + }); } @Override - public CompletionStage forEachAsync( Consumer action ) - { + public CompletionStage forEachAsync(Consumer action) { CompletableFuture resultFuture = new CompletableFuture<>(); - internalForEachAsync( action, resultFuture ); - return resultFuture.thenCompose( ignore -> consumeAsync() ); + internalForEachAsync(action, resultFuture); + return resultFuture.thenCompose(ignore -> consumeAsync()); } @Override - public CompletionStage> listAsync() - { - return listAsync( Function.identity() ); + public CompletionStage> listAsync() { + return listAsync(Function.identity()); } @Override - public CompletionStage> listAsync( Function mapFunction ) - { - return pullAllHandler.listAsync( mapFunction ); + public CompletionStage> listAsync(Function mapFunction) { + return pullAllHandler.listAsync(mapFunction); } @Override - public CompletionStage discardAllFailureAsync() - { + public CompletionStage discardAllFailureAsync() { // runError has priority over other errors and is expected to have been reported to user by now - return consumeAsync().handle( ( summary, error ) -> runError != null ? null : error ); + return consumeAsync().handle((summary, error) -> runError != null ? null : error); } @Override - public CompletionStage pullAllFailureAsync() - { + public CompletionStage pullAllFailureAsync() { // runError has priority over other errors and is expected to have been reported to user by now - return pullAllHandler.pullAllFailureAsync().thenApply( error -> runError != null ? null : error ); + return pullAllHandler.pullAllFailureAsync().thenApply(error -> runError != null ? null : error); } - private void internalForEachAsync( Consumer action, CompletableFuture resultFuture ) - { + private void internalForEachAsync(Consumer action, CompletableFuture resultFuture) { CompletionStage recordFuture = nextAsync(); // use async completion listener because of recursion, otherwise it is possible for // the caller thread to get StackOverflowError when result is large and buffered - recordFuture.whenCompleteAsync( ( record, completionError ) -> - { - Throwable error = Futures.completionExceptionCause( completionError ); - if ( error != null ) - { - resultFuture.completeExceptionally( error ); - } - else if ( record != null ) - { - try - { - action.accept( record ); - } - catch ( Throwable actionError ) - { - resultFuture.completeExceptionally( actionError ); + recordFuture.whenCompleteAsync((record, completionError) -> { + Throwable error = Futures.completionExceptionCause(completionError); + if (error != null) { + resultFuture.completeExceptionally(error); + } else if (record != null) { + try { + action.accept(record); + } catch (Throwable actionError) { + resultFuture.completeExceptionally(actionError); return; } - internalForEachAsync( action, resultFuture ); - } - else - { - resultFuture.complete( null ); + internalForEachAsync(action, resultFuture); + } else { + resultFuture.complete(null); } - } ); + }); } @Override - public CompletableFuture mapSuccessfulRunCompletionAsync() - { - return runError != null ? Futures.failedFuture( runError ) : CompletableFuture.completedFuture( this ); + public CompletableFuture mapSuccessfulRunCompletionAsync() { + return runError != null ? Futures.failedFuture(runError) : CompletableFuture.completedFuture(this); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursorOnlyFactory.java b/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursorOnlyFactory.java index 9709c1ef6c..596ff44b52 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursorOnlyFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cursor/AsyncResultCursorOnlyFactory.java @@ -18,9 +18,10 @@ */ package org.neo4j.driver.internal.cursor; +import static java.util.Objects.requireNonNull; + import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.handlers.PullAllResponseHandler; import org.neo4j.driver.internal.handlers.RunResponseHandler; @@ -28,27 +29,27 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.Futures; -import static java.util.Objects.requireNonNull; - /** * Used by Bolt V1, V2, V3 */ -public class AsyncResultCursorOnlyFactory implements ResultCursorFactory -{ +public class AsyncResultCursorOnlyFactory implements ResultCursorFactory { protected final Connection connection; protected final Message runMessage; protected final RunResponseHandler runHandler; private final CompletableFuture runFuture; protected final PullAllResponseHandler pullAllHandler; - public AsyncResultCursorOnlyFactory( Connection connection, Message runMessage, RunResponseHandler runHandler, CompletableFuture runFuture, - PullAllResponseHandler pullHandler ) - { - requireNonNull( connection ); - requireNonNull( runMessage ); - requireNonNull( runHandler ); - requireNonNull( runFuture ); - requireNonNull( pullHandler ); + public AsyncResultCursorOnlyFactory( + Connection connection, + Message runMessage, + RunResponseHandler runHandler, + CompletableFuture runFuture, + PullAllResponseHandler pullHandler) { + requireNonNull(connection); + requireNonNull(runMessage); + requireNonNull(runHandler); + requireNonNull(runFuture); + requireNonNull(pullHandler); this.connection = connection; this.runMessage = runMessage; @@ -58,18 +59,18 @@ public AsyncResultCursorOnlyFactory( Connection connection, Message runMessage, this.pullAllHandler = pullHandler; } - public CompletionStage asyncResult() - { + public CompletionStage asyncResult() { // only write and flush messages when async result is wanted. - connection.write( runMessage, runHandler ); // queues the run message, will be flushed with pull message together + connection.write(runMessage, runHandler); // queues the run message, will be flushed with pull message together pullAllHandler.prePopulateRecords(); - return runFuture.handle( ( ignored, error ) -> new DisposableAsyncResultCursor( new AsyncResultCursorImpl( error, runHandler, pullAllHandler ) ) ); + return runFuture.handle((ignored, error) -> + new DisposableAsyncResultCursor(new AsyncResultCursorImpl(error, runHandler, pullAllHandler))); } - public CompletionStage rxResult() - { - return Futures.failedFuture( new ClientException( "Driver is connected to the database that does not support driver reactive API. " + - "In order to use the driver reactive API, please upgrade to neo4j 4.0.0 or later." ) ); + public CompletionStage rxResult() { + return Futures.failedFuture( + new ClientException("Driver is connected to the database that does not support driver reactive API. " + + "In order to use the driver reactive API, please upgrade to neo4j 4.0.0 or later.")); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cursor/DisposableAsyncResultCursor.java b/driver/src/main/java/org/neo4j/driver/internal/cursor/DisposableAsyncResultCursor.java index a013e5612a..cff4993be1 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cursor/DisposableAsyncResultCursor.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cursor/DisposableAsyncResultCursor.java @@ -18,110 +18,94 @@ */ package org.neo4j.driver.internal.cursor; +import static org.neo4j.driver.internal.util.ErrorUtil.newResultConsumedError; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; + import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.Consumer; import java.util.function.Function; - import org.neo4j.driver.Record; import org.neo4j.driver.summary.ResultSummary; -import static org.neo4j.driver.internal.util.ErrorUtil.newResultConsumedError; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; - -public class DisposableAsyncResultCursor implements AsyncResultCursor -{ +public class DisposableAsyncResultCursor implements AsyncResultCursor { private final AsyncResultCursor delegate; private boolean isDisposed; - public DisposableAsyncResultCursor( AsyncResultCursor delegate ) - { + public DisposableAsyncResultCursor(AsyncResultCursor delegate) { this.delegate = delegate; } @Override - public List keys() - { + public List keys() { return delegate.keys(); } @Override - public CompletionStage consumeAsync() - { + public CompletionStage consumeAsync() { isDisposed = true; return delegate.consumeAsync(); } @Override - public CompletionStage nextAsync() - { - return assertNotDisposed().thenCompose( ignored -> delegate.nextAsync() ); + public CompletionStage nextAsync() { + return assertNotDisposed().thenCompose(ignored -> delegate.nextAsync()); } @Override - public CompletionStage peekAsync() - { - return assertNotDisposed().thenCompose( ignored -> delegate.peekAsync() ); + public CompletionStage peekAsync() { + return assertNotDisposed().thenCompose(ignored -> delegate.peekAsync()); } @Override - public CompletionStage singleAsync() - { - return assertNotDisposed().thenCompose( ignored -> delegate.singleAsync() ); + public CompletionStage singleAsync() { + return assertNotDisposed().thenCompose(ignored -> delegate.singleAsync()); } @Override - public CompletionStage forEachAsync( Consumer action ) - { - return assertNotDisposed().thenCompose( ignored -> delegate.forEachAsync( action ) ); + public CompletionStage forEachAsync(Consumer action) { + return assertNotDisposed().thenCompose(ignored -> delegate.forEachAsync(action)); } @Override - public CompletionStage> listAsync() - { - return assertNotDisposed().thenCompose( ignored -> delegate.listAsync() ); + public CompletionStage> listAsync() { + return assertNotDisposed().thenCompose(ignored -> delegate.listAsync()); } @Override - public CompletionStage> listAsync( Function mapFunction ) - { - return assertNotDisposed().thenCompose( ignored -> delegate.listAsync( mapFunction ) ); + public CompletionStage> listAsync(Function mapFunction) { + return assertNotDisposed().thenCompose(ignored -> delegate.listAsync(mapFunction)); } @Override - public CompletionStage discardAllFailureAsync() - { + public CompletionStage discardAllFailureAsync() { isDisposed = true; return delegate.discardAllFailureAsync(); } @Override - public CompletionStage pullAllFailureAsync() - { - // This one does not dispose the result so that a user could still visit the buffered result after this method call. + public CompletionStage pullAllFailureAsync() { + // This one does not dispose the result so that a user could still visit the buffered result after this method + // call. // This also does not assert not disposed so that this method can be called after summary. return delegate.pullAllFailureAsync(); } - private CompletableFuture assertNotDisposed() - { - if ( isDisposed ) - { - return failedFuture( newResultConsumedError() ); + private CompletableFuture assertNotDisposed() { + if (isDisposed) { + return failedFuture(newResultConsumedError()); } return completedWithNull(); } - boolean isDisposed() - { + boolean isDisposed() { return this.isDisposed; } @Override - public CompletableFuture mapSuccessfulRunCompletionAsync() - { - return this.delegate.mapSuccessfulRunCompletionAsync().thenApply( ignored -> this ); + public CompletableFuture mapSuccessfulRunCompletionAsync() { + return this.delegate.mapSuccessfulRunCompletionAsync().thenApply(ignored -> this); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cursor/ResultCursorFactory.java b/driver/src/main/java/org/neo4j/driver/internal/cursor/ResultCursorFactory.java index 756ebe166a..10915f78ca 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cursor/ResultCursorFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cursor/ResultCursorFactory.java @@ -20,8 +20,7 @@ import java.util.concurrent.CompletionStage; -public interface ResultCursorFactory -{ +public interface ResultCursorFactory { CompletionStage asyncResult(); CompletionStage rxResult(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/cursor/ResultCursorFactoryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cursor/ResultCursorFactoryImpl.java index 370d0b0aee..880be18f3a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cursor/ResultCursorFactoryImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cursor/ResultCursorFactoryImpl.java @@ -18,22 +18,20 @@ */ package org.neo4j.driver.internal.cursor; +import static java.util.Objects.requireNonNull; + import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.internal.handlers.PullAllResponseHandler; import org.neo4j.driver.internal.handlers.RunResponseHandler; import org.neo4j.driver.internal.handlers.pulln.PullResponseHandler; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.spi.Connection; -import static java.util.Objects.requireNonNull; - /** * Bolt V4 */ -public class ResultCursorFactoryImpl implements ResultCursorFactory -{ +public class ResultCursorFactoryImpl implements ResultCursorFactory { private final RunResponseHandler runHandler; private final Connection connection; @@ -42,15 +40,19 @@ public class ResultCursorFactoryImpl implements ResultCursorFactory private final Message runMessage; private final CompletableFuture runFuture; - public ResultCursorFactoryImpl( Connection connection, Message runMessage, RunResponseHandler runHandler, CompletableFuture runFuture, - PullResponseHandler pullHandler, PullAllResponseHandler pullAllHandler ) - { - requireNonNull( connection ); - requireNonNull( runMessage ); - requireNonNull( runHandler ); - requireNonNull( runFuture ); - requireNonNull( pullHandler ); - requireNonNull( pullAllHandler ); + public ResultCursorFactoryImpl( + Connection connection, + Message runMessage, + RunResponseHandler runHandler, + CompletableFuture runFuture, + PullResponseHandler pullHandler, + PullAllResponseHandler pullAllHandler) { + requireNonNull(connection); + requireNonNull(runMessage); + requireNonNull(runHandler); + requireNonNull(runFuture); + requireNonNull(pullHandler); + requireNonNull(pullAllHandler); this.connection = connection; this.runMessage = runMessage; @@ -61,18 +63,17 @@ public ResultCursorFactoryImpl( Connection connection, Message runMessage, RunRe } @Override - public CompletionStage asyncResult() - { + public CompletionStage asyncResult() { // only write and flush messages when async result is wanted. - connection.write( runMessage, runHandler ); // queues the run message, will be flushed with pull message together + connection.write(runMessage, runHandler); // queues the run message, will be flushed with pull message together pullAllHandler.prePopulateRecords(); - return runFuture.handle( ( ignored, error ) -> new DisposableAsyncResultCursor( new AsyncResultCursorImpl( error, runHandler, pullAllHandler ) ) ); + return runFuture.handle((ignored, error) -> + new DisposableAsyncResultCursor(new AsyncResultCursorImpl(error, runHandler, pullAllHandler))); } @Override - public CompletionStage rxResult() - { - connection.writeAndFlush( runMessage, runHandler ); - return runFuture.handle( ( ignored, error ) -> new RxResultCursorImpl( error, runHandler, pullHandler ) ); + public CompletionStage rxResult() { + connection.writeAndFlush(runMessage, runHandler); + return runFuture.handle((ignored, error) -> new RxResultCursorImpl(error, runHandler, pullHandler)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/cursor/RxResultCursor.java b/driver/src/main/java/org/neo4j/driver/internal/cursor/RxResultCursor.java index 503dd8c51b..3f2e29c17f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cursor/RxResultCursor.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cursor/RxResultCursor.java @@ -18,21 +18,18 @@ */ package org.neo4j.driver.internal.cursor; -import org.reactivestreams.Subscription; - import java.util.List; import java.util.concurrent.CompletionStage; import java.util.function.BiConsumer; - import org.neo4j.driver.Record; import org.neo4j.driver.internal.FailableCursor; import org.neo4j.driver.summary.ResultSummary; +import org.reactivestreams.Subscription; -public interface RxResultCursor extends Subscription, FailableCursor -{ +public interface RxResultCursor extends Subscription, FailableCursor { List keys(); - void installRecordConsumer( BiConsumer recordConsumer ); + void installRecordConsumer(BiConsumer recordConsumer); CompletionStage summaryAsync(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/cursor/RxResultCursorImpl.java b/driver/src/main/java/org/neo4j/driver/internal/cursor/RxResultCursorImpl.java index 5f85128a21..6f2eb8dcec 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cursor/RxResultCursorImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cursor/RxResultCursorImpl.java @@ -18,27 +18,26 @@ */ package org.neo4j.driver.internal.cursor; +import static org.neo4j.driver.internal.cursor.RxResultCursorImpl.RecordConsumerStatus.DISCARD_INSTALLED; +import static org.neo4j.driver.internal.cursor.RxResultCursorImpl.RecordConsumerStatus.INSTALLED; +import static org.neo4j.driver.internal.cursor.RxResultCursorImpl.RecordConsumerStatus.NOT_INSTALLED; +import static org.neo4j.driver.internal.util.ErrorUtil.newResultConsumedError; + import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.BiConsumer; - import org.neo4j.driver.Record; import org.neo4j.driver.exceptions.TransactionNestingException; import org.neo4j.driver.internal.handlers.RunResponseHandler; import org.neo4j.driver.internal.handlers.pulln.PullResponseHandler; import org.neo4j.driver.summary.ResultSummary; -import static org.neo4j.driver.internal.cursor.RxResultCursorImpl.RecordConsumerStatus.DISCARD_INSTALLED; -import static org.neo4j.driver.internal.cursor.RxResultCursorImpl.RecordConsumerStatus.INSTALLED; -import static org.neo4j.driver.internal.cursor.RxResultCursorImpl.RecordConsumerStatus.NOT_INSTALLED; -import static org.neo4j.driver.internal.util.ErrorUtil.newResultConsumedError; - -public class RxResultCursorImpl implements RxResultCursor -{ - static final BiConsumer DISCARD_RECORD_CONSUMER = ( record, throwable ) -> - {/*do nothing*/}; +public class RxResultCursorImpl implements RxResultCursor { + static final BiConsumer DISCARD_RECORD_CONSUMER = (record, throwable) -> { + /*do nothing*/ + }; private final RunResponseHandler runHandler; private final PullResponseHandler pullHandler; private final Throwable runResponseError; @@ -47,15 +46,13 @@ public class RxResultCursorImpl implements RxResultCursor private boolean resultConsumed; private RecordConsumerStatus consumerStatus = NOT_INSTALLED; - public RxResultCursorImpl( RunResponseHandler runHandler, PullResponseHandler pullHandler ) - { - this( null, runHandler, pullHandler ); + public RxResultCursorImpl(RunResponseHandler runHandler, PullResponseHandler pullHandler) { + this(null, runHandler, pullHandler); } - public RxResultCursorImpl( Throwable runError, RunResponseHandler runHandler, PullResponseHandler pullHandler ) - { - Objects.requireNonNull( runHandler ); - Objects.requireNonNull( pullHandler ); + public RxResultCursorImpl(Throwable runError, RunResponseHandler runHandler, PullResponseHandler pullHandler) { + Objects.requireNonNull(runHandler); + Objects.requireNonNull(pullHandler); this.runResponseError = runError; this.runHandler = runHandler; @@ -64,136 +61,115 @@ public RxResultCursorImpl( Throwable runError, RunResponseHandler runHandler, Pu } @Override - public List keys() - { + public List keys() { return runHandler.queryKeys().keys(); } @Override - public void installRecordConsumer( BiConsumer recordConsumer ) - { - if ( resultConsumed ) - { + public void installRecordConsumer(BiConsumer recordConsumer) { + if (resultConsumed) { throw newResultConsumedError(); } - if ( consumerStatus.isInstalled() ) - { + if (consumerStatus.isInstalled()) { return; } - consumerStatus = recordConsumer == DISCARD_RECORD_CONSUMER ? - DISCARD_INSTALLED : INSTALLED; - pullHandler.installRecordConsumer( recordConsumer ); + consumerStatus = recordConsumer == DISCARD_RECORD_CONSUMER ? DISCARD_INSTALLED : INSTALLED; + pullHandler.installRecordConsumer(recordConsumer); assertRunCompletedSuccessfully(); } @Override - public void request( long n ) - { - if ( n == Long.MAX_VALUE ) - { + public void request(long n) { + if (n == Long.MAX_VALUE) { n = -1; } - pullHandler.request( n ); + pullHandler.request(n); } @Override - public void cancel() - { + public void cancel() { pullHandler.cancel(); } @Override - public CompletionStage discardAllFailureAsync() - { + public CompletionStage discardAllFailureAsync() { // calling this method will enforce discarding record stream and finish running cypher query - return summaryStage().thenApply( summary -> (Throwable) null ) - .exceptionally( throwable -> summaryFutureExposed ? null : throwable ); + return summaryStage() + .thenApply(summary -> (Throwable) null) + .exceptionally(throwable -> summaryFutureExposed ? null : throwable); } @Override - public CompletionStage pullAllFailureAsync() - { - if ( consumerStatus.isInstalled() && !isDone() ) - { - return CompletableFuture.completedFuture( new TransactionNestingException( - "You cannot run another query or begin a new transaction in the same session before you've fully consumed the previous run result." ) ); + public CompletionStage pullAllFailureAsync() { + if (consumerStatus.isInstalled() && !isDone()) { + return CompletableFuture.completedFuture( + new TransactionNestingException( + "You cannot run another query or begin a new transaction in the same session before you've fully consumed the previous run result.")); } - // It is safe to discard records as either the streaming has not started at all, or the streaming is fully finished. + // It is safe to discard records as either the streaming has not started at all, or the streaming is fully + // finished. return discardAllFailureAsync(); } @Override - public CompletionStage summaryAsync() - { + public CompletionStage summaryAsync() { summaryFutureExposed = true; return summaryStage(); } @Override - public boolean isDone() - { + public boolean isDone() { return summaryFuture.isDone(); } - public CompletionStage summaryStage() - { - if ( !isDone() && !resultConsumed ) // the summary is called before record streaming + public CompletionStage summaryStage() { + if (!isDone() && !resultConsumed) // the summary is called before record streaming { - installRecordConsumer( DISCARD_RECORD_CONSUMER ); + installRecordConsumer(DISCARD_RECORD_CONSUMER); cancel(); resultConsumed = true; } return this.summaryFuture; } - private void assertRunCompletedSuccessfully() - { - if ( runResponseError != null ) - { - pullHandler.onFailure( runResponseError ); + private void assertRunCompletedSuccessfully() { + if (runResponseError != null) { + pullHandler.onFailure(runResponseError); } } - private void installSummaryConsumer() - { - pullHandler.installSummaryConsumer( ( summary, error ) -> { - if ( error != null && consumerStatus.isDiscardConsumer() ) - { + private void installSummaryConsumer() { + pullHandler.installSummaryConsumer((summary, error) -> { + if (error != null && consumerStatus.isDiscardConsumer()) { // We will only report the error to summary if there is no user record consumer installed // When a user record consumer is installed, the error will be reported to record consumer instead. - summaryFuture.completeExceptionally( error ); - } - else if ( summary != null ) - { - summaryFuture.complete( summary ); + summaryFuture.completeExceptionally(error); + } else if (summary != null) { + summaryFuture.complete(summary); } - //else (null, null) to indicate a has_more success - } ); + // else (null, null) to indicate a has_more success + }); } - enum RecordConsumerStatus - { - NOT_INSTALLED( false, false ), - INSTALLED( true, false ), - DISCARD_INSTALLED( true, true ); + enum RecordConsumerStatus { + NOT_INSTALLED(false, false), + INSTALLED(true, false), + DISCARD_INSTALLED(true, true); private final boolean isInstalled; private final boolean isDiscardConsumer; - RecordConsumerStatus( boolean isInstalled, boolean isDiscardConsumer ) - { + RecordConsumerStatus(boolean isInstalled, boolean isDiscardConsumer) { this.isInstalled = isInstalled; this.isDiscardConsumer = isDiscardConsumer; } - boolean isInstalled() - { + boolean isInstalled() { return isInstalled; } - boolean isDiscardConsumer() - { + boolean isDiscardConsumer() { return isDiscardConsumer; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/BeginTxResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/BeginTxResponseHandler.java index eb0cb4b929..2394b6987c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/BeginTxResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/BeginTxResponseHandler.java @@ -18,40 +18,34 @@ */ package org.neo4j.driver.internal.handlers; +import static java.util.Objects.requireNonNull; + import java.util.Arrays; import java.util.Map; import java.util.concurrent.CompletableFuture; - -import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.Value; +import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.util.Objects.requireNonNull; - -public class BeginTxResponseHandler implements ResponseHandler -{ +public class BeginTxResponseHandler implements ResponseHandler { private final CompletableFuture beginTxFuture; - public BeginTxResponseHandler( CompletableFuture beginTxFuture ) - { - this.beginTxFuture = requireNonNull( beginTxFuture ); + public BeginTxResponseHandler(CompletableFuture beginTxFuture) { + this.beginTxFuture = requireNonNull(beginTxFuture); } @Override - public void onSuccess( Map metadata ) - { - beginTxFuture.complete( null ); + public void onSuccess(Map metadata) { + beginTxFuture.complete(null); } @Override - public void onFailure( Throwable error ) - { - beginTxFuture.completeExceptionally( error ); + public void onFailure(Throwable error) { + beginTxFuture.completeExceptionally(error); } @Override - public void onRecord( Value[] fields ) - { + public void onRecord(Value[] fields) { throw new UnsupportedOperationException( - "Transaction begin is not expected to receive records: " + Arrays.toString( fields ) ); + "Transaction begin is not expected to receive records: " + Arrays.toString(fields)); } } 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 39aeb32330..d2e6a9378f 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 @@ -18,51 +18,48 @@ */ package org.neo4j.driver.internal.handlers; -import io.netty.channel.Channel; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setLastUsedTimestamp; +import static org.neo4j.driver.internal.util.Futures.asCompletionStage; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import io.netty.channel.Channel; 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; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setLastUsedTimestamp; -import static org.neo4j.driver.internal.util.Futures.asCompletionStage; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; - -public class ChannelReleasingResetResponseHandler extends ResetResponseHandler -{ +public class ChannelReleasingResetResponseHandler extends ResetResponseHandler { private final Channel channel; private final ExtendedChannelPool pool; private final Clock clock; - public ChannelReleasingResetResponseHandler( Channel channel, ExtendedChannelPool pool, - InboundMessageDispatcher messageDispatcher, Clock clock, CompletableFuture releaseFuture ) - { - super( messageDispatcher, releaseFuture ); + public ChannelReleasingResetResponseHandler( + Channel channel, + ExtendedChannelPool pool, + InboundMessageDispatcher messageDispatcher, + Clock clock, + CompletableFuture releaseFuture) { + super(messageDispatcher, releaseFuture); this.channel = channel; this.pool = pool; this.clock = clock; } @Override - protected void resetCompleted( CompletableFuture completionFuture, boolean success ) - { + protected void resetCompleted(CompletableFuture completionFuture, boolean success) { CompletionStage closureStage; - if ( success ) - { + if (success) { // update the last-used timestamp before returning the channel back to the pool - setLastUsedTimestamp( channel, clock.millis() ); + setLastUsedTimestamp(channel, clock.millis()); closureStage = completedWithNull(); - } - else - { + } else { // close the channel before returning it back to the pool if RESET failed - closureStage = asCompletionStage( channel.close() ); + closureStage = asCompletionStage(channel.close()); } - closureStage.exceptionally( throwable -> null ) - .thenCompose( ignored -> pool.release( channel ) ) - .whenComplete( ( ignore, error ) -> completionFuture.complete( null ) ); + closureStage + .exceptionally(throwable -> null) + .thenCompose(ignored -> pool.release(channel)) + .whenComplete((ignore, error) -> completionFuture.complete(null)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/CommitTxResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/CommitTxResponseHandler.java index 2b6fdc2ed8..ff79dee4f3 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/CommitTxResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/CommitTxResponseHandler.java @@ -18,50 +18,41 @@ */ package org.neo4j.driver.internal.handlers; +import static java.util.Objects.requireNonNull; + import java.util.Arrays; import java.util.Map; import java.util.concurrent.CompletableFuture; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalBookmark; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.util.Objects.requireNonNull; - -public class CommitTxResponseHandler implements ResponseHandler -{ +public class CommitTxResponseHandler implements ResponseHandler { private final CompletableFuture commitFuture; - public CommitTxResponseHandler( CompletableFuture commitFuture ) - { - this.commitFuture = requireNonNull( commitFuture ); + public CommitTxResponseHandler(CompletableFuture commitFuture) { + this.commitFuture = requireNonNull(commitFuture); } @Override - public void onSuccess( Map metadata ) - { - Value bookmarkValue = metadata.get( "bookmark" ); - if ( bookmarkValue == null ) - { - commitFuture.complete( null ); - } - else - { - commitFuture.complete( InternalBookmark.parse( bookmarkValue.asString() ) ); + public void onSuccess(Map metadata) { + Value bookmarkValue = metadata.get("bookmark"); + if (bookmarkValue == null) { + commitFuture.complete(null); + } else { + commitFuture.complete(InternalBookmark.parse(bookmarkValue.asString())); } } @Override - public void onFailure( Throwable error ) - { - commitFuture.completeExceptionally( error ); + public void onFailure(Throwable error) { + commitFuture.completeExceptionally(error); } @Override - public void onRecord( Value[] fields ) - { + public void onRecord(Value[] fields) { throw new UnsupportedOperationException( - "Transaction commit is not expected to receive records: " + Arrays.toString( fields ) ); + "Transaction commit is not expected to receive records: " + Arrays.toString(fields)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/HelloResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/HelloResponseHandler.java index af028cef16..2f5eb37f41 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/HelloResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/HelloResponseHandler.java @@ -18,28 +18,25 @@ */ package org.neo4j.driver.internal.handlers; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setConnectionId; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setConnectionReadTimeout; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerAgent; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerVersion; +import static org.neo4j.driver.internal.util.MetadataExtractor.extractNeo4jServerVersion; +import static org.neo4j.driver.internal.util.MetadataExtractor.extractServer; +import static org.neo4j.driver.internal.util.ServerVersion.fromBoltProtocolVersion; + import io.netty.channel.Channel; import io.netty.channel.ChannelPromise; - import java.util.Map; import java.util.Optional; import java.util.function.Supplier; - import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.BoltProtocolVersion; import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; import org.neo4j.driver.internal.spi.ResponseHandler; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setConnectionId; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setConnectionReadTimeout; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerAgent; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerVersion; -import static org.neo4j.driver.internal.util.MetadataExtractor.extractNeo4jServerVersion; -import static org.neo4j.driver.internal.util.MetadataExtractor.extractServer; -import static org.neo4j.driver.internal.util.ServerVersion.fromBoltProtocolVersion; - -public class HelloResponseHandler implements ResponseHandler -{ +public class HelloResponseHandler implements ResponseHandler { private static final String CONNECTION_ID_METADATA_KEY = "connection_id"; public static final String CONFIGURATION_HINTS_KEY = "hints"; public static final String CONNECTION_RECEIVE_TIMEOUT_SECONDS_KEY = "connection.recv_timeout_seconds"; @@ -48,87 +45,71 @@ public class HelloResponseHandler implements ResponseHandler private final Channel channel; private final BoltProtocolVersion protocolVersion; - public HelloResponseHandler( ChannelPromise connectionInitializedPromise, BoltProtocolVersion protocolVersion ) - { + public HelloResponseHandler(ChannelPromise connectionInitializedPromise, BoltProtocolVersion protocolVersion) { this.connectionInitializedPromise = connectionInitializedPromise; this.channel = connectionInitializedPromise.channel(); this.protocolVersion = protocolVersion; } @Override - public void onSuccess( Map metadata ) - { - try - { - Value serverValue = extractServer( metadata ); - setServerAgent( channel, serverValue.asString() ); + public void onSuccess(Map metadata) { + try { + Value serverValue = extractServer(metadata); + setServerAgent(channel, serverValue.asString()); // From Server V4 extracting server from metadata in the success message is unreliable // so we fix the Server version against the Bolt Protocol version for Server V4 and above. - if ( BoltProtocolV3.VERSION.equals( protocolVersion ) ) - { - setServerVersion( channel, extractNeo4jServerVersion( metadata ) ); - } - else - { - setServerVersion( channel, fromBoltProtocolVersion( protocolVersion ) ); + if (BoltProtocolV3.VERSION.equals(protocolVersion)) { + setServerVersion(channel, extractNeo4jServerVersion(metadata)); + } else { + setServerVersion(channel, fromBoltProtocolVersion(protocolVersion)); } - String connectionId = extractConnectionId( metadata ); - setConnectionId( channel, connectionId ); + String connectionId = extractConnectionId(metadata); + setConnectionId(channel, connectionId); - processConfigurationHints( metadata ); + processConfigurationHints(metadata); connectionInitializedPromise.setSuccess(); - } - catch ( Throwable error ) - { - onFailure( error ); + } catch (Throwable error) { + onFailure(error); throw error; } } @Override - public void onFailure( Throwable error ) - { - channel.close().addListener( future -> connectionInitializedPromise.setFailure( error ) ); + public void onFailure(Throwable error) { + channel.close().addListener(future -> connectionInitializedPromise.setFailure(error)); } @Override - public void onRecord( Value[] fields ) - { + public void onRecord(Value[] fields) { throw new UnsupportedOperationException(); } - private static String extractConnectionId( Map metadata ) - { - Value value = metadata.get( CONNECTION_ID_METADATA_KEY ); - if ( value == null || value.isNull() ) - { - throw new IllegalStateException( "Unable to extract " + CONNECTION_ID_METADATA_KEY + " from a response to HELLO message. " + - "Received metadata: " + metadata ); + private static String extractConnectionId(Map metadata) { + Value value = metadata.get(CONNECTION_ID_METADATA_KEY); + if (value == null || value.isNull()) { + throw new IllegalStateException("Unable to extract " + CONNECTION_ID_METADATA_KEY + + " from a response to HELLO message. " + "Received metadata: " + metadata); } return value.asString(); } - private void processConfigurationHints( Map metadata ) - { - Value configurationHints = metadata.get( CONFIGURATION_HINTS_KEY ); - if ( configurationHints != null ) - { - getFromSupplierOrEmptyOnException( () -> configurationHints.get( CONNECTION_RECEIVE_TIMEOUT_SECONDS_KEY ).asLong() ) - .ifPresent( timeout -> setConnectionReadTimeout( channel, timeout ) ); + private void processConfigurationHints(Map metadata) { + Value configurationHints = metadata.get(CONFIGURATION_HINTS_KEY); + if (configurationHints != null) { + getFromSupplierOrEmptyOnException(() -> configurationHints + .get(CONNECTION_RECEIVE_TIMEOUT_SECONDS_KEY) + .asLong()) + .ifPresent(timeout -> setConnectionReadTimeout(channel, timeout)); } } - private static Optional getFromSupplierOrEmptyOnException( Supplier supplier ) - { - try - { - return Optional.of( supplier.get() ); - } - catch ( Exception e ) - { + private static Optional getFromSupplierOrEmptyOnException(Supplier supplier) { + try { + return Optional.of(supplier.get()); + } catch (Exception e) { return Optional.empty(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/LegacyPullAllResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/LegacyPullAllResponseHandler.java index 20b0d51646..490c77219b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/LegacyPullAllResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/LegacyPullAllResponseHandler.java @@ -18,6 +18,12 @@ */ package org.neo4j.driver.internal.handlers; +import static java.util.Collections.emptyMap; +import static java.util.Objects.requireNonNull; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; @@ -26,7 +32,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.Function; - import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -39,21 +44,14 @@ import org.neo4j.driver.internal.util.MetadataExtractor; import org.neo4j.driver.summary.ResultSummary; -import static java.util.Collections.emptyMap; -import static java.util.Objects.requireNonNull; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; - /** * This is the Pull All response handler that handles pull all messages in Bolt v3 and previous protocol versions. */ -public class LegacyPullAllResponseHandler implements PullAllResponseHandler -{ +public class LegacyPullAllResponseHandler implements PullAllResponseHandler { private static final Queue UNINITIALIZED_RECORDS = Iterables.emptyQueue(); - static final int RECORD_BUFFER_LOW_WATERMARK = Integer.getInteger( "recordBufferLowWatermark", 300 ); - static final int RECORD_BUFFER_HIGH_WATERMARK = Integer.getInteger( "recordBufferHighWatermark", 1000 ); + static final int RECORD_BUFFER_LOW_WATERMARK = Integer.getInteger("recordBufferLowWatermark", 300); + static final int RECORD_BUFFER_HIGH_WATERMARK = Integer.getInteger("recordBufferHighWatermark", 1000); private final Query query; private final RunResponseHandler runResponseHandler; @@ -73,68 +71,58 @@ public class LegacyPullAllResponseHandler implements PullAllResponseHandler private CompletableFuture recordFuture; private CompletableFuture failureFuture; - public LegacyPullAllResponseHandler(Query query, RunResponseHandler runResponseHandler, Connection connection, MetadataExtractor metadataExtractor, - PullResponseCompletionListener completionListener ) - { + public LegacyPullAllResponseHandler( + Query query, + RunResponseHandler runResponseHandler, + Connection connection, + MetadataExtractor metadataExtractor, + PullResponseCompletionListener completionListener) { this.query = requireNonNull(query); - this.runResponseHandler = requireNonNull( runResponseHandler ); - this.metadataExtractor = requireNonNull( metadataExtractor ); - this.connection = requireNonNull( connection ); - this.completionListener = requireNonNull( completionListener ); + this.runResponseHandler = requireNonNull(runResponseHandler); + this.metadataExtractor = requireNonNull(metadataExtractor); + this.connection = requireNonNull(connection); + this.completionListener = requireNonNull(completionListener); } @Override - public boolean canManageAutoRead() - { + public boolean canManageAutoRead() { return true; } @Override - public synchronized void onSuccess( Map metadata ) - { + public synchronized void onSuccess(Map metadata) { finished = true; Neo4jException exception = null; - try - { - summary = extractResultSummary( metadata ); - } - catch ( Neo4jException e ) - { + try { + summary = extractResultSummary(metadata); + } catch (Neo4jException e) { exception = e; } - if ( exception == null ) - { - completionListener.afterSuccess( metadata ); + if (exception == null) { + completionListener.afterSuccess(metadata); - completeRecordFuture( null ); - completeFailureFuture( null ); - } - else - { - onFailure( exception ); + completeRecordFuture(null); + completeFailureFuture(null); + } else { + onFailure(exception); } } @Override - public synchronized void onFailure( Throwable error ) - { + public synchronized void onFailure(Throwable error) { finished = true; - summary = extractResultSummary( emptyMap() ); + summary = extractResultSummary(emptyMap()); - completionListener.afterFailure( error ); + completionListener.afterFailure(error); - boolean failedRecordFuture = failRecordFuture( error ); - if ( failedRecordFuture ) - { + boolean failedRecordFuture = failRecordFuture(error); + if (failedRecordFuture) { // error propagated through the record future - completeFailureFuture( null ); - } - else - { - boolean completedFailureFuture = completeFailureFuture( error ); - if ( !completedFailureFuture ) - { + completeFailureFuture(null); + } else { + boolean completedFailureFuture = completeFailureFuture(error); + if (!completedFailureFuture) { // error has not been propagated to the user, remember it failure = error; } @@ -142,104 +130,77 @@ public synchronized void onFailure( Throwable error ) } @Override - public synchronized void onRecord( Value[] fields ) - { - if ( ignoreRecords ) - { - completeRecordFuture( null ); - } - else - { - Record record = new InternalRecord( runResponseHandler.queryKeys(), fields ); - enqueueRecord( record ); - completeRecordFuture( record ); + public synchronized void onRecord(Value[] fields) { + if (ignoreRecords) { + completeRecordFuture(null); + } else { + Record record = new InternalRecord(runResponseHandler.queryKeys(), fields); + enqueueRecord(record); + completeRecordFuture(record); } } @Override - public synchronized void disableAutoReadManagement() - { + public synchronized void disableAutoReadManagement() { autoReadManagementEnabled = false; } - public synchronized CompletionStage peekAsync() - { + public synchronized CompletionStage peekAsync() { Record record = records.peek(); - if ( record == null ) - { - if ( failure != null ) - { - return failedFuture( extractFailure() ); + if (record == null) { + if (failure != null) { + return failedFuture(extractFailure()); } - if ( ignoreRecords || finished ) - { + if (ignoreRecords || finished) { return completedWithNull(); } - if ( recordFuture == null ) - { + if (recordFuture == null) { recordFuture = new CompletableFuture<>(); } return recordFuture; - } - else - { - return completedFuture( record ); + } else { + return completedFuture(record); } } - public synchronized CompletionStage nextAsync() - { - return peekAsync().thenApply( ignore -> dequeueRecord() ); + public synchronized CompletionStage nextAsync() { + return peekAsync().thenApply(ignore -> dequeueRecord()); } - public synchronized CompletionStage consumeAsync() - { + public synchronized CompletionStage consumeAsync() { ignoreRecords = true; records.clear(); - return pullAllFailureAsync().thenApply( error -> - { - if ( error != null ) - { - throw Futures.asCompletionException( error ); + return pullAllFailureAsync().thenApply(error -> { + if (error != null) { + throw Futures.asCompletionException(error); } return summary; - } ); + }); } - public synchronized CompletionStage> listAsync( Function mapFunction ) - { - return pullAllFailureAsync().thenApply( error -> - { - if ( error != null ) - { - throw Futures.asCompletionException( error ); + public synchronized CompletionStage> listAsync(Function mapFunction) { + return pullAllFailureAsync().thenApply(error -> { + if (error != null) { + throw Futures.asCompletionException(error); } - return recordsAsList( mapFunction ); - } ); + return recordsAsList(mapFunction); + }); } @Override - public void prePopulateRecords() - { - connection.writeAndFlush( PullAllMessage.PULL_ALL, this ); + public void prePopulateRecords() { + connection.writeAndFlush(PullAllMessage.PULL_ALL, this); } - public synchronized CompletionStage pullAllFailureAsync() - { - if ( failure != null ) - { - return completedFuture( extractFailure() ); - } - else if ( finished ) - { + public synchronized CompletionStage pullAllFailureAsync() { + if (failure != null) { + return completedFuture(extractFailure()); + } else if (finished) { return completedWithNull(); - } - else - { - if ( failureFuture == null ) - { + } else { + if (failureFuture == null) { // neither SUCCESS nor FAILURE message has arrived, register future to be notified when it arrives // future will be completed with null on SUCCESS and completed with Throwable on FAILURE // enable auto-read, otherwise we might not read SUCCESS/FAILURE if records are not consumed @@ -250,21 +211,18 @@ else if ( finished ) } } - private void enqueueRecord( Record record ) - { - if ( records == UNINITIALIZED_RECORDS ) - { + private void enqueueRecord(Record record) { + if (records == UNINITIALIZED_RECORDS) { records = new ArrayDeque<>(); } - records.add( record ); + records.add(record); boolean shouldBufferAllRecords = failureFuture != null; // when failure is requested we have to buffer all remaining records and then return the error // do not disable auto-read in this case, otherwise records will not be consumed and trailing // SUCCESS or FAILURE message will not arrive as well, so callers will get stuck waiting for the error - if ( !shouldBufferAllRecords && records.size() > RECORD_BUFFER_HIGH_WATERMARK ) - { + if (!shouldBufferAllRecords && records.size() > RECORD_BUFFER_HIGH_WATERMARK) { // more than high watermark records are already queued, tell connection to stop auto-reading from network // this is needed to deal with slow consumers, we do not want to buffer all records in memory if they are // fetched from network faster than consumed @@ -272,12 +230,10 @@ private void enqueueRecord( Record record ) } } - private Record dequeueRecord() - { + private Record dequeueRecord() { Record record = records.poll(); - if ( records.size() < RECORD_BUFFER_LOW_WATERMARK ) - { + if (records.size() < RECORD_BUFFER_LOW_WATERMARK) { // less than low watermark records are now available in the buffer, tell connection to pre-fetch more // and populate queue with new records from network enableAutoRead(); @@ -286,27 +242,22 @@ private Record dequeueRecord() return record; } - private List recordsAsList( Function mapFunction ) - { - if ( !finished ) - { - throw new IllegalStateException( "Can't get records as list because SUCCESS or FAILURE did not arrive" ); + private List recordsAsList(Function mapFunction) { + if (!finished) { + throw new IllegalStateException("Can't get records as list because SUCCESS or FAILURE did not arrive"); } - List result = new ArrayList<>( records.size() ); - while ( !records.isEmpty() ) - { + List result = new ArrayList<>(records.size()); + while (!records.isEmpty()) { Record record = records.poll(); - result.add( mapFunction.apply( record ) ); + result.add(mapFunction.apply(record)); } return result; } - private Throwable extractFailure() - { - if ( failure == null ) - { - throw new IllegalStateException( "Can't extract failure because it does not exist" ); + private Throwable extractFailure() { + if (failure == null) { + throw new IllegalStateException("Can't extract failure because it does not exist"); } Throwable error = failure; @@ -314,58 +265,47 @@ private Throwable extractFailure() return error; } - private void completeRecordFuture( Record record ) - { - if ( recordFuture != null ) - { + private void completeRecordFuture(Record record) { + if (recordFuture != null) { CompletableFuture future = recordFuture; recordFuture = null; - future.complete( record ); + future.complete(record); } } - private boolean failRecordFuture( Throwable error ) - { - if ( recordFuture != null ) - { + private boolean failRecordFuture(Throwable error) { + if (recordFuture != null) { CompletableFuture future = recordFuture; recordFuture = null; - future.completeExceptionally( error ); + future.completeExceptionally(error); return true; } return false; } - private boolean completeFailureFuture( Throwable error ) - { - if ( failureFuture != null ) - { + private boolean completeFailureFuture(Throwable error) { + if (failureFuture != null) { CompletableFuture future = failureFuture; failureFuture = null; - future.complete( error ); + future.complete(error); return true; } return false; } - private ResultSummary extractResultSummary( Map metadata ) - { + private ResultSummary extractResultSummary(Map metadata) { long resultAvailableAfter = runResponseHandler.resultAvailableAfter(); - return metadataExtractor.extractSummary( query, connection, resultAvailableAfter, metadata ); + return metadataExtractor.extractSummary(query, connection, resultAvailableAfter, metadata); } - private void enableAutoRead() - { - if ( autoReadManagementEnabled ) - { + private void enableAutoRead() { + if (autoReadManagementEnabled) { connection.enableAutoRead(); } } - private void disableAutoRead() - { - if ( autoReadManagementEnabled ) - { + private void disableAutoRead() { + if (autoReadManagementEnabled) { connection.disableAutoRead(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/NoOpResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/NoOpResponseHandler.java index 3e35c2602a..6f99c347d0 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/NoOpResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/NoOpResponseHandler.java @@ -19,26 +19,18 @@ package org.neo4j.driver.internal.handlers; import java.util.Map; - -import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.Value; +import org.neo4j.driver.internal.spi.ResponseHandler; -public class NoOpResponseHandler implements ResponseHandler -{ +public class NoOpResponseHandler implements ResponseHandler { public static final NoOpResponseHandler INSTANCE = new NoOpResponseHandler(); @Override - public void onSuccess( Map metadata ) - { - } + public void onSuccess(Map metadata) {} @Override - public void onFailure( Throwable error ) - { - } + public void onFailure(Throwable error) {} @Override - public void onRecord( Value[] fields ) - { - } + public void onRecord(Value[] fields) {} } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/PingResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/PingResponseHandler.java index ba3e15461d..54225e78fd 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/PingResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/PingResponseHandler.java @@ -20,44 +20,37 @@ import io.netty.channel.Channel; import io.netty.util.concurrent.Promise; - import java.util.Map; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.Value; import org.neo4j.driver.internal.spi.ResponseHandler; -public class PingResponseHandler implements ResponseHandler -{ +public class PingResponseHandler implements ResponseHandler { private final Promise result; private final Channel channel; private final Logger log; - public PingResponseHandler( Promise result, Channel channel, Logging logging ) - { + public PingResponseHandler(Promise result, Channel channel, Logging logging) { this.result = result; this.channel = channel; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); } @Override - public void onSuccess( Map metadata ) - { - log.trace( "Channel %s pinged successfully", channel ); - result.setSuccess( true ); + public void onSuccess(Map metadata) { + log.trace("Channel %s pinged successfully", channel); + result.setSuccess(true); } @Override - public void onFailure( Throwable error ) - { - log.trace( "Channel %s failed ping %s", channel, error ); - result.setSuccess( false ); + public void onFailure(Throwable error) { + log.trace("Channel %s failed ping %s", channel, error); + result.setSuccess(false); } @Override - public void onRecord( Value[] fields ) - { + public void onRecord(Value[] fields) { throw new UnsupportedOperationException(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/PullAllResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/PullAllResponseHandler.java index 67e3ed6b7f..f0ea4a63d3 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/PullAllResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/PullAllResponseHandler.java @@ -21,20 +21,18 @@ import java.util.List; import java.util.concurrent.CompletionStage; import java.util.function.Function; - import org.neo4j.driver.Record; import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.summary.ResultSummary; -public interface PullAllResponseHandler extends ResponseHandler -{ +public interface PullAllResponseHandler extends ResponseHandler { CompletionStage consumeAsync(); CompletionStage nextAsync(); CompletionStage peekAsync(); - CompletionStage> listAsync( Function mapFunction ); + CompletionStage> listAsync(Function mapFunction); CompletionStage pullAllFailureAsync(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/PullHandlers.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/PullHandlers.java index 5c6396be38..57f64dee30 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/PullHandlers.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/PullHandlers.java @@ -27,37 +27,52 @@ import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; import org.neo4j.driver.internal.spi.Connection; -public class PullHandlers -{ +public class PullHandlers { - public static PullAllResponseHandler newBoltV3PullAllHandler(Query query, RunResponseHandler runHandler, Connection connection, - BookmarkHolder bookmarkHolder, UnmanagedTransaction tx ) - { - PullResponseCompletionListener completionListener = createPullResponseCompletionListener( connection, bookmarkHolder, tx ); + public static PullAllResponseHandler newBoltV3PullAllHandler( + Query query, + RunResponseHandler runHandler, + Connection connection, + BookmarkHolder bookmarkHolder, + UnmanagedTransaction tx) { + PullResponseCompletionListener completionListener = + createPullResponseCompletionListener(connection, bookmarkHolder, tx); - return new LegacyPullAllResponseHandler(query, runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, completionListener ); + return new LegacyPullAllResponseHandler( + query, runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, completionListener); } - public static PullAllResponseHandler newBoltV4AutoPullHandler(Query query, RunResponseHandler runHandler, Connection connection, - BookmarkHolder bookmarkHolder, UnmanagedTransaction tx, long fetchSize ) - { - PullResponseCompletionListener completionListener = createPullResponseCompletionListener( connection, bookmarkHolder, tx ); + public static PullAllResponseHandler newBoltV4AutoPullHandler( + Query query, + RunResponseHandler runHandler, + Connection connection, + BookmarkHolder bookmarkHolder, + UnmanagedTransaction tx, + long fetchSize) { + PullResponseCompletionListener completionListener = + createPullResponseCompletionListener(connection, bookmarkHolder, tx); - return new AutoPullResponseHandler(query, runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, completionListener, fetchSize ); + return new AutoPullResponseHandler( + query, runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, completionListener, fetchSize); } + public static PullResponseHandler newBoltV4BasicPullHandler( + Query query, + RunResponseHandler runHandler, + Connection connection, + BookmarkHolder bookmarkHolder, + UnmanagedTransaction tx) { + PullResponseCompletionListener completionListener = + createPullResponseCompletionListener(connection, bookmarkHolder, tx); - public static PullResponseHandler newBoltV4BasicPullHandler(Query query, RunResponseHandler runHandler, Connection connection, - BookmarkHolder bookmarkHolder, UnmanagedTransaction tx ) - { - PullResponseCompletionListener completionListener = createPullResponseCompletionListener( connection, bookmarkHolder, tx ); - - return new BasicPullResponseHandler(query, runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, completionListener ); + return new BasicPullResponseHandler( + query, runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, completionListener); } - private static PullResponseCompletionListener createPullResponseCompletionListener( Connection connection, BookmarkHolder bookmarkHolder, - UnmanagedTransaction tx ) - { - return tx != null ? new TransactionPullResponseCompletionListener( tx ) : new SessionPullResponseCompletionListener( connection, bookmarkHolder ); + private static PullResponseCompletionListener createPullResponseCompletionListener( + Connection connection, BookmarkHolder bookmarkHolder, UnmanagedTransaction tx) { + return tx != null + ? new TransactionPullResponseCompletionListener(tx) + : new SessionPullResponseCompletionListener(connection, bookmarkHolder); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/PullResponseCompletionListener.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/PullResponseCompletionListener.java index 139350902c..93adad4557 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/PullResponseCompletionListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/PullResponseCompletionListener.java @@ -19,13 +19,10 @@ package org.neo4j.driver.internal.handlers; import java.util.Map; - import org.neo4j.driver.Value; -public interface PullResponseCompletionListener -{ - void afterSuccess( Map metadata ); - - void afterFailure( Throwable error ); +public interface PullResponseCompletionListener { + void afterSuccess(Map metadata); + void afterFailure(Throwable error); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/ResetResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/ResetResponseHandler.java index 7177cd4a0a..82cd04d207 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/ResetResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/ResetResponseHandler.java @@ -20,56 +20,46 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; - +import org.neo4j.driver.Value; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.spi.ResponseHandler; -import org.neo4j.driver.Value; -public class ResetResponseHandler implements ResponseHandler -{ +public class ResetResponseHandler implements ResponseHandler { private final InboundMessageDispatcher messageDispatcher; private final CompletableFuture completionFuture; - public ResetResponseHandler( InboundMessageDispatcher messageDispatcher ) - { - this( messageDispatcher, null ); + public ResetResponseHandler(InboundMessageDispatcher messageDispatcher) { + this(messageDispatcher, null); } - public ResetResponseHandler( InboundMessageDispatcher messageDispatcher, CompletableFuture completionFuture ) - { + public ResetResponseHandler(InboundMessageDispatcher messageDispatcher, CompletableFuture completionFuture) { this.messageDispatcher = messageDispatcher; this.completionFuture = completionFuture; } @Override - public final void onSuccess( Map metadata ) - { - resetCompleted( true ); + public final void onSuccess(Map metadata) { + resetCompleted(true); } @Override - public final void onFailure( Throwable error ) - { - resetCompleted( false ); + public final void onFailure(Throwable error) { + resetCompleted(false); } @Override - public final void onRecord( Value[] fields ) - { + public final void onRecord(Value[] fields) { throw new UnsupportedOperationException(); } - private void resetCompleted( boolean success ) - { + private void resetCompleted(boolean success) { messageDispatcher.clearCurrentError(); - if ( completionFuture != null ) - { - resetCompleted( completionFuture, success ); + if (completionFuture != null) { + resetCompleted(completionFuture, success); } } - protected void resetCompleted( CompletableFuture completionFuture, boolean success ) - { - completionFuture.complete( null ); + protected void resetCompleted(CompletableFuture completionFuture, boolean success) { + completionFuture.complete(null); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/RollbackTxResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/RollbackTxResponseHandler.java index 569158bfc2..feb6659cf4 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/RollbackTxResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/RollbackTxResponseHandler.java @@ -18,40 +18,34 @@ */ package org.neo4j.driver.internal.handlers; +import static java.util.Objects.requireNonNull; + import java.util.Arrays; import java.util.Map; import java.util.concurrent.CompletableFuture; - -import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.Value; +import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.util.Objects.requireNonNull; - -public class RollbackTxResponseHandler implements ResponseHandler -{ +public class RollbackTxResponseHandler implements ResponseHandler { private final CompletableFuture rollbackFuture; - public RollbackTxResponseHandler( CompletableFuture rollbackFuture ) - { - this.rollbackFuture = requireNonNull( rollbackFuture ); + public RollbackTxResponseHandler(CompletableFuture rollbackFuture) { + this.rollbackFuture = requireNonNull(rollbackFuture); } @Override - public void onSuccess( Map metadata ) - { - rollbackFuture.complete( null ); + public void onSuccess(Map metadata) { + rollbackFuture.complete(null); } @Override - public void onFailure( Throwable error ) - { - rollbackFuture.completeExceptionally( error ); + public void onFailure(Throwable error) { + rollbackFuture.completeExceptionally(error); } @Override - public void onRecord( Value[] fields ) - { + public void onRecord(Value[] fields) { throw new UnsupportedOperationException( - "Transaction rollback is not expected to receive records: " + Arrays.toString( fields ) ); + "Transaction rollback is not expected to receive records: " + Arrays.toString(fields)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/RouteMessageResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/RouteMessageResponseHandler.java index 91ab385e4e..d6d5bede06 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/RouteMessageResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/RouteMessageResponseHandler.java @@ -18,74 +18,61 @@ */ package org.neo4j.driver.internal.handlers; +import static java.util.Objects.requireNonNull; + import java.util.Arrays; import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; - import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.util.Objects.requireNonNull; - /** * Handles the RouteMessage response getting the success response * and return its routing table property as the response. */ -public class RouteMessageResponseHandler implements ResponseHandler -{ - private final CompletableFuture> completableFuture; +public class RouteMessageResponseHandler implements ResponseHandler { + private final CompletableFuture> completableFuture; - public RouteMessageResponseHandler( final CompletableFuture> completableFuture ) - { - this.completableFuture = requireNonNull( completableFuture ); + public RouteMessageResponseHandler(final CompletableFuture> completableFuture) { + this.completableFuture = requireNonNull(completableFuture); } @Override - public void onSuccess( Map metadata ) - { - try - { - completableFuture.complete( metadata.get( "rt" ).asMap( Values::value ) ); - } - catch ( Exception ex ) - { - completableFuture.completeExceptionally( ex ); + public void onSuccess(Map metadata) { + try { + completableFuture.complete(metadata.get("rt").asMap(Values::value)); + } catch (Exception ex) { + completableFuture.completeExceptionally(ex); } } @Override - public void onFailure( Throwable error ) - { - completableFuture.completeExceptionally( error ); + public void onFailure(Throwable error) { + completableFuture.completeExceptionally(error); } @Override - public void onRecord( Value[] fields ) - { - completableFuture.completeExceptionally( new UnsupportedOperationException( - "Route is not expected to receive records: " + Arrays.toString( fields ) ) ); + public void onRecord(Value[] fields) { + completableFuture.completeExceptionally(new UnsupportedOperationException( + "Route is not expected to receive records: " + Arrays.toString(fields))); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } RouteMessageResponseHandler that = (RouteMessageResponseHandler) o; - return completableFuture.equals( that.completableFuture ); + return completableFuture.equals(that.completableFuture); } @Override - public int hashCode() - { - return Objects.hash( completableFuture ); + public int hashCode() { + return Objects.hash(completableFuture); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/RoutingResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/RoutingResponseHandler.java index 02d2f6a898..4c8db3df39 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/RoutingResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/RoutingResponseHandler.java @@ -18,9 +18,10 @@ */ package org.neo4j.driver.internal.handlers; +import static java.lang.String.format; + import java.util.Map; import java.util.Objects; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Value; import org.neo4j.driver.exceptions.ClientException; @@ -32,18 +33,17 @@ import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.internal.util.Futures; -import static java.lang.String.format; - -public class RoutingResponseHandler implements ResponseHandler -{ +public class RoutingResponseHandler implements ResponseHandler { private final ResponseHandler delegate; private final BoltServerAddress address; private final AccessMode accessMode; private final RoutingErrorHandler errorHandler; - public RoutingResponseHandler( ResponseHandler delegate, BoltServerAddress address, AccessMode accessMode, - RoutingErrorHandler errorHandler ) - { + public RoutingResponseHandler( + ResponseHandler delegate, + BoltServerAddress address, + AccessMode accessMode, + RoutingErrorHandler errorHandler) { this.delegate = delegate; this.address = address; this.accessMode = accessMode; @@ -51,98 +51,78 @@ public RoutingResponseHandler( ResponseHandler delegate, BoltServerAddress addre } @Override - public void onSuccess( Map metadata ) - { - delegate.onSuccess( metadata ); + public void onSuccess(Map metadata) { + delegate.onSuccess(metadata); } @Override - public void onFailure( Throwable error ) - { - Throwable newError = handledError( error ); - delegate.onFailure( newError ); + public void onFailure(Throwable error) { + Throwable newError = handledError(error); + delegate.onFailure(newError); } @Override - public void onRecord( Value[] fields ) - { - delegate.onRecord( fields ); + public void onRecord(Value[] fields) { + delegate.onRecord(fields); } @Override - public boolean canManageAutoRead() - { + public boolean canManageAutoRead() { return delegate.canManageAutoRead(); } @Override - public void disableAutoReadManagement() - { + public void disableAutoReadManagement() { delegate.disableAutoReadManagement(); } - private Throwable handledError( Throwable receivedError ) - { - Throwable error = Futures.completionExceptionCause( receivedError ); + private Throwable handledError(Throwable receivedError) { + Throwable error = Futures.completionExceptionCause(receivedError); - if ( error instanceof ServiceUnavailableException ) - { - return handledServiceUnavailableException( ((ServiceUnavailableException) error) ); - } - else if ( error instanceof ClientException ) - { - return handledClientException( ((ClientException) error) ); - } - else if ( error instanceof TransientException ) - { - return handledTransientException( ((TransientException) error) ); - } - else - { + if (error instanceof ServiceUnavailableException) { + return handledServiceUnavailableException(((ServiceUnavailableException) error)); + } else if (error instanceof ClientException) { + return handledClientException(((ClientException) error)); + } else if (error instanceof TransientException) { + return handledTransientException(((TransientException) error)); + } else { return error; } } - private Throwable handledServiceUnavailableException( ServiceUnavailableException e ) - { - errorHandler.onConnectionFailure( address ); - return new SessionExpiredException( format( "Server at %s is no longer available", address ), e ); + private Throwable handledServiceUnavailableException(ServiceUnavailableException e) { + errorHandler.onConnectionFailure(address); + return new SessionExpiredException(format("Server at %s is no longer available", address), e); } - private Throwable handledTransientException( TransientException e ) - { + private Throwable handledTransientException(TransientException e) { String errorCode = e.code(); - if ( Objects.equals( errorCode, "Neo.TransientError.General.DatabaseUnavailable" ) ) - { - errorHandler.onConnectionFailure( address ); + if (Objects.equals(errorCode, "Neo.TransientError.General.DatabaseUnavailable")) { + errorHandler.onConnectionFailure(address); } return e; } - private Throwable handledClientException( ClientException e ) - { - if ( isFailureToWrite( e ) ) - { + private Throwable handledClientException(ClientException e) { + if (isFailureToWrite(e)) { // The server is unaware of the session mode, so we have to implement this logic in the driver. // In the future, we might be able to move this logic to the server. - switch ( accessMode ) - { - case READ: - return new ClientException( "Write queries cannot be performed in READ access mode." ); - case WRITE: - errorHandler.onWriteFailure( address ); - return new SessionExpiredException( format( "Server at %s no longer accepts writes", address ) ); - default: - throw new IllegalArgumentException( accessMode + " not supported." ); + switch (accessMode) { + case READ: + return new ClientException("Write queries cannot be performed in READ access mode."); + case WRITE: + errorHandler.onWriteFailure(address); + return new SessionExpiredException(format("Server at %s no longer accepts writes", address)); + default: + throw new IllegalArgumentException(accessMode + " not supported."); } } return e; } - private static boolean isFailureToWrite( ClientException e ) - { + private static boolean isFailureToWrite(ClientException e) { String errorCode = e.code(); - return Objects.equals( errorCode, "Neo.ClientError.Cluster.NotALeader" ) || - Objects.equals( errorCode, "Neo.ClientError.General.ForbiddenOnReadOnlyDatabase" ); + return Objects.equals(errorCode, "Neo.ClientError.Cluster.NotALeader") + || Objects.equals(errorCode, "Neo.ClientError.General.ForbiddenOnReadOnlyDatabase"); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/RunResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/RunResponseHandler.java index 31a6a69e5c..97ecf0db8a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/RunResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/RunResponseHandler.java @@ -20,7 +20,6 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; - import org.neo4j.driver.Value; import org.neo4j.driver.exceptions.AuthorizationExpiredException; import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; @@ -30,8 +29,7 @@ import org.neo4j.driver.internal.util.MetadataExtractor; import org.neo4j.driver.internal.util.QueryKeys; -public class RunResponseHandler implements ResponseHandler -{ +public class RunResponseHandler implements ResponseHandler { private final CompletableFuture runFuture; private final MetadataExtractor metadataExtractor; private long queryId = MetadataExtractor.ABSENT_QUERY_ID; @@ -42,8 +40,11 @@ public class RunResponseHandler implements ResponseHandler private final Connection connection; private final UnmanagedTransaction tx; - public RunResponseHandler( CompletableFuture runFuture, MetadataExtractor metadataExtractor, Connection connection, UnmanagedTransaction tx ) - { + public RunResponseHandler( + CompletableFuture runFuture, + MetadataExtractor metadataExtractor, + Connection connection, + UnmanagedTransaction tx) { this.runFuture = runFuture; this.metadataExtractor = metadataExtractor; this.connection = connection; @@ -51,51 +52,40 @@ public RunResponseHandler( CompletableFuture runFuture, MetadataExtractor } @Override - public void onSuccess( Map metadata ) - { - queryKeys = metadataExtractor.extractQueryKeys( metadata ); - resultAvailableAfter = metadataExtractor.extractResultAvailableAfter( metadata ); - queryId = metadataExtractor.extractQueryId( metadata ); + public void onSuccess(Map metadata) { + queryKeys = metadataExtractor.extractQueryKeys(metadata); + resultAvailableAfter = metadataExtractor.extractResultAvailableAfter(metadata); + queryId = metadataExtractor.extractQueryId(metadata); - runFuture.complete( null ); + runFuture.complete(null); } @Override - public void onFailure( Throwable error ) - { - if ( tx != null ) - { - tx.markTerminated( error ); - } - else if ( error instanceof AuthorizationExpiredException ) - { - connection.terminateAndRelease( AuthorizationExpiredException.DESCRIPTION ); - } - else if ( error instanceof ConnectionReadTimeoutException ) - { - connection.terminateAndRelease( error.getMessage() ); + public void onFailure(Throwable error) { + if (tx != null) { + tx.markTerminated(error); + } else if (error instanceof AuthorizationExpiredException) { + connection.terminateAndRelease(AuthorizationExpiredException.DESCRIPTION); + } else if (error instanceof ConnectionReadTimeoutException) { + connection.terminateAndRelease(error.getMessage()); } - runFuture.completeExceptionally( error ); + runFuture.completeExceptionally(error); } @Override - public void onRecord( Value[] fields ) - { + public void onRecord(Value[] fields) { throw new UnsupportedOperationException(); } - public QueryKeys queryKeys() - { + public QueryKeys queryKeys() { return queryKeys; } - public long resultAvailableAfter() - { + public long resultAvailableAfter() { return resultAvailableAfter; } - public long queryId() - { + public long queryId() { return queryId; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/SessionPullResponseCompletionListener.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/SessionPullResponseCompletionListener.java index 5ff2d63dc0..c09379c1e2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/SessionPullResponseCompletionListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/SessionPullResponseCompletionListener.java @@ -18,8 +18,9 @@ */ package org.neo4j.driver.internal.handlers; -import java.util.Map; +import static java.util.Objects.requireNonNull; +import java.util.Map; import org.neo4j.driver.Value; import org.neo4j.driver.exceptions.AuthorizationExpiredException; import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; @@ -27,45 +28,33 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.MetadataExtractor; -import static java.util.Objects.requireNonNull; - -public class SessionPullResponseCompletionListener implements PullResponseCompletionListener -{ +public class SessionPullResponseCompletionListener implements PullResponseCompletionListener { private final BookmarkHolder bookmarkHolder; private final Connection connection; - public SessionPullResponseCompletionListener( Connection connection, BookmarkHolder bookmarkHolder ) - { - this.connection = requireNonNull( connection ); - this.bookmarkHolder = requireNonNull( bookmarkHolder ); + public SessionPullResponseCompletionListener(Connection connection, BookmarkHolder bookmarkHolder) { + this.connection = requireNonNull(connection); + this.bookmarkHolder = requireNonNull(bookmarkHolder); } @Override - public void afterSuccess( Map metadata ) - { + public void afterSuccess(Map metadata) { releaseConnection(); - bookmarkHolder.setBookmark( MetadataExtractor.extractBookmarks( metadata ) ); + bookmarkHolder.setBookmark(MetadataExtractor.extractBookmarks(metadata)); } @Override - public void afterFailure( Throwable error ) - { - if ( error instanceof AuthorizationExpiredException ) - { - connection.terminateAndRelease( AuthorizationExpiredException.DESCRIPTION ); - } - else if ( error instanceof ConnectionReadTimeoutException ) - { - connection.terminateAndRelease( error.getMessage() ); - } - else - { + public void afterFailure(Throwable error) { + if (error instanceof AuthorizationExpiredException) { + connection.terminateAndRelease(AuthorizationExpiredException.DESCRIPTION); + } else if (error instanceof ConnectionReadTimeoutException) { + connection.terminateAndRelease(error.getMessage()); + } else { releaseConnection(); } } - private void releaseConnection() - { + private void releaseConnection() { connection.release(); // release in background } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/TransactionPullResponseCompletionListener.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/TransactionPullResponseCompletionListener.java index 3e686f0a53..71b7872259 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/TransactionPullResponseCompletionListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/TransactionPullResponseCompletionListener.java @@ -18,33 +18,27 @@ */ package org.neo4j.driver.internal.handlers; -import java.util.Map; +import static java.util.Objects.requireNonNull; +import java.util.Map; import org.neo4j.driver.Value; import org.neo4j.driver.internal.async.UnmanagedTransaction; -import static java.util.Objects.requireNonNull; - -public class TransactionPullResponseCompletionListener implements PullResponseCompletionListener -{ +public class TransactionPullResponseCompletionListener implements PullResponseCompletionListener { private final UnmanagedTransaction tx; - public TransactionPullResponseCompletionListener( UnmanagedTransaction tx ) - { - this.tx = requireNonNull( tx ); + public TransactionPullResponseCompletionListener(UnmanagedTransaction tx) { + this.tx = requireNonNull(tx); } @Override - public void afterSuccess( Map metadata ) - { - } + public void afterSuccess(Map metadata) {} @Override - public void afterFailure( Throwable error ) - { + public void afterFailure(Throwable error) { // always mark transaction as terminated because every error is "acknowledged" with a RESET message // so database forgets about the transaction after the first error // such transaction should not attempt to commit and can be considered as rolled back - tx.markTerminated( error ); + tx.markTerminated(error); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/AutoPullResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/AutoPullResponseHandler.java index 7ecebef0a4..2d8a392693 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/AutoPullResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/AutoPullResponseHandler.java @@ -18,6 +18,11 @@ */ package org.neo4j.driver.internal.handlers.pulln; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; @@ -25,7 +30,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.Function; - import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.internal.handlers.PullAllResponseHandler; @@ -36,17 +40,11 @@ import org.neo4j.driver.internal.util.MetadataExtractor; import org.neo4j.driver.summary.ResultSummary; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; - /** * Built on top of {@link BasicPullResponseHandler} to be able to pull in batches. * It is exposed as {@link PullAllResponseHandler} as it can automatically pull when running out of records locally. */ -public class AutoPullResponseHandler extends BasicPullResponseHandler implements PullAllResponseHandler -{ +public class AutoPullResponseHandler extends BasicPullResponseHandler implements PullAllResponseHandler { private static final Queue UNINITIALIZED_RECORDS = Iterables.emptyQueue(); private final long fetchSize; private final long lowRecordWatermark; @@ -62,20 +60,21 @@ public class AutoPullResponseHandler extends BasicPullResponseHandler implements private CompletableFuture recordFuture; private CompletableFuture summaryFuture; - public AutoPullResponseHandler(Query query, RunResponseHandler runResponseHandler, Connection connection, MetadataExtractor metadataExtractor, - PullResponseCompletionListener completionListener, long fetchSize ) - { - super(query, runResponseHandler, connection, metadataExtractor, completionListener ); + public AutoPullResponseHandler( + Query query, + RunResponseHandler runResponseHandler, + Connection connection, + MetadataExtractor metadataExtractor, + PullResponseCompletionListener completionListener, + long fetchSize) { + super(query, runResponseHandler, connection, metadataExtractor, completionListener); this.fetchSize = fetchSize; - //For pull everything ensure conditions for disabling auto pull are never met - if ( fetchSize == UNLIMITED_FETCH_SIZE ) - { + // For pull everything ensure conditions for disabling auto pull are never met + if (fetchSize == UNLIMITED_FETCH_SIZE) { this.highRecordWatermark = Long.MAX_VALUE; this.lowRecordWatermark = Long.MAX_VALUE; - } - else - { + } else { this.highRecordWatermark = (long) (fetchSize * 0.7); this.lowRecordWatermark = (long) (fetchSize * 0.3); } @@ -83,91 +82,71 @@ public AutoPullResponseHandler(Query query, RunResponseHandler runResponseHandle installRecordAndSummaryConsumers(); } - private void installRecordAndSummaryConsumers() - { - installRecordConsumer( ( record, error ) -> { - if ( record != null ) - { - enqueueRecord( record ); - completeRecordFuture( record ); + private void installRecordAndSummaryConsumers() { + installRecordConsumer((record, error) -> { + if (record != null) { + enqueueRecord(record); + completeRecordFuture(record); } // if ( error != null ) Handled by summary.error already - if ( record == null && error == null ) - { + if (record == null && error == null) { // complete - completeRecordFuture( null ); + completeRecordFuture(null); } - } ); + }); - installSummaryConsumer( ( summary, error ) -> { - if ( error != null ) - { - handleFailure( error ); + installSummaryConsumer((summary, error) -> { + if (error != null) { + handleFailure(error); } - if ( summary != null ) - { + if (summary != null) { this.summary = summary; - completeSummaryFuture( summary ); + completeSummaryFuture(summary); } - if ( error == null && summary == null ) // has_more + if (error == null && summary == null) // has_more { - if ( isAutoPullEnabled ) - { - request( fetchSize ); + if (isAutoPullEnabled) { + request(fetchSize); } } - } ); + }); } - private void handleFailure( Throwable error ) - { + private void handleFailure(Throwable error) { // error has not been propagated to the user, remember it - if ( !failRecordFuture( error ) && !failSummaryFuture( error ) ) - { + if (!failRecordFuture(error) && !failSummaryFuture(error)) { failure = error; } } - public synchronized CompletionStage peekAsync() - { + public synchronized CompletionStage peekAsync() { Record record = records.peek(); - if ( record == null ) - { - if ( isDone() ) - { - return completedWithValueIfNoFailure( null ); + if (record == null) { + if (isDone()) { + return completedWithValueIfNoFailure(null); } - if ( recordFuture == null ) - { + if (recordFuture == null) { recordFuture = new CompletableFuture<>(); } return recordFuture; - } - else - { - return completedFuture( record ); + } else { + return completedFuture(record); } } - public synchronized CompletionStage nextAsync() - { - return peekAsync().thenApply( ignore -> dequeueRecord() ); + public synchronized CompletionStage nextAsync() { + return peekAsync().thenApply(ignore -> dequeueRecord()); } - public synchronized CompletionStage consumeAsync() - { + public synchronized CompletionStage consumeAsync() { records.clear(); - if ( isDone() ) - { - return completedWithValueIfNoFailure( summary ); - } - else - { + if (isDone()) { + return completedWithValueIfNoFailure(summary); + } else { cancel(); - if ( summaryFuture == null ) - { + if (summaryFuture == null) { summaryFuture = new CompletableFuture<>(); } @@ -175,34 +154,26 @@ public synchronized CompletionStage consumeAsync() } } - public synchronized CompletionStage> listAsync( Function mapFunction ) - { - return pullAllAsync().thenApply( summary -> recordsAsList( mapFunction ) ); + public synchronized CompletionStage> listAsync(Function mapFunction) { + return pullAllAsync().thenApply(summary -> recordsAsList(mapFunction)); } @Override - public synchronized CompletionStage pullAllFailureAsync() - { - return pullAllAsync().handle( ( ignore, error ) -> error ); + public synchronized CompletionStage pullAllFailureAsync() { + return pullAllAsync().handle((ignore, error) -> error); } @Override - public void prePopulateRecords() - { - request( fetchSize ); + public void prePopulateRecords() { + request(fetchSize); } - private synchronized CompletionStage pullAllAsync() - { - if ( isDone() ) - { - return completedWithValueIfNoFailure( summary ); - } - else - { - request( UNLIMITED_FETCH_SIZE ); - if ( summaryFuture == null ) - { + private synchronized CompletionStage pullAllAsync() { + if (isDone()) { + return completedWithValueIfNoFailure(summary); + } else { + request(UNLIMITED_FETCH_SIZE); + if (summaryFuture == null) { summaryFuture = new CompletableFuture<>(); } @@ -210,32 +181,26 @@ private synchronized CompletionStage pullAllAsync() } } - private void enqueueRecord( Record record ) - { - if ( records == UNINITIALIZED_RECORDS ) - { + private void enqueueRecord(Record record) { + if (records == UNINITIALIZED_RECORDS) { records = new ArrayDeque<>(); } - records.add( record ); + records.add(record); // too many records in the queue, pause auto request gathering - if ( records.size() > highRecordWatermark ) - { + if (records.size() > highRecordWatermark) { isAutoPullEnabled = false; } } - private Record dequeueRecord() - { + private Record dequeueRecord() { Record record = records.poll(); - if ( records.size() <= lowRecordWatermark ) - { - //if not in streaming state we need to restart streaming - if ( state() != State.STREAMING_STATE ) - { - request( fetchSize ); + if (records.size() <= lowRecordWatermark) { + // if not in streaming state we need to restart streaming + if (state() != State.STREAMING_STATE) { + request(fetchSize); } isAutoPullEnabled = true; } @@ -243,27 +208,22 @@ private Record dequeueRecord() return record; } - private List recordsAsList( Function mapFunction ) - { - if ( !isDone() ) - { - throw new IllegalStateException( "Can't get records as list because SUCCESS or FAILURE did not arrive" ); + private List recordsAsList(Function mapFunction) { + if (!isDone()) { + throw new IllegalStateException("Can't get records as list because SUCCESS or FAILURE did not arrive"); } - List result = new ArrayList<>( records.size() ); - while ( !records.isEmpty() ) - { + List result = new ArrayList<>(records.size()); + while (!records.isEmpty()) { Record record = records.poll(); - result.add( mapFunction.apply( record ) ); + result.add(mapFunction.apply(record)); } return result; } - private Throwable extractFailure() - { - if ( failure == null ) - { - throw new IllegalStateException( "Can't extract failure because it does not exist" ); + private Throwable extractFailure() { + if (failure == null) { + throw new IllegalStateException("Can't extract failure because it does not exist"); } Throwable error = failure; @@ -271,63 +231,49 @@ private Throwable extractFailure() return error; } - private void completeRecordFuture( Record record ) - { - if ( recordFuture != null ) - { + private void completeRecordFuture(Record record) { + if (recordFuture != null) { CompletableFuture future = recordFuture; recordFuture = null; - future.complete( record ); + future.complete(record); } } - private void completeSummaryFuture( ResultSummary summary ) - { - if ( summaryFuture != null ) - { + private void completeSummaryFuture(ResultSummary summary) { + if (summaryFuture != null) { CompletableFuture future = summaryFuture; summaryFuture = null; - future.complete( summary ); + future.complete(summary); } } - private boolean failRecordFuture( Throwable error ) - { - if ( recordFuture != null ) - { + private boolean failRecordFuture(Throwable error) { + if (recordFuture != null) { CompletableFuture future = recordFuture; recordFuture = null; - future.completeExceptionally( error ); + future.completeExceptionally(error); return true; } return false; } - private boolean failSummaryFuture( Throwable error ) - { - if ( summaryFuture != null ) - { + private boolean failSummaryFuture(Throwable error) { + if (summaryFuture != null) { CompletableFuture future = summaryFuture; summaryFuture = null; - future.completeExceptionally( error ); + future.completeExceptionally(error); return true; } return false; } - private CompletionStage completedWithValueIfNoFailure( T value ) - { - if ( failure != null ) - { - return failedFuture( extractFailure() ); - } - else if ( value == null ) - { + private CompletionStage completedWithValueIfNoFailure(T value) { + if (failure != null) { + return failedFuture(extractFailure()); + } else if (value == null) { return completedWithNull(); - } - else - { - return completedFuture( value ); + } else { + return completedFuture(value); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/BasicPullResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/BasicPullResponseHandler.java index c3c28b2e2b..8c124e7fe3 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/BasicPullResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/BasicPullResponseHandler.java @@ -18,9 +18,14 @@ */ package org.neo4j.driver.internal.handlers.pulln; +import static java.lang.String.format; +import static java.util.Collections.emptyMap; +import static java.util.Objects.requireNonNull; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.internal.messaging.request.DiscardMessage.newDiscardAllMessage; + import java.util.Map; import java.util.function.BiConsumer; - import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -34,17 +39,10 @@ import org.neo4j.driver.internal.value.BooleanValue; import org.neo4j.driver.summary.ResultSummary; -import static java.lang.String.format; -import static java.util.Collections.emptyMap; -import static java.util.Objects.requireNonNull; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.internal.messaging.request.DiscardMessage.newDiscardAllMessage; - /** * Provides basic handling of pull responses from sever. The state is managed by {@link State}. */ -public class BasicPullResponseHandler implements PullResponseHandler -{ +public class BasicPullResponseHandler implements PullResponseHandler { private final Query query; protected final RunResponseHandler runResponseHandler; protected final MetadataExtractor metadataExtractor; @@ -53,403 +51,340 @@ public class BasicPullResponseHandler implements PullResponseHandler private State state; private long toRequest; - private BiConsumer recordConsumer = null; - private BiConsumer summaryConsumer = null; - - public BasicPullResponseHandler( Query query, RunResponseHandler runResponseHandler, - Connection connection, MetadataExtractor metadataExtractor, - PullResponseCompletionListener completionListener ) - { - this.query = requireNonNull( query ); - this.runResponseHandler = requireNonNull( runResponseHandler ); - this.metadataExtractor = requireNonNull( metadataExtractor ); - this.connection = requireNonNull( connection ); - this.completionListener = requireNonNull( completionListener ); + private BiConsumer recordConsumer = null; + private BiConsumer summaryConsumer = null; + + public BasicPullResponseHandler( + Query query, + RunResponseHandler runResponseHandler, + Connection connection, + MetadataExtractor metadataExtractor, + PullResponseCompletionListener completionListener) { + this.query = requireNonNull(query); + this.runResponseHandler = requireNonNull(runResponseHandler); + this.metadataExtractor = requireNonNull(metadataExtractor); + this.connection = requireNonNull(connection); + this.completionListener = requireNonNull(completionListener); this.state = State.READY_STATE; } @Override - public synchronized void onSuccess( Map metadata ) - { + public synchronized void onSuccess(Map metadata) { assertRecordAndSummaryConsumerInstalled(); - state.onSuccess( this, metadata ); + state.onSuccess(this, metadata); } @Override - public synchronized void onFailure( Throwable error ) - { + public synchronized void onFailure(Throwable error) { assertRecordAndSummaryConsumerInstalled(); - state.onFailure( this, error ); + state.onFailure(this, error); } @Override - public synchronized void onRecord( Value[] fields ) - { + public synchronized void onRecord(Value[] fields) { assertRecordAndSummaryConsumerInstalled(); - state.onRecord( this, fields ); + state.onRecord(this, fields); } @Override - public synchronized void request( long size ) - { + public synchronized void request(long size) { assertRecordAndSummaryConsumerInstalled(); - state.request( this, size ); + state.request(this, size); } @Override - public synchronized void cancel() - { + public synchronized void cancel() { assertRecordAndSummaryConsumerInstalled(); - state.cancel( this ); + state.cancel(this); } - protected void completeWithFailure( Throwable error ) - { - completionListener.afterFailure( error ); - complete( extractResultSummary( emptyMap() ), error ); + protected void completeWithFailure(Throwable error) { + completionListener.afterFailure(error); + complete(extractResultSummary(emptyMap()), error); } - protected void completeWithSuccess( Map metadata ) - { - completionListener.afterSuccess( metadata ); + protected void completeWithSuccess(Map metadata) { + completionListener.afterSuccess(metadata); ResultSummary summary; Neo4jException exception = null; - try - { - summary = extractResultSummary( metadata ); - } - catch ( Neo4jException e ) - { - summary = extractResultSummary( emptyMap() ); + try { + summary = extractResultSummary(metadata); + } catch (Neo4jException e) { + summary = extractResultSummary(emptyMap()); exception = e; } - complete( summary, exception ); + complete(summary, exception); } - protected void successHasMore() - { - if ( toRequest > 0 || toRequest == UNLIMITED_FETCH_SIZE ) - { - request( toRequest ); + protected void successHasMore() { + if (toRequest > 0 || toRequest == UNLIMITED_FETCH_SIZE) { + request(toRequest); toRequest = 0; } // summary consumer use (null, null) to identify done handling of success with has_more - summaryConsumer.accept( null, null ); + summaryConsumer.accept(null, null); } - protected void handleRecord( Value[] fields ) - { - Record record = new InternalRecord( runResponseHandler.queryKeys(), fields ); - recordConsumer.accept( record, null ); + protected void handleRecord(Value[] fields) { + Record record = new InternalRecord(runResponseHandler.queryKeys(), fields); + recordConsumer.accept(record, null); } - protected void writePull( long n ) - { - connection.writeAndFlush( new PullMessage( n, runResponseHandler.queryId() ), this ); + protected void writePull(long n) { + connection.writeAndFlush(new PullMessage(n, runResponseHandler.queryId()), this); } - protected void discardAll() - { - connection.writeAndFlush( newDiscardAllMessage( runResponseHandler.queryId() ), this ); + protected void discardAll() { + connection.writeAndFlush(newDiscardAllMessage(runResponseHandler.queryId()), this); } @Override - public synchronized void installSummaryConsumer( BiConsumer summaryConsumer ) - { - if ( this.summaryConsumer != null ) - { - throw new IllegalStateException( "Summary consumer already installed." ); + public synchronized void installSummaryConsumer(BiConsumer summaryConsumer) { + if (this.summaryConsumer != null) { + throw new IllegalStateException("Summary consumer already installed."); } this.summaryConsumer = summaryConsumer; } @Override - public synchronized void installRecordConsumer( BiConsumer recordConsumer ) - { - if ( this.recordConsumer != null ) - { - throw new IllegalStateException( "Record consumer already installed." ); + public synchronized void installRecordConsumer(BiConsumer recordConsumer) { + if (this.recordConsumer != null) { + throw new IllegalStateException("Record consumer already installed."); } this.recordConsumer = recordConsumer; } - protected boolean isDone() - { - return state.equals( State.SUCCEEDED_STATE ) || state.equals( State.FAILURE_STATE ); + protected boolean isDone() { + return state.equals(State.SUCCEEDED_STATE) || state.equals(State.FAILURE_STATE); } - private ResultSummary extractResultSummary( Map metadata ) - { + private ResultSummary extractResultSummary(Map metadata) { long resultAvailableAfter = runResponseHandler.resultAvailableAfter(); - return metadataExtractor.extractSummary( query, connection, resultAvailableAfter, metadata ); + return metadataExtractor.extractSummary(query, connection, resultAvailableAfter, metadata); } - private void addToRequest( long toAdd ) - { - if ( toRequest == UNLIMITED_FETCH_SIZE ) - { + private void addToRequest(long toAdd) { + if (toRequest == UNLIMITED_FETCH_SIZE) { return; } - if ( toAdd == UNLIMITED_FETCH_SIZE ) - { + if (toAdd == UNLIMITED_FETCH_SIZE) { // pull all toRequest = UNLIMITED_FETCH_SIZE; return; } - if ( toAdd <= 0 ) - { - throw new IllegalArgumentException( "Cannot request record amount that is less than or equal to 0. Request amount: " + toAdd ); + if (toAdd <= 0) { + throw new IllegalArgumentException( + "Cannot request record amount that is less than or equal to 0. Request amount: " + toAdd); } toRequest += toAdd; - if ( toRequest <= 0 ) // toAdd is already at least 1, we hit buffer overflow + if (toRequest <= 0) // toAdd is already at least 1, we hit buffer overflow { toRequest = Long.MAX_VALUE; } } - private void assertRecordAndSummaryConsumerInstalled() - { - if ( isDone() ) - { + private void assertRecordAndSummaryConsumerInstalled() { + if (isDone()) { // no need to check if we've finished. return; } - if ( recordConsumer == null || summaryConsumer == null ) - { - throw new IllegalStateException( format( "Access record stream without record consumer and/or summary consumer. " + - "Record consumer=%s, Summary consumer=%s", recordConsumer, summaryConsumer ) ); + if (recordConsumer == null || summaryConsumer == null) { + throw new IllegalStateException(format( + "Access record stream without record consumer and/or summary consumer. " + + "Record consumer=%s, Summary consumer=%s", + recordConsumer, summaryConsumer)); } } - private void complete( ResultSummary summary, Throwable error ) - { + private void complete(ResultSummary summary, Throwable error) { // we first inform the summary consumer to ensure when streaming finished, summary is definitely available. - summaryConsumer.accept( summary, error ); + summaryConsumer.accept(summary, error); // record consumer use (null, null) to identify the end of record stream - recordConsumer.accept( null, error ); + recordConsumer.accept(null, error); dispose(); } - private void dispose() - { - // release the reference to the consumers who hold the reference to subscribers which shall be released when subscription is completed. + private void dispose() { + // release the reference to the consumers who hold the reference to subscribers which shall be released when + // subscription is completed. this.recordConsumer = null; this.summaryConsumer = null; } - protected State state() - { + protected State state() { return state; } - protected void state( State state ) - { + protected void state(State state) { this.state = state; } - enum State - { - READY_STATE - { - @Override - void onSuccess( BasicPullResponseHandler context, Map metadata ) - { - context.state( SUCCEEDED_STATE ); - context.completeWithSuccess( metadata ); - } - - @Override - void onFailure( BasicPullResponseHandler context, Throwable error ) - { - context.state( FAILURE_STATE ); - context.completeWithFailure( error ); - } - - @Override - void onRecord( BasicPullResponseHandler context, Value[] fields ) - { - context.state( READY_STATE ); - } - - @Override - void request( BasicPullResponseHandler context, long n ) - { - context.state( STREAMING_STATE ); - context.writePull( n ); - } - - @Override - void cancel( BasicPullResponseHandler context ) - { - context.state( CANCELLED_STATE ); - context.discardAll(); - } - }, - STREAMING_STATE - { - @Override - void onSuccess( BasicPullResponseHandler context, Map metadata ) - { - if ( metadata.getOrDefault( "has_more", BooleanValue.FALSE ).asBoolean() ) - { - context.state( READY_STATE ); - context.successHasMore(); - } - else - { - context.state( SUCCEEDED_STATE ); - context.completeWithSuccess( metadata ); - } - } - - @Override - void onFailure( BasicPullResponseHandler context, Throwable error ) - { - context.state( FAILURE_STATE ); - context.completeWithFailure( error ); - } - - @Override - void onRecord( BasicPullResponseHandler context, Value[] fields ) - { - context.state( STREAMING_STATE ); - context.handleRecord( fields ); - } - - @Override - void request( BasicPullResponseHandler context, long n ) - { - context.state( STREAMING_STATE ); - context.addToRequest( n ); - } - - @Override - void cancel( BasicPullResponseHandler context ) - { - context.state( CANCELLED_STATE ); - } - }, - CANCELLED_STATE - { - @Override - void onSuccess( BasicPullResponseHandler context, Map metadata ) - { - if ( metadata.getOrDefault( "has_more", BooleanValue.FALSE ).asBoolean() ) - { - context.state( CANCELLED_STATE ); - context.discardAll(); - } - else - { - context.state( SUCCEEDED_STATE ); - context.completeWithSuccess( metadata ); - } - } - - @Override - void onFailure( BasicPullResponseHandler context, Throwable error ) - { - context.state( FAILURE_STATE ); - context.completeWithFailure( error ); - } - - @Override - void onRecord( BasicPullResponseHandler context, Value[] fields ) - { - context.state( CANCELLED_STATE ); - } - - @Override - void request( BasicPullResponseHandler context, long n ) - { - context.state( CANCELLED_STATE ); - } - - @Override - void cancel( BasicPullResponseHandler context ) - { - context.state( CANCELLED_STATE ); - } - }, - SUCCEEDED_STATE - { - @Override - void onSuccess( BasicPullResponseHandler context, Map metadata ) - { - context.state( SUCCEEDED_STATE ); - context.completeWithSuccess( metadata ); - } - - @Override - void onFailure( BasicPullResponseHandler context, Throwable error ) - { - context.state( FAILURE_STATE ); - context.completeWithFailure( error ); - } - - @Override - void onRecord( BasicPullResponseHandler context, Value[] fields ) - { - context.state( SUCCEEDED_STATE ); - } - - @Override - void request( BasicPullResponseHandler context, long n ) - { - context.state( SUCCEEDED_STATE ); - } - - @Override - void cancel( BasicPullResponseHandler context ) - { - context.state( SUCCEEDED_STATE ); - } - }, - FAILURE_STATE - { - @Override - void onSuccess( BasicPullResponseHandler context, Map metadata ) - { - context.state( SUCCEEDED_STATE ); - context.completeWithSuccess( metadata ); - } - - @Override - void onFailure( BasicPullResponseHandler context, Throwable error ) - { - context.state( FAILURE_STATE ); - context.completeWithFailure( error ); - } - - @Override - void onRecord( BasicPullResponseHandler context, Value[] fields ) - { - context.state( FAILURE_STATE ); - } - - @Override - void request( BasicPullResponseHandler context, long n ) - { - context.state( FAILURE_STATE ); - } - - @Override - void cancel( BasicPullResponseHandler context ) - { - context.state( FAILURE_STATE ); - } - }; - - abstract void onSuccess( BasicPullResponseHandler context, Map metadata ); - - abstract void onFailure( BasicPullResponseHandler context, Throwable error ); - - abstract void onRecord( BasicPullResponseHandler context, Value[] fields ); - - abstract void request( BasicPullResponseHandler context, long n ); - - abstract void cancel( BasicPullResponseHandler context ); + enum State { + READY_STATE { + @Override + void onSuccess(BasicPullResponseHandler context, Map metadata) { + context.state(SUCCEEDED_STATE); + context.completeWithSuccess(metadata); + } + + @Override + void onFailure(BasicPullResponseHandler context, Throwable error) { + context.state(FAILURE_STATE); + context.completeWithFailure(error); + } + + @Override + void onRecord(BasicPullResponseHandler context, Value[] fields) { + context.state(READY_STATE); + } + + @Override + void request(BasicPullResponseHandler context, long n) { + context.state(STREAMING_STATE); + context.writePull(n); + } + + @Override + void cancel(BasicPullResponseHandler context) { + context.state(CANCELLED_STATE); + context.discardAll(); + } + }, + STREAMING_STATE { + @Override + void onSuccess(BasicPullResponseHandler context, Map metadata) { + if (metadata.getOrDefault("has_more", BooleanValue.FALSE).asBoolean()) { + context.state(READY_STATE); + context.successHasMore(); + } else { + context.state(SUCCEEDED_STATE); + context.completeWithSuccess(metadata); + } + } + + @Override + void onFailure(BasicPullResponseHandler context, Throwable error) { + context.state(FAILURE_STATE); + context.completeWithFailure(error); + } + + @Override + void onRecord(BasicPullResponseHandler context, Value[] fields) { + context.state(STREAMING_STATE); + context.handleRecord(fields); + } + + @Override + void request(BasicPullResponseHandler context, long n) { + context.state(STREAMING_STATE); + context.addToRequest(n); + } + + @Override + void cancel(BasicPullResponseHandler context) { + context.state(CANCELLED_STATE); + } + }, + CANCELLED_STATE { + @Override + void onSuccess(BasicPullResponseHandler context, Map metadata) { + if (metadata.getOrDefault("has_more", BooleanValue.FALSE).asBoolean()) { + context.state(CANCELLED_STATE); + context.discardAll(); + } else { + context.state(SUCCEEDED_STATE); + context.completeWithSuccess(metadata); + } + } + + @Override + void onFailure(BasicPullResponseHandler context, Throwable error) { + context.state(FAILURE_STATE); + context.completeWithFailure(error); + } + + @Override + void onRecord(BasicPullResponseHandler context, Value[] fields) { + context.state(CANCELLED_STATE); + } + + @Override + void request(BasicPullResponseHandler context, long n) { + context.state(CANCELLED_STATE); + } + + @Override + void cancel(BasicPullResponseHandler context) { + context.state(CANCELLED_STATE); + } + }, + SUCCEEDED_STATE { + @Override + void onSuccess(BasicPullResponseHandler context, Map metadata) { + context.state(SUCCEEDED_STATE); + context.completeWithSuccess(metadata); + } + + @Override + void onFailure(BasicPullResponseHandler context, Throwable error) { + context.state(FAILURE_STATE); + context.completeWithFailure(error); + } + + @Override + void onRecord(BasicPullResponseHandler context, Value[] fields) { + context.state(SUCCEEDED_STATE); + } + + @Override + void request(BasicPullResponseHandler context, long n) { + context.state(SUCCEEDED_STATE); + } + + @Override + void cancel(BasicPullResponseHandler context) { + context.state(SUCCEEDED_STATE); + } + }, + FAILURE_STATE { + @Override + void onSuccess(BasicPullResponseHandler context, Map metadata) { + context.state(SUCCEEDED_STATE); + context.completeWithSuccess(metadata); + } + + @Override + void onFailure(BasicPullResponseHandler context, Throwable error) { + context.state(FAILURE_STATE); + context.completeWithFailure(error); + } + + @Override + void onRecord(BasicPullResponseHandler context, Value[] fields) { + context.state(FAILURE_STATE); + } + + @Override + void request(BasicPullResponseHandler context, long n) { + context.state(FAILURE_STATE); + } + + @Override + void cancel(BasicPullResponseHandler context) { + context.state(FAILURE_STATE); + } + }; + + abstract void onSuccess(BasicPullResponseHandler context, Map metadata); + + abstract void onFailure(BasicPullResponseHandler context, Throwable error); + + abstract void onRecord(BasicPullResponseHandler context, Value[] fields); + + abstract void request(BasicPullResponseHandler context, long n); + + abstract void cancel(BasicPullResponseHandler context); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/FetchSizeUtil.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/FetchSizeUtil.java index 57a66aca4e..193379abee 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/FetchSizeUtil.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/FetchSizeUtil.java @@ -18,16 +18,14 @@ */ package org.neo4j.driver.internal.handlers.pulln; -public class FetchSizeUtil -{ +public class FetchSizeUtil { public static final long UNLIMITED_FETCH_SIZE = -1; public static final long DEFAULT_FETCH_SIZE = 1000; - public static long assertValidFetchSize( long size ) - { - if ( size <= 0 && size != UNLIMITED_FETCH_SIZE ) - { - throw new IllegalArgumentException( String.format( "The record fetch size may not be 0 or negative. Illegal record fetch size: %s.", size ) ); + public static long assertValidFetchSize(long size) { + if (size <= 0 && size != UNLIMITED_FETCH_SIZE) { + throw new IllegalArgumentException(String.format( + "The record fetch size may not be 0 or negative. Illegal record fetch size: %s.", size)); } return size; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/PullResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/PullResponseHandler.java index 00654d7359..d144b6b83b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/PullResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/pulln/PullResponseHandler.java @@ -18,23 +18,20 @@ */ package org.neo4j.driver.internal.handlers.pulln; -import org.reactivestreams.Subscription; - import java.util.function.BiConsumer; - -import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.Record; +import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.summary.ResultSummary; +import org.reactivestreams.Subscription; -public interface PullResponseHandler extends ResponseHandler, Subscription -{ +public interface PullResponseHandler extends ResponseHandler, Subscription { /** * Register a record consumer for each record received. * STREAMING shall not be started before this consumer is registered. * A null record with no error indicates the end of streaming. * @param recordConsumer register a record consumer to be notified for each record received. */ - void installRecordConsumer( BiConsumer recordConsumer ); + void installRecordConsumer(BiConsumer recordConsumer); /** * Register a summary consumer to be notified when a summary is received. @@ -42,6 +39,5 @@ public interface PullResponseHandler extends ResponseHandler, Subscription * A null summary with no error indicates a SUCCESS message with has_more=true has arrived. * @param summaryConsumer register a summary consumer */ - void installSummaryConsumer( BiConsumer summaryConsumer ); - + void installSummaryConsumer(BiConsumer summaryConsumer); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/ChannelActivityLogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/ChannelActivityLogger.java index 5ccd1f1ef9..a94e28e564 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/ChannelActivityLogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/ChannelActivityLogger.java @@ -18,65 +18,57 @@ */ package org.neo4j.driver.internal.logging; -import io.netty.channel.Channel; +import static java.lang.String.format; +import static org.neo4j.driver.internal.util.Format.valueOrEmpty; +import io.netty.channel.Channel; import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.connection.ChannelAttributes; -import static java.lang.String.format; -import static org.neo4j.driver.internal.util.Format.valueOrEmpty; - -public class ChannelActivityLogger extends ReformattedLogger -{ +public class ChannelActivityLogger extends ReformattedLogger { private final Channel channel; private final String localChannelId; private String dbConnectionId; private String serverAddress; - public ChannelActivityLogger( Channel channel, Logging logging, Class owner ) - { - this( channel, logging.getLog( owner ) ); + public ChannelActivityLogger(Channel channel, Logging logging, Class owner) { + this(channel, logging.getLog(owner)); } - private ChannelActivityLogger( Channel channel, Logger delegate ) - { - super( delegate ); + private ChannelActivityLogger(Channel channel, Logger delegate) { + super(delegate); this.channel = channel; this.localChannelId = channel != null ? channel.id().toString() : null; } @Override - protected String reformat( String message ) - { - if ( channel == null ) - { + protected String reformat(String message) { + if (channel == null) { return message; } String dbConnectionId = getDbConnectionId(); String serverAddress = getServerAddress(); - return format( "[0x%s][%s][%s] %s", localChannelId, valueOrEmpty( serverAddress ), valueOrEmpty( dbConnectionId ), message ); + return format( + "[0x%s][%s][%s] %s", + localChannelId, valueOrEmpty(serverAddress), valueOrEmpty(dbConnectionId), message); } - private String getDbConnectionId() - { - if ( dbConnectionId == null ) - { - dbConnectionId = ChannelAttributes.connectionId( channel ); + private String getDbConnectionId() { + if (dbConnectionId == null) { + dbConnectionId = ChannelAttributes.connectionId(channel); } return dbConnectionId; } - private String getServerAddress() - { + private String getServerAddress() { - if ( serverAddress == null ) - { - BoltServerAddress serverAddress = ChannelAttributes.serverAddress( channel ); + if (serverAddress == null) { + BoltServerAddress serverAddress = ChannelAttributes.serverAddress(channel); this.serverAddress = serverAddress != null ? serverAddress.toString() : null; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/ChannelErrorLogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/ChannelErrorLogger.java index 82262c52f8..615a20e394 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/ChannelErrorLogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/ChannelErrorLogger.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.logging; import io.netty.channel.Channel; - import org.neo4j.driver.Logging; /** @@ -27,24 +26,18 @@ *

* It keeps messages shorter in debug mode and provides more details in trace mode. */ -public class ChannelErrorLogger extends ChannelActivityLogger -{ +public class ChannelErrorLogger extends ChannelActivityLogger { private static final String DEBUG_MESSAGE_FORMAT = "%s (%s)"; - public ChannelErrorLogger( Channel channel, Logging logging ) - { - super( channel, logging, ChannelErrorLogger.class ); + public ChannelErrorLogger(Channel channel, Logging logging) { + super(channel, logging, ChannelErrorLogger.class); } - public void traceOrDebug( String message, Throwable error ) - { - if ( isTraceEnabled() ) - { - trace( message, error ); - } - else - { - debug( String.format( DEBUG_MESSAGE_FORMAT, message, error.getClass() ) ); + public void traceOrDebug(String message, Throwable error) { + if (isTraceEnabled()) { + trace(message, error); + } else { + debug(String.format(DEBUG_MESSAGE_FORMAT, message, error.getClass())); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/ConsoleLogging.java b/driver/src/main/java/org/neo4j/driver/internal/logging/ConsoleLogging.java index bf6d55e436..fe415bc49f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/ConsoleLogging.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/ConsoleLogging.java @@ -18,6 +18,8 @@ */ package org.neo4j.driver.internal.logging; +import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME; + import java.io.PrintWriter; import java.io.Serializable; import java.io.StringWriter; @@ -28,82 +30,68 @@ import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; -import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME; - /** * Internal implementation of the console logging. * This class should not be used directly. Please use {@link Logging#console(Level)} factory method instead. * * @see Logging#console(Level) */ -public class ConsoleLogging implements Logging, Serializable -{ +public class ConsoleLogging implements Logging, Serializable { private static final long serialVersionUID = 9205935204074879150L; private final Level level; - public ConsoleLogging( Level level ) - { - this.level = Objects.requireNonNull( level ); + public ConsoleLogging(Level level) { + this.level = Objects.requireNonNull(level); } @Override - public Logger getLog( String name ) - { - return new ConsoleLogger( name, level ); + public Logger getLog(String name) { + return new ConsoleLogger(name, level); } - public static class ConsoleLogger extends JULogger - { + public static class ConsoleLogger extends JULogger { private final ConsoleHandler handler; - public ConsoleLogger( String name, Level level ) - { - super( name, level ); - java.util.logging.Logger logger = java.util.logging.Logger.getLogger( name ); + public ConsoleLogger(String name, Level level) { + super(name, level); + java.util.logging.Logger logger = java.util.logging.Logger.getLogger(name); - logger.setUseParentHandlers( false ); + logger.setUseParentHandlers(false); // remove all other logging handlers Handler[] handlers = logger.getHandlers(); - for ( Handler handlerToRemove : handlers ) - { - logger.removeHandler( handlerToRemove ); + for (Handler handlerToRemove : handlers) { + logger.removeHandler(handlerToRemove); } handler = new ConsoleHandler(); - handler.setFormatter( new ConsoleFormatter() ); - handler.setLevel( level ); - logger.addHandler( handler ); - logger.setLevel( level ); + handler.setFormatter(new ConsoleFormatter()); + handler.setLevel(level); + logger.addHandler(handler); + logger.setLevel(level); } } - private static class ConsoleFormatter extends Formatter - { + private static class ConsoleFormatter extends Formatter { @Override - public String format( LogRecord record ) - { - return LocalDateTime.now().format( ISO_LOCAL_DATE_TIME ) + " " + - record.getLevel() + " " + - record.getLoggerName() + " - " + - formatMessage( record ) + - formatThrowable( record.getThrown() ) + - "\n"; + public String format(LogRecord record) { + return LocalDateTime.now().format(ISO_LOCAL_DATE_TIME) + " " + record.getLevel() + + " " + record.getLoggerName() + + " - " + formatMessage(record) + + formatThrowable(record.getThrown()) + + "\n"; } - private String formatThrowable( Throwable throwable ) - { + private String formatThrowable(Throwable throwable) { String throwableString = ""; - if ( throwable != null ) - { + if (throwable != null) { StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter( sw ); + PrintWriter pw = new PrintWriter(sw); pw.println(); - throwable.printStackTrace( pw ); + throwable.printStackTrace(pw); pw.close(); throwableString = sw.toString(); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/DevNullLogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/DevNullLogger.java index f7e02496a4..5045b1b89c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/DevNullLogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/DevNullLogger.java @@ -20,58 +20,39 @@ import org.neo4j.driver.Logger; -public class DevNullLogger implements Logger -{ +public class DevNullLogger implements Logger { public static final Logger DEV_NULL_LOGGER = new DevNullLogger(); - private DevNullLogger() - { - } + private DevNullLogger() {} @Override - public void error( String message, Throwable cause ) - { - } + public void error(String message, Throwable cause) {} @Override - public void info( String message, Object... params ) - { - } + public void info(String message, Object... params) {} @Override - public void warn( String message, Object... params ) - { - } + public void warn(String message, Object... params) {} @Override - public void warn( String message, Throwable cause ) - { - } + public void warn(String message, Throwable cause) {} @Override - public void debug( String message, Object... params ) - { - } + public void debug(String message, Object... params) {} @Override - public void debug( String message, Throwable throwable ) - { - } + public void debug(String message, Throwable throwable) {} @Override - public void trace( String message, Object... params ) - { - } + public void trace(String message, Object... params) {} @Override - public boolean isTraceEnabled() - { + public boolean isTraceEnabled() { return false; } @Override - public boolean isDebugEnabled() - { + public boolean isDebugEnabled() { return false; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/DevNullLogging.java b/driver/src/main/java/org/neo4j/driver/internal/logging/DevNullLogging.java index 02158709a6..b66e8d65b2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/DevNullLogging.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/DevNullLogging.java @@ -19,23 +19,18 @@ package org.neo4j.driver.internal.logging; import java.io.Serializable; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; -public class DevNullLogging implements Logging, Serializable -{ +public class DevNullLogging implements Logging, Serializable { private static final long serialVersionUID = -2632752338512373821L; public static final Logging DEV_NULL_LOGGING = new DevNullLogging(); - private DevNullLogging() - { - } + private DevNullLogging() {} @Override - public Logger getLog( String name ) - { + public Logger getLog(String name) { return DevNullLogger.DEV_NULL_LOGGER; } @@ -43,9 +38,9 @@ public Logger getLog( String name ) // It is involved during deserialization after readObject on the new object. // The returned value replaces the object read. // An enum would be preferable, but would not be API compatible. - // Reference: https://docs.oracle.com/en/java/javase/17/docs/specs/serialization/input.html#the-readresolve-method andJoshua Bloch, Effective Java 3rd edition - private Object readResolve() - { + // Reference: https://docs.oracle.com/en/java/javase/17/docs/specs/serialization/input.html#the-readresolve-method + // andJoshua Bloch, Effective Java 3rd edition + private Object readResolve() { return DEV_NULL_LOGGING; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/JULogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/JULogger.java index 502664c066..f514647423 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/JULogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/JULogger.java @@ -19,83 +19,68 @@ package org.neo4j.driver.internal.logging; import java.util.logging.Level; - import org.neo4j.driver.Logger; -public class JULogger implements Logger -{ +public class JULogger implements Logger { private final java.util.logging.Logger delegate; private final boolean debugEnabled; private final boolean traceEnabled; - public JULogger( String name, Level loggingLevel ) - { - delegate = java.util.logging.Logger.getLogger( name ); - delegate.setLevel( loggingLevel ); - debugEnabled = delegate.isLoggable( Level.FINE ); - traceEnabled = delegate.isLoggable( Level.FINEST ); + public JULogger(String name, Level loggingLevel) { + delegate = java.util.logging.Logger.getLogger(name); + delegate.setLevel(loggingLevel); + debugEnabled = delegate.isLoggable(Level.FINE); + traceEnabled = delegate.isLoggable(Level.FINEST); } @Override - public void error( String message, Throwable cause ) - { - delegate.log( Level.SEVERE, message, cause ); + public void error(String message, Throwable cause) { + delegate.log(Level.SEVERE, message, cause); } @Override - public void info( String format, Object... params ) - { - delegate.log( Level.INFO, String.format( format, params ) ); + public void info(String format, Object... params) { + delegate.log(Level.INFO, String.format(format, params)); } @Override - public void warn( String format, Object... params ) - { - delegate.log( Level.WARNING, String.format( format, params ) ); + public void warn(String format, Object... params) { + delegate.log(Level.WARNING, String.format(format, params)); } @Override - public void warn( String message, Throwable cause ) - { - delegate.log( Level.WARNING, message, cause ); + public void warn(String message, Throwable cause) { + delegate.log(Level.WARNING, message, cause); } @Override - public void debug( String format, Object... params ) - { - if ( debugEnabled ) - { - delegate.log( Level.FINE, String.format( format, params ) ); + public void debug(String format, Object... params) { + if (debugEnabled) { + delegate.log(Level.FINE, String.format(format, params)); } } @Override - public void debug( String message, Throwable throwable ) - { - if ( debugEnabled ) - { - delegate.log( Level.FINE, message, throwable ); + public void debug(String message, Throwable throwable) { + if (debugEnabled) { + delegate.log(Level.FINE, message, throwable); } } @Override - public void trace( String format, Object... params ) - { - if ( traceEnabled ) - { - delegate.log( Level.FINEST, String.format( format, params ) ); + public void trace(String format, Object... params) { + if (traceEnabled) { + delegate.log(Level.FINEST, String.format(format, params)); } } @Override - public boolean isTraceEnabled() - { + public boolean isTraceEnabled() { return traceEnabled; } @Override - public boolean isDebugEnabled() - { + public boolean isDebugEnabled() { return debugEnabled; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/JULogging.java b/driver/src/main/java/org/neo4j/driver/internal/logging/JULogging.java index 9dffed957e..58ee48908f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/JULogging.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/JULogging.java @@ -20,7 +20,6 @@ import java.io.Serializable; import java.util.logging.Level; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; @@ -30,20 +29,17 @@ * * @see Logging#javaUtilLogging(Level) */ -public class JULogging implements Logging, Serializable -{ +public class JULogging implements Logging, Serializable { private static final long serialVersionUID = -1145576859241657833L; private final Level loggingLevel; - public JULogging( Level loggingLevel ) - { + public JULogging(Level loggingLevel) { this.loggingLevel = loggingLevel; } @Override - public Logger getLog( String name ) - { - return new JULogger( name, loggingLevel ); + public Logger getLog(String name) { + return new JULogger(name, loggingLevel); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/NettyLogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/NettyLogger.java index 593cc5ecf7..1f072cdc28 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/NettyLogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/NettyLogger.java @@ -18,220 +18,183 @@ */ package org.neo4j.driver.internal.logging; -import io.netty.util.internal.logging.AbstractInternalLogger; +import static java.lang.String.format; +import io.netty.util.internal.logging.AbstractInternalLogger; import java.util.regex.Pattern; - import org.neo4j.driver.Logger; -import static java.lang.String.format; - -public class NettyLogger extends AbstractInternalLogger -{ +public class NettyLogger extends AbstractInternalLogger { private Logger log; private static final Pattern PLACE_HOLDER_PATTERN = Pattern.compile("\\{\\}"); - public NettyLogger( String name, Logger log ) - { - super( name ); + public NettyLogger(String name, Logger log) { + super(name); this.log = log; } @Override - public boolean isTraceEnabled() - { + public boolean isTraceEnabled() { return log.isTraceEnabled(); } @Override - public void trace( String msg ) - { - log.trace( msg ); + public void trace(String msg) { + log.trace(msg); } @Override - public void trace( String format, Object arg ) - { - log.trace( toDriverLoggerFormat( format ), arg ); + public void trace(String format, Object arg) { + log.trace(toDriverLoggerFormat(format), arg); } @Override - public void trace( String format, Object argA, Object argB ) - { - log.trace( toDriverLoggerFormat( format ), argA, argB ); + public void trace(String format, Object argA, Object argB) { + log.trace(toDriverLoggerFormat(format), argA, argB); } @Override - public void trace( String format, Object... arguments ) - { - log.trace( toDriverLoggerFormat( format ), arguments ); + public void trace(String format, Object... arguments) { + log.trace(toDriverLoggerFormat(format), arguments); } @Override - public void trace( String msg, Throwable t ) - { - log.trace( "%s%n%s", msg, t ); + public void trace(String msg, Throwable t) { + log.trace("%s%n%s", msg, t); } @Override - public boolean isDebugEnabled() - { + public boolean isDebugEnabled() { return log.isDebugEnabled(); } @Override - public void debug( String msg ) - { - log.debug( msg ); + public void debug(String msg) { + log.debug(msg); } @Override - public void debug( String format, Object arg ) - { - log.debug( toDriverLoggerFormat( format ), arg ); + public void debug(String format, Object arg) { + log.debug(toDriverLoggerFormat(format), arg); } @Override - public void debug( String format, Object argA, Object argB ) - { - log.debug( toDriverLoggerFormat( format ), argA, argB ); + public void debug(String format, Object argA, Object argB) { + log.debug(toDriverLoggerFormat(format), argA, argB); } @Override - public void debug( String format, Object... arguments ) - { - log.debug( toDriverLoggerFormat( format ), arguments ); + public void debug(String format, Object... arguments) { + log.debug(toDriverLoggerFormat(format), arguments); } @Override - public void debug( String msg, Throwable t ) - { - log.debug( "%s%n%s", msg, t ); + public void debug(String msg, Throwable t) { + log.debug("%s%n%s", msg, t); } @Override - public boolean isInfoEnabled() - { + public boolean isInfoEnabled() { return true; } @Override - public void info( String msg ) - { - log.info( msg ); + public void info(String msg) { + log.info(msg); } @Override - public void info( String format, Object arg ) - { - log.info( toDriverLoggerFormat( format ), arg ); + public void info(String format, Object arg) { + log.info(toDriverLoggerFormat(format), arg); } @Override - public void info( String format, Object argA, Object argB ) - { - log.info( toDriverLoggerFormat( format ), argA, argB ); + public void info(String format, Object argA, Object argB) { + log.info(toDriverLoggerFormat(format), argA, argB); } @Override - public void info( String format, Object... arguments ) - { - log.info( toDriverLoggerFormat( format ), arguments ); + public void info(String format, Object... arguments) { + log.info(toDriverLoggerFormat(format), arguments); } @Override - public void info( String msg, Throwable t ) - { - log.info( "%s%n%s", msg, t ); + public void info(String msg, Throwable t) { + log.info("%s%n%s", msg, t); } @Override - public boolean isWarnEnabled() - { + public boolean isWarnEnabled() { return true; } @Override - public void warn( String msg ) - { - log.warn( msg ); + public void warn(String msg) { + log.warn(msg); } @Override - public void warn( String format, Object arg ) - { - log.warn( toDriverLoggerFormat( format ), arg ); + public void warn(String format, Object arg) { + log.warn(toDriverLoggerFormat(format), arg); } @Override - public void warn( String format, Object... arguments ) - { - log.warn( toDriverLoggerFormat( format ), arguments ); + public void warn(String format, Object... arguments) { + log.warn(toDriverLoggerFormat(format), arguments); } @Override - public void warn( String format, Object argA, Object argB ) - { - log.warn( toDriverLoggerFormat( format ), argA, argB ); + public void warn(String format, Object argA, Object argB) { + log.warn(toDriverLoggerFormat(format), argA, argB); } @Override - public void warn( String msg, Throwable t ) - { - log.warn( "%s%n%s", msg, t ); + public void warn(String msg, Throwable t) { + log.warn("%s%n%s", msg, t); } @Override - public boolean isErrorEnabled() - { + public boolean isErrorEnabled() { return true; } @Override - public void error( String msg ) - { - log.error( msg, null ); + public void error(String msg) { + log.error(msg, null); } @Override - public void error( String format, Object arg ) - { - error( format, new Object[]{arg} ); + public void error(String format, Object arg) { + error(format, new Object[] {arg}); } @Override - public void error( String format, Object argA, Object argB ) - { - error( format, new Object[]{argA, argB} ); + public void error(String format, Object argA, Object argB) { + error(format, new Object[] {argA, argB}); } @Override - public void error( String format, Object... arguments ) - { - format = toDriverLoggerFormat( format ); - if ( arguments.length == 0 ) - { - log.error( format, null ); + public void error(String format, Object... arguments) { + format = toDriverLoggerFormat(format); + if (arguments.length == 0) { + log.error(format, null); return; } Object arg = arguments[arguments.length - 1]; - if ( arg instanceof Throwable ) - { + if (arg instanceof Throwable) { // still give all arguments to string format, // for the worst case, the redundant parameter will be ignored. - log.error( format( format, arguments ), (Throwable) arg ); + log.error(format(format, arguments), (Throwable) arg); } } @Override - public void error( String msg, Throwable t ) - { - log.error( msg, t ); + public void error(String msg, Throwable t) { + log.error(msg, t); } - private String toDriverLoggerFormat( String format ) - { - return PLACE_HOLDER_PATTERN.matcher( format ).replaceAll( "%s" ); + private String toDriverLoggerFormat(String format) { + return PLACE_HOLDER_PATTERN.matcher(format).replaceAll("%s"); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/NettyLogging.java b/driver/src/main/java/org/neo4j/driver/internal/logging/NettyLogging.java index 31ac9e140c..1894bcfc8f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/NettyLogging.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/NettyLogging.java @@ -20,24 +20,20 @@ import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; - import org.neo4j.driver.Logging; /** * This is the logging factory to delegate netty's logging to our logging system */ -public class NettyLogging extends InternalLoggerFactory -{ +public class NettyLogging extends InternalLoggerFactory { private Logging logging; - public NettyLogging( Logging logging ) - { + public NettyLogging(Logging logging) { this.logging = logging; } @Override - protected InternalLogger newInstance( String name ) - { - return new NettyLogger( name, logging.getLog( name ) ); + protected InternalLogger newInstance(String name) { + return new NettyLogger(name, logging.getLog(name)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/PrefixedLogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/PrefixedLogger.java index b028568b77..6280fa97fa 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/PrefixedLogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/PrefixedLogger.java @@ -20,28 +20,23 @@ import org.neo4j.driver.Logger; -public class PrefixedLogger extends ReformattedLogger -{ +public class PrefixedLogger extends ReformattedLogger { private final String messagePrefix; - public PrefixedLogger( Logger delegate ) - { - this( null, delegate ); + public PrefixedLogger(Logger delegate) { + this(null, delegate); } - public PrefixedLogger( String messagePrefix, Logger delegate ) - { + public PrefixedLogger(String messagePrefix, Logger delegate) { super(delegate); this.messagePrefix = messagePrefix; } @Override - protected String reformat( String message ) - { - if ( messagePrefix == null ) - { + protected String reformat(String message) { + if (messagePrefix == null) { return message; } - return String.format( "%s %s", messagePrefix, message ); + return String.format("%s %s", messagePrefix, message); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/ReformattedLogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/ReformattedLogger.java index b0d9a503e6..2d5020e1b1 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/ReformattedLogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/ReformattedLogger.java @@ -18,81 +18,67 @@ */ package org.neo4j.driver.internal.logging; -import org.neo4j.driver.Logger; - import static java.util.Objects.requireNonNull; -public abstract class ReformattedLogger implements Logger -{ +import org.neo4j.driver.Logger; + +public abstract class ReformattedLogger implements Logger { private final Logger delegate; - protected ReformattedLogger(Logger delegate) - { - this.delegate = requireNonNull( delegate ); + protected ReformattedLogger(Logger delegate) { + this.delegate = requireNonNull(delegate); } @Override - public void error( String message, Throwable cause ) - { - delegate.error( reformat( message ), cause ); + public void error(String message, Throwable cause) { + delegate.error(reformat(message), cause); } @Override - public void info( String message, Object... params ) - { - delegate.info( reformat( message ), params ); + public void info(String message, Object... params) { + delegate.info(reformat(message), params); } @Override - public void warn( String message, Object... params ) - { - delegate.warn( reformat( message ), params ); + public void warn(String message, Object... params) { + delegate.warn(reformat(message), params); } @Override - public void warn( String message, Throwable cause ) - { - delegate.warn( reformat( message ), cause ); + public void warn(String message, Throwable cause) { + delegate.warn(reformat(message), cause); } @Override - public void debug( String message, Object... params ) - { - if ( isDebugEnabled() ) - { - delegate.debug( reformat( message ), params ); + public void debug(String message, Object... params) { + if (isDebugEnabled()) { + delegate.debug(reformat(message), params); } } @Override - public void debug( String message, Throwable throwable ) - { - if ( isDebugEnabled() ) - { - delegate.debug( reformat( message ), throwable ); + public void debug(String message, Throwable throwable) { + if (isDebugEnabled()) { + delegate.debug(reformat(message), throwable); } } @Override - public void trace( String message, Object... params ) - { - if ( isTraceEnabled() ) - { - delegate.trace( reformat( message ), params ); + public void trace(String message, Object... params) { + if (isTraceEnabled()) { + delegate.trace(reformat(message), params); } } @Override - public boolean isTraceEnabled() - { + public boolean isTraceEnabled() { return delegate.isTraceEnabled(); } @Override - public boolean isDebugEnabled() - { + public boolean isDebugEnabled() { return delegate.isDebugEnabled(); } - protected abstract String reformat( String message ); + protected abstract String reformat(String message); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/Slf4jLogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/Slf4jLogger.java index 1b109dbc13..672155830f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/Slf4jLogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/Slf4jLogger.java @@ -19,90 +19,71 @@ package org.neo4j.driver.internal.logging; import java.util.Objects; - import org.neo4j.driver.Logger; -class Slf4jLogger implements Logger -{ +class Slf4jLogger implements Logger { private final org.slf4j.Logger delegate; - Slf4jLogger( org.slf4j.Logger delegate ) - { - this.delegate = Objects.requireNonNull( delegate ); + Slf4jLogger(org.slf4j.Logger delegate) { + this.delegate = Objects.requireNonNull(delegate); } @Override - public void error( String message, Throwable cause ) - { - if ( delegate.isErrorEnabled() ) - { - delegate.error( message, cause ); + public void error(String message, Throwable cause) { + if (delegate.isErrorEnabled()) { + delegate.error(message, cause); } } @Override - public void info( String message, Object... params ) - { - if ( delegate.isInfoEnabled() ) - { - delegate.info( formatMessage( message, params ) ); + public void info(String message, Object... params) { + if (delegate.isInfoEnabled()) { + delegate.info(formatMessage(message, params)); } } @Override - public void warn( String message, Object... params ) - { - if ( delegate.isWarnEnabled() ) - { - delegate.warn( formatMessage( message, params ) ); + public void warn(String message, Object... params) { + if (delegate.isWarnEnabled()) { + delegate.warn(formatMessage(message, params)); } } @Override - public void warn( String message, Throwable cause ) - { - if ( delegate.isWarnEnabled() ) - { - delegate.warn( message, cause ); + public void warn(String message, Throwable cause) { + if (delegate.isWarnEnabled()) { + delegate.warn(message, cause); } } @Override - public void debug( String message, Object... params ) - { - if ( isDebugEnabled() ) - { - delegate.debug( formatMessage( message, params ) ); + public void debug(String message, Object... params) { + if (isDebugEnabled()) { + delegate.debug(formatMessage(message, params)); } } @Override - public void debug( String message, Throwable throwable ) - { - if ( isDebugEnabled() ) - { - delegate.debug( message, throwable ); + public void debug(String message, Throwable throwable) { + if (isDebugEnabled()) { + delegate.debug(message, throwable); } } @Override - public void trace( String message, Object... params ) - { - if ( isTraceEnabled() ) - { - delegate.trace( formatMessage( message, params ) ); + public void trace(String message, Object... params) { + if (isTraceEnabled()) { + delegate.trace(formatMessage(message, params)); } } @Override - public boolean isTraceEnabled() - { + public boolean isTraceEnabled() { return delegate.isTraceEnabled(); } @Override - public boolean isDebugEnabled() - { + public boolean isDebugEnabled() { return delegate.isDebugEnabled(); } @@ -114,8 +95,7 @@ public boolean isDebugEnabled() * @param params the parameters. * @return fully formatted message string. */ - private static String formatMessage( String messageTemplate, Object... params ) - { - return String.format( messageTemplate, params ); + private static String formatMessage(String messageTemplate, Object... params) { + return String.format(messageTemplate, params); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/Slf4jLogging.java b/driver/src/main/java/org/neo4j/driver/internal/logging/Slf4jLogging.java index a5c92d5735..b030e2d686 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/Slf4jLogging.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/Slf4jLogging.java @@ -18,12 +18,10 @@ */ package org.neo4j.driver.internal.logging; -import org.slf4j.LoggerFactory; - import java.io.Serializable; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; +import org.slf4j.LoggerFactory; /** * Internal implementation of the SLF4J logging. @@ -31,28 +29,22 @@ * * @see Logging#slf4j() */ -public class Slf4jLogging implements Logging, Serializable -{ +public class Slf4jLogging implements Logging, Serializable { private static final long serialVersionUID = 4120390028025944991L; @Override - public Logger getLog( String name ) - { - return new Slf4jLogger( LoggerFactory.getLogger( name ) ); + public Logger getLog(String name) { + return new Slf4jLogger(LoggerFactory.getLogger(name)); } - public static RuntimeException checkAvailability() - { - try - { - Class.forName( "org.slf4j.LoggerFactory" ); + public static RuntimeException checkAvailability() { + try { + Class.forName("org.slf4j.LoggerFactory"); return null; - } - catch ( Throwable error ) - { + } catch (Throwable error) { return new IllegalStateException( "SLF4J logging is not available. Please add dependencies on slf4j-api and SLF4J binding (Logback, Log4j, etc.)", - error ); + error); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/AbstractMessageWriter.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/AbstractMessageWriter.java index 7607c13978..3737cfffad 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/AbstractMessageWriter.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/AbstractMessageWriter.java @@ -18,31 +18,27 @@ */ package org.neo4j.driver.internal.messaging; +import static java.util.Objects.requireNonNull; + import java.io.IOException; import java.util.Map; -import static java.util.Objects.requireNonNull; - -public abstract class AbstractMessageWriter implements MessageFormat.Writer -{ +public abstract class AbstractMessageWriter implements MessageFormat.Writer { private final ValuePacker packer; - private final Map encodersByMessageSignature; + private final Map encodersByMessageSignature; - protected AbstractMessageWriter( ValuePacker packer, Map encodersByMessageSignature ) - { - this.packer = requireNonNull( packer ); - this.encodersByMessageSignature = requireNonNull( encodersByMessageSignature ); + protected AbstractMessageWriter(ValuePacker packer, Map encodersByMessageSignature) { + this.packer = requireNonNull(packer); + this.encodersByMessageSignature = requireNonNull(encodersByMessageSignature); } @Override - public final void write( Message msg ) throws IOException - { + public final void write(Message msg) throws IOException { byte signature = msg.signature(); - MessageEncoder encoder = encodersByMessageSignature.get( signature ); - if ( encoder == null ) - { - throw new IOException( "No encoder found for message " + msg + " with signature " + signature ); + MessageEncoder encoder = encodersByMessageSignature.get(signature); + if (encoder == null) { + throw new IOException("No encoder found for message " + msg + " with signature " + signature); } - encoder.encode( msg, packer ); + encoder.encode(msg, packer); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java index dee84f2a23..c95732a5e4 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java @@ -18,11 +18,11 @@ */ package org.neo4j.driver.internal.messaging; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.protocolVersion; + import io.netty.channel.Channel; import io.netty.channel.ChannelPromise; - import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -43,10 +43,7 @@ import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44; import org.neo4j.driver.internal.spi.Connection; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.protocolVersion; - -public interface BoltProtocol -{ +public interface BoltProtocol { /** * Instantiate {@link MessageFormat} used by this Bolt protocol verison. * @@ -62,13 +59,17 @@ public interface BoltProtocol * @param routingContext the configured routing context * @param channelInitializedPromise the promise to be notified when initialization is completed. */ - void initializeChannel( String userAgent, AuthToken authToken, RoutingContext routingContext, ChannelPromise channelInitializedPromise ); + void initializeChannel( + String userAgent, + AuthToken authToken, + RoutingContext routingContext, + ChannelPromise channelInitializedPromise); /** * Prepare to close channel before it is closed. * @param channel the channel to close. */ - void prepareToCloseChannel( Channel channel ); + void prepareToCloseChannel(Channel channel); /** * Begin an unmanaged transaction. @@ -78,7 +79,7 @@ public interface BoltProtocol * @param config the transaction configuration. Never null, should be {@link TransactionConfig#empty()} when absent. * @return a completion stage completed when transaction is started or completed exceptionally when there was a failure. */ - CompletionStage beginTransaction( Connection connection, Bookmark bookmark, TransactionConfig config ); + CompletionStage beginTransaction(Connection connection, Bookmark bookmark, TransactionConfig config); /** * Commit the unmanaged transaction. @@ -86,7 +87,7 @@ public interface BoltProtocol * @param connection the connection to use. * @return a completion stage completed with a bookmark when transaction is committed or completed exceptionally when there was a failure. */ - CompletionStage commitTransaction( Connection connection ); + CompletionStage commitTransaction(Connection connection); /** * Rollback the unmanaged transaction. @@ -94,7 +95,7 @@ public interface BoltProtocol * @param connection the connection to use. * @return a completion stage completed when transaction is rolled back or completed exceptionally when there was a failure. */ - CompletionStage rollbackTransaction( Connection connection ); + CompletionStage rollbackTransaction(Connection connection); /** * Execute the given query in an auto-commit transaction, i.e. {@link Session#run(Query)}. @@ -106,8 +107,12 @@ public interface BoltProtocol * @param fetchSize the record fetch size for PULL message. * @return stage with cursor. */ - ResultCursorFactory runInAutoCommitTransaction( Connection connection, Query query, BookmarkHolder bookmarkHolder, TransactionConfig config, - long fetchSize ); + ResultCursorFactory runInAutoCommitTransaction( + Connection connection, + Query query, + BookmarkHolder bookmarkHolder, + TransactionConfig config, + long fetchSize); /** * Execute the given query in a running unmanaged transaction, i.e. {@link Transaction#run(Query)}. @@ -118,7 +123,8 @@ ResultCursorFactory runInAutoCommitTransaction( Connection connection, Query que * @param fetchSize the record fetch size for PULL message. * @return stage with cursor. */ - ResultCursorFactory runInUnmanagedTransaction( Connection connection, Query query, UnmanagedTransaction tx, long fetchSize ); + ResultCursorFactory runInUnmanagedTransaction( + Connection connection, Query query, UnmanagedTransaction tx, long fetchSize); /** * Returns the protocol version. It can be used for version specific error messages. @@ -133,9 +139,8 @@ ResultCursorFactory runInAutoCommitTransaction( Connection connection, Query que * @return the protocol. * @throws ClientException when unable to find protocol version for the given channel. */ - static BoltProtocol forChannel( Channel channel ) - { - return forVersion( protocolVersion( channel ) ); + static BoltProtocol forChannel(Channel channel) { + return forVersion(protocolVersion(channel)); } /** @@ -145,32 +150,20 @@ static BoltProtocol forChannel( Channel channel ) * @return the protocol. * @throws ClientException when unable to find protocol with the given version. */ - static BoltProtocol forVersion( BoltProtocolVersion version ) - { - if ( BoltProtocolV3.VERSION.equals( version ) ) - { + static BoltProtocol forVersion(BoltProtocolVersion version) { + if (BoltProtocolV3.VERSION.equals(version)) { return BoltProtocolV3.INSTANCE; - } - else if ( BoltProtocolV4.VERSION.equals( version ) ) - { + } else if (BoltProtocolV4.VERSION.equals(version)) { return BoltProtocolV4.INSTANCE; - } - else if ( BoltProtocolV41.VERSION.equals( version ) ) - { + } else if (BoltProtocolV41.VERSION.equals(version)) { return BoltProtocolV41.INSTANCE; - } - else if ( BoltProtocolV42.VERSION.equals( version ) ) - { + } else if (BoltProtocolV42.VERSION.equals(version)) { return BoltProtocolV42.INSTANCE; - } - else if ( BoltProtocolV43.VERSION.equals( version ) ) - { + } else if (BoltProtocolV43.VERSION.equals(version)) { return BoltProtocolV43.INSTANCE; - } - else if ( BoltProtocolV44.VERSION.equals( version ) ) - { + } else if (BoltProtocolV44.VERSION.equals(version)) { return BoltProtocolV44.INSTANCE; } - throw new ClientException( "Unknown protocol version: " + version ); + throw new ClientException("Unknown protocol version: " + version); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocolVersion.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocolVersion.java index ec1c4f8245..791001f3c4 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocolVersion.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocolVersion.java @@ -20,50 +20,40 @@ import java.util.Objects; -public class BoltProtocolVersion implements Comparable -{ +public class BoltProtocolVersion implements Comparable { private final int majorVersion; private final int minorVersion; - public BoltProtocolVersion( int majorVersion, int minorVersion ) - { + public BoltProtocolVersion(int majorVersion, int minorVersion) { this.majorVersion = majorVersion; this.minorVersion = minorVersion; } - public static BoltProtocolVersion fromRawBytes( int rawVersion ) - { + public static BoltProtocolVersion fromRawBytes(int rawVersion) { int major = rawVersion & 0x000000FF; int minor = (rawVersion >> 8) & 0x000000FF; - return new BoltProtocolVersion( major, minor ); + return new BoltProtocolVersion(major, minor); } - public long getMinorVersion() - { + public long getMinorVersion() { return minorVersion; } - public long getMajorVersion() - { + public long getMajorVersion() { return majorVersion; } - public int toInt() - { + public int toInt() { int shiftedMinor = minorVersion << 8; return shiftedMinor | majorVersion; } - public int toIntRange( BoltProtocolVersion minVersion ) - { - if ( majorVersion != minVersion.majorVersion ) - { - throw new IllegalArgumentException( "Versions should be from the same major version" ); - } - else if ( minorVersion < minVersion.minorVersion ) - { - throw new IllegalArgumentException( "Max version should be newer than min version" ); + public int toIntRange(BoltProtocolVersion minVersion) { + if (majorVersion != minVersion.majorVersion) { + throw new IllegalArgumentException("Versions should be from the same major version"); + } else if (minorVersion < minVersion.minorVersion) { + throw new IllegalArgumentException("Max version should be newer than min version"); } int range = minorVersion - minVersion.minorVersion; int shiftedRange = range << 16; @@ -74,50 +64,40 @@ else if ( minorVersion < minVersion.minorVersion ) * @return the version in format X.Y where X is the major version and Y is the minor version */ @Override - public String toString() - { - return String.format( "%d.%d", majorVersion, minorVersion ); + public String toString() { + return String.format("%d.%d", majorVersion, minorVersion); } @Override - public int hashCode() - { - return Objects.hash( minorVersion, majorVersion ); + public int hashCode() { + return Objects.hash(minorVersion, majorVersion); } @Override - public boolean equals( Object o ) - { - if ( o == this ) - { + public boolean equals(Object o) { + if (o == this) { return true; - } - else if ( !(o instanceof BoltProtocolVersion) ) - { + } else if (!(o instanceof BoltProtocolVersion)) { return false; - } - else - { + } else { BoltProtocolVersion other = (BoltProtocolVersion) o; - return this.getMajorVersion() == other.getMajorVersion() && this.getMinorVersion() == other.getMinorVersion(); + return this.getMajorVersion() == other.getMajorVersion() + && this.getMinorVersion() == other.getMinorVersion(); } } @Override - public int compareTo( BoltProtocolVersion other ) - { - int result = Integer.compare( majorVersion, other.majorVersion ); + public int compareTo(BoltProtocolVersion other) { + int result = Integer.compare(majorVersion, other.majorVersion); - if ( result == 0 ) - { - return Integer.compare( minorVersion, other.minorVersion ); + if (result == 0) { + return Integer.compare(minorVersion, other.minorVersion); } return result; } - public static boolean isHttp( BoltProtocolVersion protocolVersion ) - { + public static boolean isHttp(BoltProtocolVersion protocolVersion) { // server would respond with `HTTP..` We read 4 bytes to figure out the version. The first two are not used // and therefore parse the `P` (80) for major and `T` (84) for minor. return protocolVersion.getMajorVersion() == 80 && protocolVersion.getMinorVersion() == 84; diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/Message.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/Message.java index 05328adba0..1f7e4b9225 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/Message.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/Message.java @@ -21,7 +21,6 @@ /** * Base class for all protocol messages. */ -public interface Message -{ +public interface Message { byte signature(); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/MessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/MessageEncoder.java index 0149b47f0f..94d1380ac3 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/MessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/MessageEncoder.java @@ -20,7 +20,6 @@ import java.io.IOException; -public interface MessageEncoder -{ - void encode( Message message, ValuePacker packer ) throws IOException; +public interface MessageEncoder { + void encode(Message message, ValuePacker packer) throws IOException; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/MessageFormat.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/MessageFormat.java index 08cd6ef71f..8f04336256 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/MessageFormat.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/MessageFormat.java @@ -19,23 +19,19 @@ package org.neo4j.driver.internal.messaging; import java.io.IOException; - import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -public interface MessageFormat -{ - interface Writer - { - void write( Message msg ) throws IOException; +public interface MessageFormat { + interface Writer { + void write(Message msg) throws IOException; } - interface Reader - { - void read( ResponseMessageHandler handler ) throws IOException; + interface Reader { + void read(ResponseMessageHandler handler) throws IOException; } - Writer newWriter( PackOutput output ); + Writer newWriter(PackOutput output); - Reader newReader( PackInput input ); + Reader newReader(PackInput input); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/ResponseMessageHandler.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/ResponseMessageHandler.java index 2ba14394a8..ac6796b6b9 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/ResponseMessageHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/ResponseMessageHandler.java @@ -20,16 +20,14 @@ import java.io.IOException; import java.util.Map; - import org.neo4j.driver.Value; -public interface ResponseMessageHandler -{ - void handleSuccessMessage( Map meta ) throws IOException; +public interface ResponseMessageHandler { + void handleSuccessMessage(Map meta) throws IOException; - void handleRecordMessage( Value[] fields ) throws IOException; + void handleRecordMessage(Value[] fields) throws IOException; - void handleFailureMessage( String code, String message ) throws IOException; + void handleFailureMessage(String code, String message) throws IOException; void handleIgnoredMessage() throws IOException; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/ValuePacker.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/ValuePacker.java index fea7b089d2..1f5356e484 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/ValuePacker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/ValuePacker.java @@ -20,16 +20,14 @@ import java.io.IOException; import java.util.Map; - import org.neo4j.driver.Value; -public interface ValuePacker -{ - void packStructHeader( int size, byte signature ) throws IOException; +public interface ValuePacker { + void packStructHeader(int size, byte signature) throws IOException; - void pack( String string ) throws IOException; + void pack(String string) throws IOException; - void pack( Value value ) throws IOException; + void pack(Value value) throws IOException; - void pack( Map map ) throws IOException; + void pack(Map map) throws IOException; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/ValueUnpacker.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/ValueUnpacker.java index c66adbcf9b..cb33aab78d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/ValueUnpacker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/ValueUnpacker.java @@ -20,16 +20,14 @@ import java.io.IOException; import java.util.Map; - import org.neo4j.driver.Value; -public interface ValueUnpacker -{ +public interface ValueUnpacker { long unpackStructHeader() throws IOException; int unpackStructSignature() throws IOException; - Map unpackMap() throws IOException; + Map unpackMap() throws IOException; Value[] unpackArray() throws IOException; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonMessageReader.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonMessageReader.java index faca3cb4aa..c442c2687b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonMessageReader.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonMessageReader.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.util.Map; - import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.ResponseMessageHandler; @@ -31,66 +30,57 @@ import org.neo4j.driver.internal.messaging.response.SuccessMessage; import org.neo4j.driver.internal.packstream.PackInput; -public class CommonMessageReader implements MessageFormat.Reader -{ +public class CommonMessageReader implements MessageFormat.Reader { private final ValueUnpacker unpacker; - public CommonMessageReader( PackInput input ) - { - this( new CommonValueUnpacker( input ) ); + public CommonMessageReader(PackInput input) { + this(new CommonValueUnpacker(input)); } - protected CommonMessageReader( ValueUnpacker unpacker ) - { + protected CommonMessageReader(ValueUnpacker unpacker) { this.unpacker = unpacker; } @Override - public void read( ResponseMessageHandler handler ) throws IOException - { + public void read(ResponseMessageHandler handler) throws IOException { unpacker.unpackStructHeader(); int type = unpacker.unpackStructSignature(); - switch ( type ) - { - case SuccessMessage.SIGNATURE: - unpackSuccessMessage( handler ); - break; - case FailureMessage.SIGNATURE: - unpackFailureMessage( handler ); - break; - case IgnoredMessage.SIGNATURE: - unpackIgnoredMessage( handler ); - break; - case RecordMessage.SIGNATURE: - unpackRecordMessage( handler ); - break; - default: - throw new IOException( "Unknown message type: " + type ); + switch (type) { + case SuccessMessage.SIGNATURE: + unpackSuccessMessage(handler); + break; + case FailureMessage.SIGNATURE: + unpackFailureMessage(handler); + break; + case IgnoredMessage.SIGNATURE: + unpackIgnoredMessage(handler); + break; + case RecordMessage.SIGNATURE: + unpackRecordMessage(handler); + break; + default: + throw new IOException("Unknown message type: " + type); } } - private void unpackSuccessMessage( ResponseMessageHandler output ) throws IOException - { - Map map = unpacker.unpackMap(); - output.handleSuccessMessage( map ); + private void unpackSuccessMessage(ResponseMessageHandler output) throws IOException { + Map map = unpacker.unpackMap(); + output.handleSuccessMessage(map); } - private void unpackFailureMessage( ResponseMessageHandler output ) throws IOException - { - Map params = unpacker.unpackMap(); - String code = params.get( "code" ).asString(); - String message = params.get( "message" ).asString(); - output.handleFailureMessage( code, message ); + private void unpackFailureMessage(ResponseMessageHandler output) throws IOException { + Map params = unpacker.unpackMap(); + String code = params.get("code").asString(); + String message = params.get("message").asString(); + output.handleFailureMessage(code, message); } - private void unpackIgnoredMessage( ResponseMessageHandler output ) throws IOException - { + private void unpackIgnoredMessage(ResponseMessageHandler output) throws IOException { output.handleIgnoredMessage(); } - private void unpackRecordMessage( ResponseMessageHandler output ) throws IOException - { + private void unpackRecordMessage(ResponseMessageHandler output) throws IOException { Value[] fields = unpacker.unpackArray(); - output.handleRecordMessage( fields ); + output.handleRecordMessage(fields); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValuePacker.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValuePacker.java index 28450ac7b1..4e14166ab9 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValuePacker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValuePacker.java @@ -18,6 +18,8 @@ */ package org.neo4j.driver.internal.messaging.common; +import static java.time.ZoneOffset.UTC; + import java.io.IOException; import java.time.LocalDate; import java.time.LocalDateTime; @@ -27,7 +29,6 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Map; - import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalPoint2D; import org.neo4j.driver.internal.InternalPoint3D; @@ -38,10 +39,7 @@ import org.neo4j.driver.types.IsoDuration; import org.neo4j.driver.types.Point; -import static java.time.ZoneOffset.UTC; - -public class CommonValuePacker implements ValuePacker -{ +public class CommonValuePacker implements ValuePacker { public static final byte DATE = 'D'; public static final int DATE_STRUCT_SIZE = 1; @@ -70,220 +68,190 @@ public class CommonValuePacker implements ValuePacker protected final PackStream.Packer packer; - public CommonValuePacker( PackOutput output ) - { - this.packer = new PackStream.Packer( output ); + public CommonValuePacker(PackOutput output) { + this.packer = new PackStream.Packer(output); } @Override - public final void packStructHeader( int size, byte signature ) throws IOException - { - packer.packStructHeader( size, signature ); + public final void packStructHeader(int size, byte signature) throws IOException { + packer.packStructHeader(size, signature); } @Override - public final void pack( String string ) throws IOException - { - packer.pack( string ); + public final void pack(String string) throws IOException { + packer.pack(string); } @Override - public final void pack( Value value ) throws IOException - { - if ( value instanceof InternalValue ) - { - packInternalValue( ((InternalValue) value) ); - } - else - { - throw new IllegalArgumentException( "Unable to pack: " + value ); + public final void pack(Value value) throws IOException { + if (value instanceof InternalValue) { + packInternalValue(((InternalValue) value)); + } else { + throw new IllegalArgumentException("Unable to pack: " + value); } } @Override - public final void pack( Map map ) throws IOException - { - if ( map == null || map.size() == 0 ) - { - packer.packMapHeader( 0 ); + public final void pack(Map map) throws IOException { + if (map == null || map.size() == 0) { + packer.packMapHeader(0); return; } - packer.packMapHeader( map.size() ); - for ( Map.Entry entry : map.entrySet() ) - { - packer.pack( entry.getKey() ); - pack( entry.getValue() ); + packer.packMapHeader(map.size()); + for (Map.Entry entry : map.entrySet()) { + packer.pack(entry.getKey()); + pack(entry.getValue()); } } - protected void packInternalValue( InternalValue value ) throws IOException - { - switch ( value.typeConstructor() ) - { - case DATE: - packDate( value.asLocalDate() ); - break; - case TIME: - packTime( value.asOffsetTime() ); - break; - case LOCAL_TIME: - packLocalTime( value.asLocalTime() ); - break; - case LOCAL_DATE_TIME: - packLocalDateTime( value.asLocalDateTime() ); - break; - case DATE_TIME: - packZonedDateTime( value.asZonedDateTime() ); - break; - case DURATION: - packDuration( value.asIsoDuration() ); - break; - case POINT: - packPoint( value.asPoint() ); - break; - case NULL: - packer.packNull(); - break; - - case BYTES: - packer.pack( value.asByteArray() ); - break; - - case STRING: - packer.pack( value.asString() ); - break; - - case BOOLEAN: - packer.pack( value.asBoolean() ); - break; - - case INTEGER: - packer.pack( value.asLong() ); - break; - - case FLOAT: - packer.pack( value.asDouble() ); - break; - - case MAP: - packer.packMapHeader( value.size() ); - for ( String s : value.keys() ) - { - packer.pack( s ); - pack( value.get( s ) ); - } - break; - - case LIST: - packer.packListHeader( value.size() ); - for ( Value item : value.values() ) - { - pack( item ); - } - break; - - default: - throw new IOException( "Unknown type: " + value.type().name() ); + protected void packInternalValue(InternalValue value) throws IOException { + switch (value.typeConstructor()) { + case DATE: + packDate(value.asLocalDate()); + break; + case TIME: + packTime(value.asOffsetTime()); + break; + case LOCAL_TIME: + packLocalTime(value.asLocalTime()); + break; + case LOCAL_DATE_TIME: + packLocalDateTime(value.asLocalDateTime()); + break; + case DATE_TIME: + packZonedDateTime(value.asZonedDateTime()); + break; + case DURATION: + packDuration(value.asIsoDuration()); + break; + case POINT: + packPoint(value.asPoint()); + break; + case NULL: + packer.packNull(); + break; + + case BYTES: + packer.pack(value.asByteArray()); + break; + + case STRING: + packer.pack(value.asString()); + break; + + case BOOLEAN: + packer.pack(value.asBoolean()); + break; + + case INTEGER: + packer.pack(value.asLong()); + break; + + case FLOAT: + packer.pack(value.asDouble()); + break; + + case MAP: + packer.packMapHeader(value.size()); + for (String s : value.keys()) { + packer.pack(s); + pack(value.get(s)); + } + break; + + case LIST: + packer.packListHeader(value.size()); + for (Value item : value.values()) { + pack(item); + } + break; + + default: + throw new IOException("Unknown type: " + value.type().name()); } } - private void packDate( LocalDate localDate ) throws IOException - { - packer.packStructHeader( DATE_STRUCT_SIZE, DATE ); - packer.pack( localDate.toEpochDay() ); + private void packDate(LocalDate localDate) throws IOException { + packer.packStructHeader(DATE_STRUCT_SIZE, DATE); + packer.pack(localDate.toEpochDay()); } - private void packTime( OffsetTime offsetTime ) throws IOException - { + private void packTime(OffsetTime offsetTime) throws IOException { long nanoOfDayLocal = offsetTime.toLocalTime().toNanoOfDay(); int offsetSeconds = offsetTime.getOffset().getTotalSeconds(); - packer.packStructHeader( TIME_STRUCT_SIZE, TIME ); - packer.pack( nanoOfDayLocal ); - packer.pack( offsetSeconds ); + packer.packStructHeader(TIME_STRUCT_SIZE, TIME); + packer.pack(nanoOfDayLocal); + packer.pack(offsetSeconds); } - private void packLocalTime( LocalTime localTime ) throws IOException - { - packer.packStructHeader( LOCAL_TIME_STRUCT_SIZE, LOCAL_TIME ); - packer.pack( localTime.toNanoOfDay() ); + private void packLocalTime(LocalTime localTime) throws IOException { + packer.packStructHeader(LOCAL_TIME_STRUCT_SIZE, LOCAL_TIME); + packer.pack(localTime.toNanoOfDay()); } - private void packLocalDateTime( LocalDateTime localDateTime ) throws IOException - { - long epochSecondUtc = localDateTime.toEpochSecond( UTC ); + private void packLocalDateTime(LocalDateTime localDateTime) throws IOException { + long epochSecondUtc = localDateTime.toEpochSecond(UTC); int nano = localDateTime.getNano(); - packer.packStructHeader( LOCAL_DATE_TIME_STRUCT_SIZE, LOCAL_DATE_TIME ); - packer.pack( epochSecondUtc ); - packer.pack( nano ); + packer.packStructHeader(LOCAL_DATE_TIME_STRUCT_SIZE, LOCAL_DATE_TIME); + packer.pack(epochSecondUtc); + packer.pack(nano); } - private void packZonedDateTime( ZonedDateTime zonedDateTime ) throws IOException - { - long epochSecondLocal = zonedDateTime.toLocalDateTime().toEpochSecond( UTC ); + private void packZonedDateTime(ZonedDateTime zonedDateTime) throws IOException { + long epochSecondLocal = zonedDateTime.toLocalDateTime().toEpochSecond(UTC); int nano = zonedDateTime.getNano(); ZoneId zone = zonedDateTime.getZone(); - if ( zone instanceof ZoneOffset ) - { + if (zone instanceof ZoneOffset) { int offsetSeconds = ((ZoneOffset) zone).getTotalSeconds(); - packer.packStructHeader( DATE_TIME_STRUCT_SIZE, DATE_TIME_WITH_ZONE_OFFSET ); - packer.pack( epochSecondLocal ); - packer.pack( nano ); - packer.pack( offsetSeconds ); - } - else - { + packer.packStructHeader(DATE_TIME_STRUCT_SIZE, DATE_TIME_WITH_ZONE_OFFSET); + packer.pack(epochSecondLocal); + packer.pack(nano); + packer.pack(offsetSeconds); + } else { String zoneId = zone.getId(); - packer.packStructHeader( DATE_TIME_STRUCT_SIZE, DATE_TIME_WITH_ZONE_ID ); - packer.pack( epochSecondLocal ); - packer.pack( nano ); - packer.pack( zoneId ); + packer.packStructHeader(DATE_TIME_STRUCT_SIZE, DATE_TIME_WITH_ZONE_ID); + packer.pack(epochSecondLocal); + packer.pack(nano); + packer.pack(zoneId); } } - private void packDuration( IsoDuration duration ) throws IOException - { - packer.packStructHeader( DURATION_TIME_STRUCT_SIZE, DURATION ); - packer.pack( duration.months() ); - packer.pack( duration.days() ); - packer.pack( duration.seconds() ); - packer.pack( duration.nanoseconds() ); + private void packDuration(IsoDuration duration) throws IOException { + packer.packStructHeader(DURATION_TIME_STRUCT_SIZE, DURATION); + packer.pack(duration.months()); + packer.pack(duration.days()); + packer.pack(duration.seconds()); + packer.pack(duration.nanoseconds()); } - private void packPoint( Point point ) throws IOException - { - if ( point instanceof InternalPoint2D ) - { - packPoint2D( point ); - } - else if ( point instanceof InternalPoint3D ) - { - packPoint3D( point ); - } - else - { - throw new IOException( String.format( "Unknown type: type: %s, value: %s", point.getClass(), point.toString() ) ); + private void packPoint(Point point) throws IOException { + if (point instanceof InternalPoint2D) { + packPoint2D(point); + } else if (point instanceof InternalPoint3D) { + packPoint3D(point); + } else { + throw new IOException( + String.format("Unknown type: type: %s, value: %s", point.getClass(), point.toString())); } } - private void packPoint2D( Point point ) throws IOException - { - packer.packStructHeader( POINT_2D_STRUCT_SIZE, POINT_2D_STRUCT_TYPE ); - packer.pack( point.srid() ); - packer.pack( point.x() ); - packer.pack( point.y() ); + private void packPoint2D(Point point) throws IOException { + packer.packStructHeader(POINT_2D_STRUCT_SIZE, POINT_2D_STRUCT_TYPE); + packer.pack(point.srid()); + packer.pack(point.x()); + packer.pack(point.y()); } - private void packPoint3D( Point point ) throws IOException - { - packer.packStructHeader( POINT_3D_STRUCT_SIZE, POINT_3D_STRUCT_TYPE ); - packer.pack( point.srid() ); - packer.pack( point.x() ); - packer.pack( point.y() ); - packer.pack( point.z() ); + private void packPoint3D(Point point) throws IOException { + packer.packStructHeader(POINT_3D_STRUCT_SIZE, POINT_3D_STRUCT_TYPE); + packer.pack(point.srid()); + packer.pack(point.x()); + packer.pack(point.y()); + packer.pack(point.z()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValueUnpacker.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValueUnpacker.java index 768635e609..6bb8e2e5cf 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValueUnpacker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValueUnpacker.java @@ -18,6 +18,11 @@ */ package org.neo4j.driver.internal.messaging.common; +import static java.time.ZoneOffset.UTC; +import static org.neo4j.driver.Values.isoDuration; +import static org.neo4j.driver.Values.point; +import static org.neo4j.driver.Values.value; + import java.io.IOException; import java.time.Instant; import java.time.LocalDate; @@ -32,7 +37,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; - import org.neo4j.driver.Value; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.InternalNode; @@ -53,13 +57,7 @@ import org.neo4j.driver.types.Path; import org.neo4j.driver.types.Relationship; -import static java.time.ZoneOffset.UTC; -import static org.neo4j.driver.Values.isoDuration; -import static org.neo4j.driver.Values.point; -import static org.neo4j.driver.Values.value; - -public class CommonValueUnpacker implements ValueUnpacker -{ +public class CommonValueUnpacker implements ValueUnpacker { public static final byte DATE = 'D'; public static final int DATE_STRUCT_SIZE = 1; @@ -95,199 +93,178 @@ public class CommonValueUnpacker implements ValueUnpacker protected final PackStream.Unpacker unpacker; - public CommonValueUnpacker( PackInput input ) - { - this.unpacker = new PackStream.Unpacker( input ); + public CommonValueUnpacker(PackInput input) { + this.unpacker = new PackStream.Unpacker(input); } @Override - public long unpackStructHeader() throws IOException - { + public long unpackStructHeader() throws IOException { return unpacker.unpackStructHeader(); } @Override - public int unpackStructSignature() throws IOException - { + public int unpackStructSignature() throws IOException { return unpacker.unpackStructSignature(); } @Override - public Map unpackMap() throws IOException - { + public Map unpackMap() throws IOException { int size = (int) unpacker.unpackMapHeader(); - if ( size == 0 ) - { + if (size == 0) { return Collections.emptyMap(); } - Map map = Iterables.newHashMapWithSize( size ); - for ( int i = 0; i < size; i++ ) - { + Map map = Iterables.newHashMapWithSize(size); + for (int i = 0; i < size; i++) { String key = unpacker.unpackString(); - map.put( key, unpack() ); + map.put(key, unpack()); } return map; } @Override - public Value[] unpackArray() throws IOException - { + public Value[] unpackArray() throws IOException { int size = (int) unpacker.unpackListHeader(); Value[] values = new Value[size]; - for ( int i = 0; i < size; i++ ) - { + for (int i = 0; i < size; i++) { values[i] = unpack(); } return values; } - private Value unpack() throws IOException - { + private Value unpack() throws IOException { PackType type = unpacker.peekNextType(); - switch ( type ) - { - case NULL: - return value( unpacker.unpackNull() ); - case BOOLEAN: - return value( unpacker.unpackBoolean() ); - case INTEGER: - return value( unpacker.unpackLong() ); - case FLOAT: - return value( unpacker.unpackDouble() ); - case BYTES: - return value( unpacker.unpackBytes() ); - case STRING: - return value( unpacker.unpackString() ); - case MAP: - { - return new MapValue( unpackMap() ); - } - case LIST: - { - int size = (int) unpacker.unpackListHeader(); - Value[] vals = new Value[size]; - for ( int j = 0; j < size; j++ ) - { - vals[j] = unpack(); + switch (type) { + case NULL: + return value(unpacker.unpackNull()); + case BOOLEAN: + return value(unpacker.unpackBoolean()); + case INTEGER: + return value(unpacker.unpackLong()); + case FLOAT: + return value(unpacker.unpackDouble()); + case BYTES: + return value(unpacker.unpackBytes()); + case STRING: + return value(unpacker.unpackString()); + case MAP: { + return new MapValue(unpackMap()); + } + case LIST: { + int size = (int) unpacker.unpackListHeader(); + Value[] vals = new Value[size]; + for (int j = 0; j < size; j++) { + vals[j] = unpack(); + } + return new ListValue(vals); + } + case STRUCT: { + long size = unpacker.unpackStructHeader(); + byte structType = unpacker.unpackStructSignature(); + return unpackStruct(size, structType); } - return new ListValue( vals ); - } - case STRUCT: - { - long size = unpacker.unpackStructHeader(); - byte structType = unpacker.unpackStructSignature(); - return unpackStruct( size, structType ); - } } - throw new IOException( "Unknown value type: " + type ); + throw new IOException("Unknown value type: " + type); } - protected Value unpackStruct( long size, byte type ) throws IOException - { - switch ( type ) - { - case DATE: - ensureCorrectStructSize( TypeConstructor.DATE, DATE_STRUCT_SIZE, size ); - return unpackDate(); - case TIME: - ensureCorrectStructSize( TypeConstructor.TIME, TIME_STRUCT_SIZE, size ); - return unpackTime(); - case LOCAL_TIME: - ensureCorrectStructSize( TypeConstructor.LOCAL_TIME, LOCAL_TIME_STRUCT_SIZE, size ); - return unpackLocalTime(); - case LOCAL_DATE_TIME: - ensureCorrectStructSize( TypeConstructor.LOCAL_DATE_TIME, LOCAL_DATE_TIME_STRUCT_SIZE, size ); - return unpackLocalDateTime(); - case DATE_TIME_WITH_ZONE_OFFSET: - ensureCorrectStructSize( TypeConstructor.DATE_TIME, DATE_TIME_STRUCT_SIZE, size ); - return unpackDateTimeWithZoneOffset(); - case DATE_TIME_WITH_ZONE_ID: - ensureCorrectStructSize( TypeConstructor.DATE_TIME, DATE_TIME_STRUCT_SIZE, size ); - return unpackDateTimeWithZoneId(); - case DURATION: - ensureCorrectStructSize( TypeConstructor.DURATION, DURATION_TIME_STRUCT_SIZE, size ); - return unpackDuration(); - case POINT_2D_STRUCT_TYPE: - ensureCorrectStructSize( TypeConstructor.POINT, POINT_2D_STRUCT_SIZE, size ); - return unpackPoint2D(); - case POINT_3D_STRUCT_TYPE: - ensureCorrectStructSize( TypeConstructor.POINT, POINT_3D_STRUCT_SIZE, size ); - return unpackPoint3D(); - case NODE: - ensureCorrectStructSize( TypeConstructor.NODE, NODE_FIELDS, size ); - InternalNode adapted = unpackNode(); - return new NodeValue( adapted ); - case RELATIONSHIP: - ensureCorrectStructSize( TypeConstructor.RELATIONSHIP, 5, size ); - return unpackRelationship(); - case PATH: - ensureCorrectStructSize( TypeConstructor.PATH, 3, size ); - return unpackPath(); - default: - throw new IOException( "Unknown struct type: " + type ); + protected Value unpackStruct(long size, byte type) throws IOException { + switch (type) { + case DATE: + ensureCorrectStructSize(TypeConstructor.DATE, DATE_STRUCT_SIZE, size); + return unpackDate(); + case TIME: + ensureCorrectStructSize(TypeConstructor.TIME, TIME_STRUCT_SIZE, size); + return unpackTime(); + case LOCAL_TIME: + ensureCorrectStructSize(TypeConstructor.LOCAL_TIME, LOCAL_TIME_STRUCT_SIZE, size); + return unpackLocalTime(); + case LOCAL_DATE_TIME: + ensureCorrectStructSize(TypeConstructor.LOCAL_DATE_TIME, LOCAL_DATE_TIME_STRUCT_SIZE, size); + return unpackLocalDateTime(); + case DATE_TIME_WITH_ZONE_OFFSET: + ensureCorrectStructSize(TypeConstructor.DATE_TIME, DATE_TIME_STRUCT_SIZE, size); + return unpackDateTimeWithZoneOffset(); + case DATE_TIME_WITH_ZONE_ID: + ensureCorrectStructSize(TypeConstructor.DATE_TIME, DATE_TIME_STRUCT_SIZE, size); + return unpackDateTimeWithZoneId(); + case DURATION: + ensureCorrectStructSize(TypeConstructor.DURATION, DURATION_TIME_STRUCT_SIZE, size); + return unpackDuration(); + case POINT_2D_STRUCT_TYPE: + ensureCorrectStructSize(TypeConstructor.POINT, POINT_2D_STRUCT_SIZE, size); + return unpackPoint2D(); + case POINT_3D_STRUCT_TYPE: + ensureCorrectStructSize(TypeConstructor.POINT, POINT_3D_STRUCT_SIZE, size); + return unpackPoint3D(); + case NODE: + ensureCorrectStructSize(TypeConstructor.NODE, NODE_FIELDS, size); + InternalNode adapted = unpackNode(); + return new NodeValue(adapted); + case RELATIONSHIP: + ensureCorrectStructSize(TypeConstructor.RELATIONSHIP, 5, size); + return unpackRelationship(); + case PATH: + ensureCorrectStructSize(TypeConstructor.PATH, 3, size); + return unpackPath(); + default: + throw new IOException("Unknown struct type: " + type); } } - private Value unpackRelationship() throws IOException - { + private Value unpackRelationship() throws IOException { long urn = unpacker.unpackLong(); long startUrn = unpacker.unpackLong(); long endUrn = unpacker.unpackLong(); String relType = unpacker.unpackString(); - Map props = unpackMap(); + Map props = unpackMap(); - InternalRelationship adapted = new InternalRelationship( urn, startUrn, endUrn, relType, props ); - return new RelationshipValue( adapted ); + InternalRelationship adapted = new InternalRelationship(urn, startUrn, endUrn, relType, props); + return new RelationshipValue(adapted); } - private InternalNode unpackNode() throws IOException - { + private InternalNode unpackNode() throws IOException { long urn = unpacker.unpackLong(); int numLabels = (int) unpacker.unpackListHeader(); - List labels = new ArrayList<>( numLabels ); - for ( int i = 0; i < numLabels; i++ ) - { - labels.add( unpacker.unpackString() ); + List labels = new ArrayList<>(numLabels); + for (int i = 0; i < numLabels; i++) { + labels.add(unpacker.unpackString()); } int numProps = (int) unpacker.unpackMapHeader(); - Map props = Iterables.newHashMapWithSize( numProps ); - for ( int j = 0; j < numProps; j++ ) - { + Map props = Iterables.newHashMapWithSize(numProps); + for (int j = 0; j < numProps; j++) { String key = unpacker.unpackString(); - props.put( key, unpack() ); + props.put(key, unpack()); } - return new InternalNode( urn, labels, props ); + return new InternalNode(urn, labels, props); } - private Value unpackPath() throws IOException - { + private Value unpackPath() throws IOException { // List of unique nodes Node[] uniqNodes = new Node[(int) unpacker.unpackListHeader()]; - for ( int i = 0; i < uniqNodes.length; i++ ) - { - ensureCorrectStructSize( TypeConstructor.NODE, NODE_FIELDS, unpacker.unpackStructHeader() ); - ensureCorrectStructSignature( "NODE", NODE, unpacker.unpackStructSignature() ); + for (int i = 0; i < uniqNodes.length; i++) { + ensureCorrectStructSize(TypeConstructor.NODE, NODE_FIELDS, unpacker.unpackStructHeader()); + ensureCorrectStructSignature("NODE", NODE, unpacker.unpackStructSignature()); uniqNodes[i] = unpackNode(); } // List of unique relationships, without start/end information InternalRelationship[] uniqRels = new InternalRelationship[(int) unpacker.unpackListHeader()]; - for ( int i = 0; i < uniqRels.length; i++ ) - { - ensureCorrectStructSize( TypeConstructor.RELATIONSHIP, 3, unpacker.unpackStructHeader() ); - ensureCorrectStructSignature( "UNBOUND_RELATIONSHIP", UNBOUND_RELATIONSHIP, unpacker.unpackStructSignature() ); + for (int i = 0; i < uniqRels.length; i++) { + ensureCorrectStructSize(TypeConstructor.RELATIONSHIP, 3, unpacker.unpackStructHeader()); + ensureCorrectStructSignature( + "UNBOUND_RELATIONSHIP", UNBOUND_RELATIONSHIP, unpacker.unpackStructSignature()); long id = unpacker.unpackLong(); String relType = unpacker.unpackString(); - Map props = unpackMap(); - uniqRels[i] = new InternalRelationship( id, -1, -1, relType, props ); + Map props = unpackMap(); + uniqRels[i] = new InternalRelationship(id, -1, -1, relType, props); } // Path sequence int length = (int) unpacker.unpackListHeader(); - // Knowing the sequence length, we can create the arrays that will represent the nodes, rels and segments in their "path order" + // Knowing the sequence length, we can create the arrays that will represent the nodes, rels and segments in + // their "path order" Path.Segment[] segments = new Path.Segment[length / 2]; Node[] nodes = new Node[segments.length + 1]; Relationship[] rels = new Relationship[segments.length]; @@ -295,128 +272,109 @@ private Value unpackPath() throws IOException Node prevNode = uniqNodes[0], nextNode; // Start node is always 0, and isn't encoded in the sequence nodes[0] = prevNode; InternalRelationship rel; - for ( int i = 0; i < segments.length; i++ ) - { + for (int i = 0; i < segments.length; i++) { int relIdx = (int) unpacker.unpackLong(); nextNode = uniqNodes[(int) unpacker.unpackLong()]; // Negative rel index means this rel was traversed "inversed" from its direction - if ( relIdx < 0 ) - { + if (relIdx < 0) { rel = uniqRels[(-relIdx) - 1]; // -1 because rel idx are 1-indexed - rel.setStartAndEnd( nextNode.id(), prevNode.id() ); - } - else - { + rel.setStartAndEnd(nextNode.id(), prevNode.id()); + } else { rel = uniqRels[relIdx - 1]; - rel.setStartAndEnd( prevNode.id(), nextNode.id() ); + rel.setStartAndEnd(prevNode.id(), nextNode.id()); } nodes[i + 1] = nextNode; rels[i] = rel; - segments[i] = new InternalPath.SelfContainedSegment( prevNode, rel, nextNode ); + segments[i] = new InternalPath.SelfContainedSegment(prevNode, rel, nextNode); prevNode = nextNode; } - return new PathValue( new InternalPath( Arrays.asList( segments ), Arrays.asList( nodes ), Arrays.asList( rels ) ) ); + return new PathValue(new InternalPath(Arrays.asList(segments), Arrays.asList(nodes), Arrays.asList(rels))); } - protected final void ensureCorrectStructSize( TypeConstructor typeConstructor, int expected, long actual ) - { - if ( expected != actual ) - { + protected final void ensureCorrectStructSize(TypeConstructor typeConstructor, int expected, long actual) { + if (expected != actual) { String structName = typeConstructor.toString(); - throw new ClientException( String.format( + throw new ClientException(String.format( "Invalid message received, serialized %s structures should have %d fields, " - + "received %s structure has %d fields.", structName, expected, structName, actual ) ); + + "received %s structure has %d fields.", + structName, expected, structName, actual)); } } - private void ensureCorrectStructSignature( String structName, byte expected, byte actual ) - { - if ( expected != actual ) - { - throw new ClientException( String.format( + private void ensureCorrectStructSignature(String structName, byte expected, byte actual) { + if (expected != actual) { + throw new ClientException(String.format( "Invalid message received, expected a `%s`, signature 0x%s. Received signature was 0x%s.", - structName, Integer.toHexString( expected ), Integer.toHexString( actual ) ) ); + structName, Integer.toHexString(expected), Integer.toHexString(actual))); } } - private Value unpackDate() throws IOException - { + private Value unpackDate() throws IOException { long epochDay = unpacker.unpackLong(); - return value( LocalDate.ofEpochDay( epochDay ) ); + return value(LocalDate.ofEpochDay(epochDay)); } - private Value unpackTime() throws IOException - { + private Value unpackTime() throws IOException { long nanoOfDayLocal = unpacker.unpackLong(); - int offsetSeconds = Math.toIntExact( unpacker.unpackLong() ); + int offsetSeconds = Math.toIntExact(unpacker.unpackLong()); - LocalTime localTime = LocalTime.ofNanoOfDay( nanoOfDayLocal ); - ZoneOffset offset = ZoneOffset.ofTotalSeconds( offsetSeconds ); - return value( OffsetTime.of( localTime, offset ) ); + LocalTime localTime = LocalTime.ofNanoOfDay(nanoOfDayLocal); + ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSeconds); + return value(OffsetTime.of(localTime, offset)); } - private Value unpackLocalTime() throws IOException - { + private Value unpackLocalTime() throws IOException { long nanoOfDayLocal = unpacker.unpackLong(); - return value( LocalTime.ofNanoOfDay( nanoOfDayLocal ) ); + return value(LocalTime.ofNanoOfDay(nanoOfDayLocal)); } - private Value unpackLocalDateTime() throws IOException - { + private Value unpackLocalDateTime() throws IOException { long epochSecondUtc = unpacker.unpackLong(); - int nano = Math.toIntExact( unpacker.unpackLong() ); - return value( LocalDateTime.ofEpochSecond( epochSecondUtc, nano, UTC ) ); + int nano = Math.toIntExact(unpacker.unpackLong()); + return value(LocalDateTime.ofEpochSecond(epochSecondUtc, nano, UTC)); } - private Value unpackDateTimeWithZoneOffset() throws IOException - { + private Value unpackDateTimeWithZoneOffset() throws IOException { long epochSecondLocal = unpacker.unpackLong(); - int nano = Math.toIntExact( unpacker.unpackLong() ); - int offsetSeconds = Math.toIntExact( unpacker.unpackLong() ); - return value( newZonedDateTime( epochSecondLocal, nano, ZoneOffset.ofTotalSeconds( offsetSeconds ) ) ); + int nano = Math.toIntExact(unpacker.unpackLong()); + int offsetSeconds = Math.toIntExact(unpacker.unpackLong()); + return value(newZonedDateTime(epochSecondLocal, nano, ZoneOffset.ofTotalSeconds(offsetSeconds))); } - private Value unpackDateTimeWithZoneId() throws IOException - { + private Value unpackDateTimeWithZoneId() throws IOException { long epochSecondLocal = unpacker.unpackLong(); - int nano = Math.toIntExact( unpacker.unpackLong() ); + int nano = Math.toIntExact(unpacker.unpackLong()); String zoneIdString = unpacker.unpackString(); - return value( newZonedDateTime( epochSecondLocal, nano, ZoneId.of( zoneIdString ) ) ); + return value(newZonedDateTime(epochSecondLocal, nano, ZoneId.of(zoneIdString))); } - private Value unpackDuration() throws IOException - { + private Value unpackDuration() throws IOException { long months = unpacker.unpackLong(); long days = unpacker.unpackLong(); long seconds = unpacker.unpackLong(); - int nanoseconds = Math.toIntExact( unpacker.unpackLong() ); - return isoDuration( months, days, seconds, nanoseconds ); + int nanoseconds = Math.toIntExact(unpacker.unpackLong()); + return isoDuration(months, days, seconds, nanoseconds); } - private Value unpackPoint2D() throws IOException - { - int srid = Math.toIntExact( unpacker.unpackLong() ); + private Value unpackPoint2D() throws IOException { + int srid = Math.toIntExact(unpacker.unpackLong()); double x = unpacker.unpackDouble(); double y = unpacker.unpackDouble(); - return point( srid, x, y ); + return point(srid, x, y); } - private Value unpackPoint3D() throws IOException - { - int srid = Math.toIntExact( unpacker.unpackLong() ); + private Value unpackPoint3D() throws IOException { + int srid = Math.toIntExact(unpacker.unpackLong()); double x = unpacker.unpackDouble(); double y = unpacker.unpackDouble(); double z = unpacker.unpackDouble(); - return point( srid, x, y, z ); + return point(srid, x, y, z); } - private static ZonedDateTime newZonedDateTime( long epochSecondLocal, long nano, ZoneId zoneId ) - { - Instant instant = Instant.ofEpochSecond( epochSecondLocal, nano ); - LocalDateTime localDateTime = LocalDateTime.ofInstant( instant, UTC ); - return ZonedDateTime.of( localDateTime, zoneId ); + private static ZonedDateTime newZonedDateTime(long epochSecondLocal, long nano, ZoneId zoneId) { + Instant instant = Instant.ofEpochSecond(epochSecondLocal, nano); + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, UTC); + return ZonedDateTime.of(localDateTime, zoneId); } } - - diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoder.java index f29784ff53..b16b18ea9e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoder.java @@ -18,23 +18,20 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.BeginMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class BeginMessageEncoder implements MessageEncoder -{ +public class BeginMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, BeginMessage.class ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, BeginMessage.class); BeginMessage beginMessage = (BeginMessage) message; - packer.packStructHeader( 1, beginMessage.signature() ); - packer.pack( beginMessage.metadata() ); + packer.packStructHeader(1, beginMessage.signature()); + packer.pack(beginMessage.metadata()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/CommitMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/CommitMessageEncoder.java index 3654482161..133ab174a5 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/CommitMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/CommitMessageEncoder.java @@ -18,21 +18,18 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.CommitMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class CommitMessageEncoder implements MessageEncoder -{ +public class CommitMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, CommitMessage.class ); - packer.packStructHeader( 0, CommitMessage.SIGNATURE ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, CommitMessage.class); + packer.packStructHeader(0, CommitMessage.SIGNATURE); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/DiscardAllMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/DiscardAllMessageEncoder.java index 54c4383858..e0d2bb62f0 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/DiscardAllMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/DiscardAllMessageEncoder.java @@ -18,21 +18,18 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.DiscardAllMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class DiscardAllMessageEncoder implements MessageEncoder -{ +public class DiscardAllMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, DiscardAllMessage.class ); - packer.packStructHeader( 0, DiscardAllMessage.SIGNATURE ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, DiscardAllMessage.class); + packer.packStructHeader(0, DiscardAllMessage.SIGNATURE); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/DiscardMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/DiscardMessageEncoder.java index 20d8b11162..05056efae2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/DiscardMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/DiscardMessageEncoder.java @@ -18,22 +18,19 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.DiscardMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class DiscardMessageEncoder implements MessageEncoder -{ +public class DiscardMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, DiscardMessage.class ); - packer.packStructHeader( 1, DiscardMessage.SIGNATURE ); - packer.pack( ((DiscardMessage) message).metadata() ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, DiscardMessage.class); + packer.packStructHeader(1, DiscardMessage.SIGNATURE); + packer.pack(((DiscardMessage) message).metadata()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/GoodbyeMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/GoodbyeMessageEncoder.java index b711f3e6d2..5ad8ff1691 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/GoodbyeMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/GoodbyeMessageEncoder.java @@ -18,21 +18,18 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.GoodbyeMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class GoodbyeMessageEncoder implements MessageEncoder -{ +public class GoodbyeMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, GoodbyeMessage.class ); - packer.packStructHeader( 0, GoodbyeMessage.SIGNATURE ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, GoodbyeMessage.class); + packer.packStructHeader(0, GoodbyeMessage.SIGNATURE); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoder.java index b6a92b75da..a4435c7a44 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoder.java @@ -18,23 +18,20 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.HelloMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class HelloMessageEncoder implements MessageEncoder -{ +public class HelloMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, HelloMessage.class ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, HelloMessage.class); HelloMessage helloMessage = (HelloMessage) message; - packer.packStructHeader( 1, helloMessage.signature() ); - packer.pack( helloMessage.metadata() ); + packer.packStructHeader(1, helloMessage.signature()); + packer.pack(helloMessage.metadata()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/PullAllMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/PullAllMessageEncoder.java index 467b28bab4..3e7e037549 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/PullAllMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/PullAllMessageEncoder.java @@ -18,21 +18,18 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.PullAllMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class PullAllMessageEncoder implements MessageEncoder -{ +public class PullAllMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, PullAllMessage.class ); - packer.packStructHeader( 0, PullAllMessage.SIGNATURE ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, PullAllMessage.class); + packer.packStructHeader(0, PullAllMessage.SIGNATURE); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/PullMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/PullMessageEncoder.java index a704abfd3a..82903edd3a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/PullMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/PullMessageEncoder.java @@ -18,22 +18,19 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.PullMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class PullMessageEncoder implements MessageEncoder -{ +public class PullMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, PullMessage.class ); - packer.packStructHeader( 1, PullMessage.SIGNATURE ); - packer.pack( ((PullMessage) message).metadata() ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, PullMessage.class); + packer.packStructHeader(1, PullMessage.SIGNATURE); + packer.pack(((PullMessage) message).metadata()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/ResetMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/ResetMessageEncoder.java index d9000a8e91..1c86f0018e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/ResetMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/ResetMessageEncoder.java @@ -18,21 +18,18 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.ResetMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class ResetMessageEncoder implements MessageEncoder -{ +public class ResetMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, ResetMessage.class ); - packer.packStructHeader( 0, ResetMessage.SIGNATURE ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, ResetMessage.class); + packer.packStructHeader(0, ResetMessage.SIGNATURE); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RollbackMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RollbackMessageEncoder.java index ab537ecf11..072d0b77fe 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RollbackMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RollbackMessageEncoder.java @@ -18,21 +18,18 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.RollbackMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class RollbackMessageEncoder implements MessageEncoder -{ +public class RollbackMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, RollbackMessage.class ); - packer.packStructHeader( 0, RollbackMessage.SIGNATURE ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, RollbackMessage.class); + packer.packStructHeader(0, RollbackMessage.SIGNATURE); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoder.java index 64848d913c..84f1883f0f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoder.java @@ -18,30 +18,30 @@ */ package org.neo4j.driver.internal.messaging.encode; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; + import java.io.IOException; import java.util.Collections; - import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.RouteMessage; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - /** * Encodes the ROUTE message to the stream */ -public class RouteMessageEncoder implements MessageEncoder -{ +public class RouteMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, RouteMessage.class ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, RouteMessage.class); RouteMessage routeMessage = (RouteMessage) message; - packer.packStructHeader( 3, message.signature() ); - packer.pack( routeMessage.getRoutingContext() ); - packer.pack( routeMessage.getBookmark().isPresent() ? value( routeMessage.getBookmark().get().values() ) : value( Collections.emptyList() ) ); - packer.pack( routeMessage.getDatabaseName() ); + packer.packStructHeader(3, message.signature()); + packer.pack(routeMessage.getRoutingContext()); + packer.pack( + routeMessage.getBookmark().isPresent() + ? value(routeMessage.getBookmark().get().values()) + : value(Collections.emptyList())); + packer.pack(routeMessage.getDatabaseName()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteV44MessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteV44MessageEncoder.java index e15d5511c0..a229cfea34 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteV44MessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteV44MessageEncoder.java @@ -18,46 +18,41 @@ */ package org.neo4j.driver.internal.messaging.encode; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; + import java.io.IOException; import java.util.Collections; import java.util.Map; - import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.RouteMessage; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - /** * Encodes the ROUTE message to the stream */ -public class RouteV44MessageEncoder implements MessageEncoder -{ +public class RouteV44MessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, RouteMessage.class ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, RouteMessage.class); RouteMessage routeMessage = (RouteMessage) message; - packer.packStructHeader( 3, message.signature() ); - packer.pack( routeMessage.getRoutingContext() ); - packer.pack( routeMessage.getBookmark().isPresent() ? value( routeMessage.getBookmark().get().values() ) : value( Collections.emptyList() ) ); + packer.packStructHeader(3, message.signature()); + packer.pack(routeMessage.getRoutingContext()); + packer.pack( + routeMessage.getBookmark().isPresent() + ? value(routeMessage.getBookmark().get().values()) + : value(Collections.emptyList())); - Map params; - if ( routeMessage.getImpersonatedUser() != null && routeMessage.getDatabaseName() == null ) - { - params = Collections.singletonMap( "imp_user", value( routeMessage.getImpersonatedUser() ) ); - } - else if ( routeMessage.getDatabaseName() != null ) - { - params = Collections.singletonMap( "db", value( routeMessage.getDatabaseName() ) ); - } - else - { + Map params; + if (routeMessage.getImpersonatedUser() != null && routeMessage.getDatabaseName() == null) { + params = Collections.singletonMap("imp_user", value(routeMessage.getImpersonatedUser())); + } else if (routeMessage.getDatabaseName() != null) { + params = Collections.singletonMap("db", value(routeMessage.getDatabaseName())); + } else { params = Collections.emptyMap(); } - packer.pack( params ); + packer.pack(params); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoder.java index 4ed68feae2..43ada81b36 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoder.java @@ -18,25 +18,22 @@ */ package org.neo4j.driver.internal.messaging.encode; -import java.io.IOException; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; +import java.io.IOException; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -public class RunWithMetadataMessageEncoder implements MessageEncoder -{ +public class RunWithMetadataMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - checkArgument( message, RunWithMetadataMessage.class ); + public void encode(Message message, ValuePacker packer) throws IOException { + checkArgument(message, RunWithMetadataMessage.class); RunWithMetadataMessage runMessage = (RunWithMetadataMessage) message; - packer.packStructHeader( 3, runMessage.signature() ); - packer.pack( runMessage.query() ); - packer.pack( runMessage.parameters() ); - packer.pack( runMessage.metadata() ); + packer.packStructHeader(3, runMessage.signature()); + packer.pack(runMessage.query()); + packer.pack(runMessage.parameters()); + packer.pack(runMessage.metadata()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/AbstractStreamingMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/AbstractStreamingMessage.java index 9a4b025037..0f46f1b264 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/AbstractStreamingMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/AbstractStreamingMessage.java @@ -18,62 +18,51 @@ */ package org.neo4j.driver.internal.messaging.request; +import static org.neo4j.driver.internal.util.MetadataExtractor.ABSENT_QUERY_ID; + import java.util.HashMap; import java.util.Map; import java.util.Objects; - -import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.Value; import org.neo4j.driver.Values; +import org.neo4j.driver.internal.messaging.Message; -import static org.neo4j.driver.internal.util.MetadataExtractor.ABSENT_QUERY_ID; - -public abstract class AbstractStreamingMessage implements Message -{ - private final Map metadata = new HashMap<>(); +public abstract class AbstractStreamingMessage implements Message { + private final Map metadata = new HashMap<>(); public static final long STREAM_LIMIT_UNLIMITED = -1; - AbstractStreamingMessage( long n, long id ) - { - this.metadata.put( "n", Values.value( n ) ); - if ( id != ABSENT_QUERY_ID ) - { - this.metadata.put( "qid", Values.value( id ) ); + AbstractStreamingMessage(long n, long id) { + this.metadata.put("n", Values.value(n)); + if (id != ABSENT_QUERY_ID) { + this.metadata.put("qid", Values.value(id)); } } - public Map metadata() - { + public Map metadata() { return metadata; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } AbstractStreamingMessage that = (AbstractStreamingMessage) o; - return Objects.equals( metadata, that.metadata ); + return Objects.equals(metadata, that.metadata); } protected abstract String name(); @Override - public int hashCode() - { - return Objects.hash( metadata ); + public int hashCode() { + return Objects.hash(metadata); } @Override - public String toString() - { - return String.format( "%s %s", name(), metadata ); + public String toString() { + return String.format("%s %s", name(), metadata); } - } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/BeginMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/BeginMessage.java index 0e82cd61da..a71089f536 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/BeginMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/BeginMessage.java @@ -18,63 +18,63 @@ */ package org.neo4j.driver.internal.messaging.request; +import static org.neo4j.driver.internal.messaging.request.TransactionMetadataBuilder.buildMetadata; + import java.time.Duration; import java.util.Map; import java.util.Objects; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.Value; import org.neo4j.driver.internal.DatabaseName; -import static org.neo4j.driver.internal.messaging.request.TransactionMetadataBuilder.buildMetadata; - -public class BeginMessage extends MessageWithMetadata -{ +public class BeginMessage extends MessageWithMetadata { public static final byte SIGNATURE = 0x11; - public BeginMessage( Bookmark bookmark, TransactionConfig config, DatabaseName databaseName, AccessMode mode, String impersonatedUser ) - { - this( bookmark, config.timeout(), config.metadata(), mode, databaseName, impersonatedUser ); + public BeginMessage( + Bookmark bookmark, + TransactionConfig config, + DatabaseName databaseName, + AccessMode mode, + String impersonatedUser) { + this(bookmark, config.timeout(), config.metadata(), mode, databaseName, impersonatedUser); } - public BeginMessage( Bookmark bookmark, Duration txTimeout, Map txMetadata, AccessMode mode, DatabaseName databaseName, - String impersonatedUser ) - { - super( buildMetadata( txTimeout, txMetadata, databaseName, mode, bookmark, impersonatedUser ) ); + public BeginMessage( + Bookmark bookmark, + Duration txTimeout, + Map txMetadata, + AccessMode mode, + DatabaseName databaseName, + String impersonatedUser) { + super(buildMetadata(txTimeout, txMetadata, databaseName, mode, bookmark, impersonatedUser)); } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } BeginMessage that = (BeginMessage) o; - return Objects.equals( metadata(), that.metadata() ); + return Objects.equals(metadata(), that.metadata()); } @Override - public int hashCode() - { - return Objects.hash( metadata() ); + public int hashCode() { + return Objects.hash(metadata()); } @Override - public String toString() - { + public String toString() { return "BEGIN " + metadata(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/CommitMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/CommitMessage.java index c163546986..e149c1a6b2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/CommitMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/CommitMessage.java @@ -20,25 +20,20 @@ import org.neo4j.driver.internal.messaging.Message; -public class CommitMessage implements Message -{ +public class CommitMessage implements Message { public static final byte SIGNATURE = 0x12; public static final Message COMMIT = new CommitMessage(); - private CommitMessage() - { - } + private CommitMessage() {} @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { + public String toString() { return "COMMIT"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/DiscardAllMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/DiscardAllMessage.java index 8662f2195c..658e05590b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/DiscardAllMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/DiscardAllMessage.java @@ -20,25 +20,20 @@ import org.neo4j.driver.internal.messaging.Message; -public class DiscardAllMessage implements Message -{ - public final static byte SIGNATURE = 0x2F; +public class DiscardAllMessage implements Message { + public static final byte SIGNATURE = 0x2F; public static final DiscardAllMessage DISCARD_ALL = new DiscardAllMessage(); - private DiscardAllMessage() - { - } + private DiscardAllMessage() {} @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { + public String toString() { return "DISCARD_ALL"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/DiscardMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/DiscardMessage.java index 7f57331b1d..27200afd03 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/DiscardMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/DiscardMessage.java @@ -18,29 +18,24 @@ */ package org.neo4j.driver.internal.messaging.request; -public class DiscardMessage extends AbstractStreamingMessage -{ - public final static byte SIGNATURE = 0x2F; +public class DiscardMessage extends AbstractStreamingMessage { + public static final byte SIGNATURE = 0x2F; - public static DiscardMessage newDiscardAllMessage( long id ) - { - return new DiscardMessage( STREAM_LIMIT_UNLIMITED, id ); + public static DiscardMessage newDiscardAllMessage(long id) { + return new DiscardMessage(STREAM_LIMIT_UNLIMITED, id); } - public DiscardMessage( long n, long id ) - { - super( n, id ); + public DiscardMessage(long n, long id) { + super(n, id); } @Override - protected String name() - { + protected String name() { return "DISCARD"; } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/GoodbyeMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/GoodbyeMessage.java index 6814c75489..ef7e62db49 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/GoodbyeMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/GoodbyeMessage.java @@ -20,25 +20,20 @@ import org.neo4j.driver.internal.messaging.Message; -public class GoodbyeMessage implements Message -{ - public final static byte SIGNATURE = 0x02; +public class GoodbyeMessage implements Message { + public static final byte SIGNATURE = 0x02; public static final GoodbyeMessage GOODBYE = new GoodbyeMessage(); - private GoodbyeMessage() - { - } + private GoodbyeMessage() {} @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { + public String toString() { return "GOODBYE"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/HelloMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/HelloMessage.java index 1de10640f4..95a6d7168c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/HelloMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/HelloMessage.java @@ -18,69 +18,59 @@ */ package org.neo4j.driver.internal.messaging.request; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.security.InternalAuthToken.CREDENTIALS_KEY; + import java.util.HashMap; import java.util.Map; import java.util.Objects; - import org.neo4j.driver.Value; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.security.InternalAuthToken.CREDENTIALS_KEY; - -public class HelloMessage extends MessageWithMetadata -{ - public final static byte SIGNATURE = 0x01; +public class HelloMessage extends MessageWithMetadata { + public static final byte SIGNATURE = 0x01; private static final String USER_AGENT_METADATA_KEY = "user_agent"; private static final String ROUTING_CONTEXT_METADATA_KEY = "routing"; - public HelloMessage( String userAgent, Map authToken, Map routingContext ) - { - super( buildMetadata( userAgent, authToken, routingContext ) ); + public HelloMessage(String userAgent, Map authToken, Map routingContext) { + super(buildMetadata(userAgent, authToken, routingContext)); } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } HelloMessage that = (HelloMessage) o; - return Objects.equals( metadata(), that.metadata() ); + return Objects.equals(metadata(), that.metadata()); } @Override - public int hashCode() - { - return Objects.hash( metadata() ); + public int hashCode() { + return Objects.hash(metadata()); } @Override - public String toString() - { - Map metadataCopy = new HashMap<>( metadata() ); - metadataCopy.replace( CREDENTIALS_KEY, value( "******" ) ); + public String toString() { + Map metadataCopy = new HashMap<>(metadata()); + metadataCopy.replace(CREDENTIALS_KEY, value("******")); return "HELLO " + metadataCopy; } - private static Map buildMetadata( String userAgent, Map authToken, Map routingContext ) - { - Map result = new HashMap<>( authToken ); - result.put( USER_AGENT_METADATA_KEY, value( userAgent ) ); - if ( routingContext != null ) - { - result.put( ROUTING_CONTEXT_METADATA_KEY, value( routingContext ) ); + private static Map buildMetadata( + String userAgent, Map authToken, Map routingContext) { + Map result = new HashMap<>(authToken); + result.put(USER_AGENT_METADATA_KEY, value(userAgent)); + if (routingContext != null) { + result.put(ROUTING_CONTEXT_METADATA_KEY, value(routingContext)); } return result; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MessageWithMetadata.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MessageWithMetadata.java index 5cb540e674..76aa05be48 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MessageWithMetadata.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MessageWithMetadata.java @@ -19,21 +19,17 @@ package org.neo4j.driver.internal.messaging.request; import java.util.Map; - import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.Message; -abstract class MessageWithMetadata implements Message -{ - private final Map metadata; +abstract class MessageWithMetadata implements Message { + private final Map metadata; - public MessageWithMetadata( Map metadata ) - { + public MessageWithMetadata(Map metadata) { this.metadata = metadata; } - public Map metadata() - { + public Map metadata() { return metadata; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MultiDatabaseUtil.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MultiDatabaseUtil.java index 8907fe7b43..2ab9618fd2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MultiDatabaseUtil.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/MultiDatabaseUtil.java @@ -26,25 +26,22 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.ServerVersion; -public final class MultiDatabaseUtil -{ - public static void assertEmptyDatabaseName( DatabaseName databaseName, BoltProtocolVersion boltVersion ) - { - if ( databaseName.databaseName().isPresent() ) - { - throw new ClientException( String.format( "Database name parameter for selecting database is not supported in Bolt Protocol Version %s. " + - "Database name: '%s'", boltVersion, databaseName.description() ) ); +public final class MultiDatabaseUtil { + public static void assertEmptyDatabaseName(DatabaseName databaseName, BoltProtocolVersion boltVersion) { + if (databaseName.databaseName().isPresent()) { + throw new ClientException(String.format( + "Database name parameter for selecting database is not supported in Bolt Protocol Version %s. " + + "Database name: '%s'", + boltVersion, databaseName.description())); } } - public static boolean supportsMultiDatabase( Connection connection ) - { - return connection.serverVersion().greaterThanOrEqual( ServerVersion.v4_0_0 ) && - connection.protocol().version().compareTo( BoltProtocolV4.VERSION ) >= 0; + public static boolean supportsMultiDatabase(Connection connection) { + return connection.serverVersion().greaterThanOrEqual(ServerVersion.v4_0_0) + && connection.protocol().version().compareTo(BoltProtocolV4.VERSION) >= 0; } - public static boolean supportsRouteMessage( Connection connection ) - { - return connection.protocol().version().compareTo( BoltProtocolV43.VERSION ) >= 0; + public static boolean supportsRouteMessage(Connection connection) { + return connection.protocol().version().compareTo(BoltProtocolV43.VERSION) >= 0; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/PullAllMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/PullAllMessage.java index 595c1a195b..1be32c87a2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/PullAllMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/PullAllMessage.java @@ -25,25 +25,20 @@ *

* Sent by clients to pull the entirety of the remaining stream down. */ -public class PullAllMessage implements Message -{ +public class PullAllMessage implements Message { public static final byte SIGNATURE = 0x3F; public static final PullAllMessage PULL_ALL = new PullAllMessage(); - private PullAllMessage() - { - } + private PullAllMessage() {} @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { + public String toString() { return "PULL_ALL"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/PullMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/PullMessage.java index 3112266c64..faee0da87e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/PullMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/PullMessage.java @@ -25,25 +25,21 @@ *

* Sent by clients to pull the entirety of the remaining stream down. */ -public class PullMessage extends AbstractStreamingMessage -{ +public class PullMessage extends AbstractStreamingMessage { public static final byte SIGNATURE = 0x3F; - public static final PullMessage PULL_ALL = new PullMessage( STREAM_LIMIT_UNLIMITED, ABSENT_QUERY_ID ); + public static final PullMessage PULL_ALL = new PullMessage(STREAM_LIMIT_UNLIMITED, ABSENT_QUERY_ID); - public PullMessage( long n, long id ) - { - super( n, id ); + public PullMessage(long n, long id) { + super(n, id); } @Override - protected String name() - { + protected String name() { return "PULL"; } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/ResetMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/ResetMessage.java index cbbc0f75ce..abdd3ce76d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/ResetMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/ResetMessage.java @@ -34,25 +34,20 @@ * This message acts as a barrier after an error, informing the server that we've seen the error * message, and that messages that follow this one are safe to execute. */ -public class ResetMessage implements Message -{ +public class ResetMessage implements Message { public static final byte SIGNATURE = 0x0F; public static final ResetMessage RESET = new ResetMessage(); - private ResetMessage() - { - } + private ResetMessage() {} @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { + public String toString() { return "RESET"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RollbackMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RollbackMessage.java index 475d168a14..598536894c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RollbackMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RollbackMessage.java @@ -20,25 +20,20 @@ import org.neo4j.driver.internal.messaging.Message; -public class RollbackMessage implements Message -{ +public class RollbackMessage implements Message { public static final byte SIGNATURE = 0x13; public static final Message ROLLBACK = new RollbackMessage(); - private RollbackMessage() - { - } + private RollbackMessage() {} @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { + public String toString() { return "ROLLBACK"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RouteMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RouteMessage.java index 440f3c81f3..9885985d0a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RouteMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RouteMessage.java @@ -18,26 +18,24 @@ */ package org.neo4j.driver.internal.messaging.request; +import static java.util.Collections.unmodifiableMap; + import java.util.Map; import java.util.Objects; import java.util.Optional; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.Message; -import static java.util.Collections.unmodifiableMap; - /** * From the application point of view it is not interesting to know about the role a member plays in the cluster. Instead, the application needs to know which * instance can provide the wanted service. *

* This message is used to fetch this routing information. */ -public class RouteMessage implements Message -{ - public final static byte SIGNATURE = 0x66; - private final Map routingContext; +public class RouteMessage implements Message { + public static final byte SIGNATURE = 0x66; + private final Map routingContext; private final Bookmark bookmark; private final String databaseName; private final String impersonatedUser; @@ -50,66 +48,56 @@ public class RouteMessage implements Message * @param databaseName The name of the database to get the routing table for. * @param impersonatedUser The name of the impersonated user to get the routing table for, should be {@code null} for non-impersonated requests */ - public RouteMessage( Map routingContext, Bookmark bookmark, String databaseName, String impersonatedUser ) - { - this.routingContext = unmodifiableMap( routingContext ); + public RouteMessage( + Map routingContext, Bookmark bookmark, String databaseName, String impersonatedUser) { + this.routingContext = unmodifiableMap(routingContext); this.bookmark = bookmark; this.databaseName = databaseName; this.impersonatedUser = impersonatedUser; } - public Map getRoutingContext() - { + public Map getRoutingContext() { return routingContext; } - public Optional getBookmark() - { - return Optional.ofNullable( bookmark ); + public Optional getBookmark() { + return Optional.ofNullable(bookmark); } - public String getDatabaseName() - { + public String getDatabaseName() { return databaseName; } - public String getImpersonatedUser() - { + public String getImpersonatedUser() { return impersonatedUser; } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { - return String.format( "ROUTE %s %s %s %s", routingContext, bookmark, databaseName, impersonatedUser ); + public String toString() { + return String.format("ROUTE %s %s %s %s", routingContext, bookmark, databaseName, impersonatedUser); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } RouteMessage that = (RouteMessage) o; - return routingContext.equals( that.routingContext ) && - Objects.equals( databaseName, that.databaseName ) && - Objects.equals( impersonatedUser, that.impersonatedUser ); + return routingContext.equals(that.routingContext) + && Objects.equals(databaseName, that.databaseName) + && Objects.equals(impersonatedUser, that.impersonatedUser); } @Override - public int hashCode() - { - return Objects.hash( routingContext, databaseName, impersonatedUser ); + public int hashCode() { + return Objects.hash(routingContext, databaseName, impersonatedUser); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RunWithMetadataMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RunWithMetadataMessage.java index 91c6712634..d658bc8c20 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RunWithMetadataMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/RunWithMetadataMessage.java @@ -18,10 +18,13 @@ */ package org.neo4j.driver.internal.messaging.request; +import static java.util.Collections.emptyMap; +import static org.neo4j.driver.Values.ofValue; +import static org.neo4j.driver.internal.messaging.request.TransactionMetadataBuilder.buildMetadata; + import java.time.Duration; import java.util.Map; import java.util.Objects; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -29,82 +32,80 @@ import org.neo4j.driver.Value; import org.neo4j.driver.internal.DatabaseName; -import static java.util.Collections.emptyMap; -import static org.neo4j.driver.Values.ofValue; -import static org.neo4j.driver.internal.messaging.request.TransactionMetadataBuilder.buildMetadata; - -public class RunWithMetadataMessage extends MessageWithMetadata -{ - public final static byte SIGNATURE = 0x10; +public class RunWithMetadataMessage extends MessageWithMetadata { + public static final byte SIGNATURE = 0x10; private final String query; - private final Map parameters; + private final Map parameters; - public static RunWithMetadataMessage autoCommitTxRunMessage( Query query, TransactionConfig config, DatabaseName databaseName, AccessMode mode, - Bookmark bookmark, String impersonatedUser ) - { - return autoCommitTxRunMessage( query, config.timeout(), config.metadata(), databaseName, mode, bookmark, impersonatedUser ); + public static RunWithMetadataMessage autoCommitTxRunMessage( + Query query, + TransactionConfig config, + DatabaseName databaseName, + AccessMode mode, + Bookmark bookmark, + String impersonatedUser) { + return autoCommitTxRunMessage( + query, config.timeout(), config.metadata(), databaseName, mode, bookmark, impersonatedUser); } - public static RunWithMetadataMessage autoCommitTxRunMessage( Query query, Duration txTimeout, Map txMetadata, DatabaseName databaseName, - AccessMode mode, Bookmark bookmark, String impersonatedUser ) - { - Map metadata = buildMetadata( txTimeout, txMetadata, databaseName, mode, bookmark, impersonatedUser ); - return new RunWithMetadataMessage( query.text(), query.parameters().asMap( ofValue() ), metadata ); + public static RunWithMetadataMessage autoCommitTxRunMessage( + Query query, + Duration txTimeout, + Map txMetadata, + DatabaseName databaseName, + AccessMode mode, + Bookmark bookmark, + String impersonatedUser) { + Map metadata = + buildMetadata(txTimeout, txMetadata, databaseName, mode, bookmark, impersonatedUser); + return new RunWithMetadataMessage(query.text(), query.parameters().asMap(ofValue()), metadata); } - public static RunWithMetadataMessage unmanagedTxRunMessage( Query query ) - { - return new RunWithMetadataMessage( query.text(), query.parameters().asMap( ofValue() ), emptyMap() ); + public static RunWithMetadataMessage unmanagedTxRunMessage(Query query) { + return new RunWithMetadataMessage(query.text(), query.parameters().asMap(ofValue()), emptyMap()); } - private RunWithMetadataMessage(String query, Map parameters, Map metadata ) - { - super( metadata ); + private RunWithMetadataMessage(String query, Map parameters, Map metadata) { + super(metadata); this.query = query; this.parameters = parameters; } - public String query() - { + public String query() { return query; } - public Map parameters() - { + public Map parameters() { return parameters; } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } RunWithMetadataMessage that = (RunWithMetadataMessage) o; - return Objects.equals(query, that.query) && Objects.equals( parameters, that.parameters ) && Objects.equals( metadata(), that.metadata() ); + return Objects.equals(query, that.query) + && Objects.equals(parameters, that.parameters) + && Objects.equals(metadata(), that.metadata()); } @Override - public int hashCode() - { - return Objects.hash(query, parameters, metadata() ); + public int hashCode() { + return Objects.hash(query, parameters, metadata()); } @Override - public String toString() - { + public String toString() { return "RUN \"" + query + "\" " + parameters + " " + metadata(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilder.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilder.java index 7a4ba34b9c..01a8c04cb4 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilder.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilder.java @@ -18,21 +18,19 @@ */ package org.neo4j.driver.internal.messaging.request; +import static java.util.Collections.emptyMap; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; + import java.time.Duration; import java.util.Map; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Value; import org.neo4j.driver.internal.DatabaseName; import org.neo4j.driver.internal.util.Iterables; -import static java.util.Collections.emptyMap; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; - -public class TransactionMetadataBuilder -{ +public class TransactionMetadataBuilder { private static final String BOOKMARKS_METADATA_KEY = "bookmarks"; private static final String DATABASE_NAME_KEY = "db"; private static final String TX_TIMEOUT_METADATA_KEY = "tx_timeout"; @@ -41,15 +39,22 @@ public class TransactionMetadataBuilder private static final String MODE_READ_VALUE = "r"; private static final String IMPERSONATED_USER_KEY = "imp_user"; - public static Map buildMetadata( Duration txTimeout, Map txMetadata, AccessMode mode, Bookmark bookmark, - String impersonatedUser ) - { - return buildMetadata( txTimeout, txMetadata, defaultDatabase(), mode, bookmark, impersonatedUser ); + public static Map buildMetadata( + Duration txTimeout, + Map txMetadata, + AccessMode mode, + Bookmark bookmark, + String impersonatedUser) { + return buildMetadata(txTimeout, txMetadata, defaultDatabase(), mode, bookmark, impersonatedUser); } - public static Map buildMetadata( Duration txTimeout, Map txMetadata, DatabaseName databaseName, AccessMode mode, - Bookmark bookmark, String impersonatedUser ) - { + public static Map buildMetadata( + Duration txTimeout, + Map txMetadata, + DatabaseName databaseName, + AccessMode mode, + Bookmark bookmark, + String impersonatedUser) { boolean bookmarksPresent = bookmark != null && !bookmark.isEmpty(); boolean txTimeoutPresent = txTimeout != null; boolean txMetadataPresent = txMetadata != null && !txMetadata.isEmpty(); @@ -57,35 +62,34 @@ public static Map buildMetadata( Duration txTimeout, Map result = Iterables.newHashMapWithSize( 5 ); + Map result = Iterables.newHashMapWithSize(5); - if ( bookmarksPresent ) - { - result.put( BOOKMARKS_METADATA_KEY, value( bookmark.values() ) ); + if (bookmarksPresent) { + result.put(BOOKMARKS_METADATA_KEY, value(bookmark.values())); } - if ( txTimeoutPresent ) - { - result.put( TX_TIMEOUT_METADATA_KEY, value( txTimeout.toMillis() ) ); + if (txTimeoutPresent) { + result.put(TX_TIMEOUT_METADATA_KEY, value(txTimeout.toMillis())); } - if ( txMetadataPresent ) - { - result.put( TX_METADATA_METADATA_KEY, value( txMetadata ) ); + if (txMetadataPresent) { + result.put(TX_METADATA_METADATA_KEY, value(txMetadata)); } - if ( accessModePresent ) - { - result.put( MODE_KEY, value( MODE_READ_VALUE ) ); + if (accessModePresent) { + result.put(MODE_KEY, value(MODE_READ_VALUE)); } - if ( impersonatedUserPresent ) - { - result.put( IMPERSONATED_USER_KEY, value( impersonatedUser ) ); + if (impersonatedUserPresent) { + result.put(IMPERSONATED_USER_KEY, value(impersonatedUser)); } - databaseName.databaseName().ifPresent( name -> result.put( DATABASE_NAME_KEY, value( name ) ) ); + databaseName.databaseName().ifPresent(name -> result.put(DATABASE_NAME_KEY, value(name))); return result; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/response/FailureMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/response/FailureMessage.java index 59a88ad1cf..5a9380d99a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/response/FailureMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/response/FailureMessage.java @@ -18,74 +18,63 @@ */ package org.neo4j.driver.internal.messaging.response; -import org.neo4j.driver.internal.messaging.Message; - import static java.lang.String.format; +import org.neo4j.driver.internal.messaging.Message; + /** * FAILURE response message *

* Sent by the server to signal a failed operation. * Terminates response sequence. */ -public class FailureMessage implements Message -{ - public final static byte SIGNATURE = 0x7F; +public class FailureMessage implements Message { + public static final byte SIGNATURE = 0x7F; private final String code; private final String message; - public FailureMessage( String code, String message ) - { + public FailureMessage(String code, String message) { super(); this.code = code; this.message = message; } - public String code() - { + public String code() { return code; } - public String message() - { + public String message() { return message; } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { - return format( "FAILURE %s \"%s\"", code, message ); + public String toString() { + return format("FAILURE %s \"%s\"", code, message); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } FailureMessage that = (FailureMessage) o; - return !(code != null ? !code.equals( that.code ) : that.code != null) && - !(message != null ? !message.equals( that.message ) : that.message != null); - + return !(code != null ? !code.equals(that.code) : that.code != null) + && !(message != null ? !message.equals(that.message) : that.message != null); } @Override - public int hashCode() - { + public int hashCode() { int result = code != null ? code.hashCode() : 0; result = 31 * result + (message != null ? message.hashCode() : 0); return result; diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/response/IgnoredMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/response/IgnoredMessage.java index 86160253cc..7f2dc39b7f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/response/IgnoredMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/response/IgnoredMessage.java @@ -26,37 +26,30 @@ * Sent by the server to signal that an operation has been ignored. * Terminates response sequence. */ -public class IgnoredMessage implements Message -{ - public final static byte SIGNATURE = 0x7E; +public class IgnoredMessage implements Message { + public static final byte SIGNATURE = 0x7E; public static final IgnoredMessage IGNORED = new IgnoredMessage(); - private IgnoredMessage() - { - } + private IgnoredMessage() {} @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { + public String toString() { return "IGNORED {}"; } @Override - public boolean equals( Object obj ) - { + public boolean equals(Object obj) { return obj != null && obj.getClass() == getClass(); } @Override - public int hashCode() - { + public int hashCode() { return 1; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/response/RecordMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/response/RecordMessage.java index 296dd2470e..406b1c49fd 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/response/RecordMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/response/RecordMessage.java @@ -19,58 +19,48 @@ package org.neo4j.driver.internal.messaging.response; import java.util.Arrays; - -import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.Value; +import org.neo4j.driver.internal.messaging.Message; -public class RecordMessage implements Message -{ - public final static byte SIGNATURE = 0x71; +public class RecordMessage implements Message { + public static final byte SIGNATURE = 0x71; private final Value[] fields; - public RecordMessage( Value[] fields ) - { + public RecordMessage(Value[] fields) { this.fields = fields; } - public Value[] fields() - { + public Value[] fields() { return fields; } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { - return "RECORD " + Arrays.toString( fields ); + public String toString() { + return "RECORD " + Arrays.toString(fields); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } RecordMessage that = (RecordMessage) o; - return Arrays.equals( fields, that.fields ); + return Arrays.equals(fields, that.fields); } @Override - public int hashCode() - { - return Arrays.hashCode( fields ); + public int hashCode() { + return Arrays.hashCode(fields); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/response/SuccessMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/response/SuccessMessage.java index d287af0131..1319b631ea 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/response/SuccessMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/response/SuccessMessage.java @@ -18,12 +18,11 @@ */ package org.neo4j.driver.internal.messaging.response; -import java.util.Map; +import static java.lang.String.format; -import org.neo4j.driver.internal.messaging.Message; +import java.util.Map; import org.neo4j.driver.Value; - -import static java.lang.String.format; +import org.neo4j.driver.internal.messaging.Message; /** * SUCCESS response message @@ -31,43 +30,36 @@ * Sent by the server to signal a successful operation. * Terminates response sequence. */ -public class SuccessMessage implements Message -{ - public final static byte SIGNATURE = 0x70; +public class SuccessMessage implements Message { + public static final byte SIGNATURE = 0x70; - private final Map metadata; + private final Map metadata; - public SuccessMessage( Map metadata ) - { + public SuccessMessage(Map metadata) { this.metadata = metadata; } - public Map metadata() - { + public Map metadata() { return metadata; } @Override - public byte signature() - { + public byte signature() { return SIGNATURE; } @Override - public String toString() - { - return format( "SUCCESS %s", metadata ); + public String toString() { + return format("SUCCESS %s", metadata); } @Override - public boolean equals( Object obj ) - { + public boolean equals(Object obj) { return obj != null && obj.getClass() == getClass(); } @Override - public int hashCode() - { + public int hashCode() { return 1; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3.java index 1f86459c7a..a95f327bb8 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3.java @@ -18,12 +18,18 @@ */ package org.neo4j.driver.internal.messaging.v3; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; +import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV3PullAllHandler; +import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; +import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.assertEmptyDatabaseName; +import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; + import io.netty.channel.Channel; import io.netty.channel.ChannelPromise; - import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -54,131 +60,124 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.internal.util.MetadataExtractor; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; -import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV3PullAllHandler; -import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; -import static org.neo4j.driver.internal.messaging.request.MultiDatabaseUtil.assertEmptyDatabaseName; -import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; - -public class BoltProtocolV3 implements BoltProtocol -{ - public static final BoltProtocolVersion VERSION = new BoltProtocolVersion( 3, 0 ); +public class BoltProtocolV3 implements BoltProtocol { + public static final BoltProtocolVersion VERSION = new BoltProtocolVersion(3, 0); public static final BoltProtocol INSTANCE = new BoltProtocolV3(); - public static final MetadataExtractor METADATA_EXTRACTOR = new MetadataExtractor( "t_first", "t_last" ); + public static final MetadataExtractor METADATA_EXTRACTOR = new MetadataExtractor("t_first", "t_last"); @Override - public MessageFormat createMessageFormat() - { + public MessageFormat createMessageFormat() { return new MessageFormatV3(); } @Override - public void initializeChannel( String userAgent, AuthToken authToken, RoutingContext routingContext, ChannelPromise channelInitializedPromise ) - { + public void initializeChannel( + String userAgent, + AuthToken authToken, + RoutingContext routingContext, + ChannelPromise channelInitializedPromise) { Channel channel = channelInitializedPromise.channel(); HelloMessage message; - if ( routingContext.isServerRoutingEnabled() ) - { - message = new HelloMessage( userAgent, ( ( InternalAuthToken ) authToken ).toMap(), routingContext.toMap() ); - } - else - { - message = new HelloMessage( userAgent, ( ( InternalAuthToken ) authToken ).toMap(), null ); + if (routingContext.isServerRoutingEnabled()) { + message = new HelloMessage(userAgent, ((InternalAuthToken) authToken).toMap(), routingContext.toMap()); + } else { + message = new HelloMessage(userAgent, ((InternalAuthToken) authToken).toMap(), null); } - HelloResponseHandler handler = new HelloResponseHandler( channelInitializedPromise, version() ); + HelloResponseHandler handler = new HelloResponseHandler(channelInitializedPromise, version()); - messageDispatcher( channel ).enqueue( handler ); - channel.writeAndFlush( message, channel.voidPromise() ); + messageDispatcher(channel).enqueue(handler); + channel.writeAndFlush(message, channel.voidPromise()); } @Override - public void prepareToCloseChannel( Channel channel ) - { - InboundMessageDispatcher messageDispatcher = messageDispatcher( channel ); + public void prepareToCloseChannel(Channel channel) { + InboundMessageDispatcher messageDispatcher = messageDispatcher(channel); GoodbyeMessage message = GoodbyeMessage.GOODBYE; - messageDispatcher.enqueue( NoOpResponseHandler.INSTANCE ); - channel.writeAndFlush( message, channel.voidPromise() ); + messageDispatcher.enqueue(NoOpResponseHandler.INSTANCE); + channel.writeAndFlush(message, channel.voidPromise()); - messageDispatcher.prepareToCloseChannel( ); + messageDispatcher.prepareToCloseChannel(); } @Override - public CompletionStage beginTransaction( Connection connection, Bookmark bookmark, TransactionConfig config ) - { - try - { - verifyDatabaseNameBeforeTransaction( connection.databaseName() ); - } - catch ( Exception error ) - { - return Futures.failedFuture( error ); + public CompletionStage beginTransaction(Connection connection, Bookmark bookmark, TransactionConfig config) { + try { + verifyDatabaseNameBeforeTransaction(connection.databaseName()); + } catch (Exception error) { + return Futures.failedFuture(error); } CompletableFuture beginTxFuture = new CompletableFuture<>(); - BeginMessage beginMessage = new BeginMessage( bookmark, config, connection.databaseName(), connection.mode(), connection.impersonatedUser() ); - connection.writeAndFlush( beginMessage, new BeginTxResponseHandler( beginTxFuture ) ); + BeginMessage beginMessage = new BeginMessage( + bookmark, config, connection.databaseName(), connection.mode(), connection.impersonatedUser()); + connection.writeAndFlush(beginMessage, new BeginTxResponseHandler(beginTxFuture)); return beginTxFuture; } @Override - public CompletionStage commitTransaction( Connection connection ) - { + public CompletionStage commitTransaction(Connection connection) { CompletableFuture commitFuture = new CompletableFuture<>(); - connection.writeAndFlush( COMMIT, new CommitTxResponseHandler( commitFuture ) ); + connection.writeAndFlush(COMMIT, new CommitTxResponseHandler(commitFuture)); return commitFuture; } @Override - public CompletionStage rollbackTransaction( Connection connection ) - { + public CompletionStage rollbackTransaction(Connection connection) { CompletableFuture rollbackFuture = new CompletableFuture<>(); - connection.writeAndFlush( ROLLBACK, new RollbackTxResponseHandler( rollbackFuture ) ); + connection.writeAndFlush(ROLLBACK, new RollbackTxResponseHandler(rollbackFuture)); return rollbackFuture; } @Override - public ResultCursorFactory runInAutoCommitTransaction( Connection connection, Query query, BookmarkHolder bookmarkHolder, - TransactionConfig config, long fetchSize ) - { - verifyDatabaseNameBeforeTransaction( connection.databaseName() ); - RunWithMetadataMessage runMessage = - autoCommitTxRunMessage( query, config, connection.databaseName(), connection.mode(), bookmarkHolder.getBookmark(), - connection.impersonatedUser() ); - return buildResultCursorFactory( connection, query, bookmarkHolder, null, runMessage, fetchSize ); + public ResultCursorFactory runInAutoCommitTransaction( + Connection connection, + Query query, + BookmarkHolder bookmarkHolder, + TransactionConfig config, + long fetchSize) { + verifyDatabaseNameBeforeTransaction(connection.databaseName()); + RunWithMetadataMessage runMessage = autoCommitTxRunMessage( + query, + config, + connection.databaseName(), + connection.mode(), + bookmarkHolder.getBookmark(), + connection.impersonatedUser()); + return buildResultCursorFactory(connection, query, bookmarkHolder, null, runMessage, fetchSize); } @Override - public ResultCursorFactory runInUnmanagedTransaction( Connection connection, Query query, UnmanagedTransaction tx, long fetchSize ) - { - RunWithMetadataMessage runMessage = unmanagedTxRunMessage( query ); - return buildResultCursorFactory( connection, query, BookmarkHolder.NO_OP, tx, runMessage, fetchSize ); + public ResultCursorFactory runInUnmanagedTransaction( + Connection connection, Query query, UnmanagedTransaction tx, long fetchSize) { + RunWithMetadataMessage runMessage = unmanagedTxRunMessage(query); + return buildResultCursorFactory(connection, query, BookmarkHolder.NO_OP, tx, runMessage, fetchSize); } - protected ResultCursorFactory buildResultCursorFactory( Connection connection, Query query, BookmarkHolder bookmarkHolder, - UnmanagedTransaction tx, RunWithMetadataMessage runMessage, long ignored ) - { + protected ResultCursorFactory buildResultCursorFactory( + Connection connection, + Query query, + BookmarkHolder bookmarkHolder, + UnmanagedTransaction tx, + RunWithMetadataMessage runMessage, + long ignored) { CompletableFuture runFuture = new CompletableFuture<>(); - RunResponseHandler runHandler = new RunResponseHandler( runFuture, METADATA_EXTRACTOR, connection, tx ); - PullAllResponseHandler pullHandler = newBoltV3PullAllHandler( query, runHandler, connection, bookmarkHolder, tx ); + RunResponseHandler runHandler = new RunResponseHandler(runFuture, METADATA_EXTRACTOR, connection, tx); + PullAllResponseHandler pullHandler = newBoltV3PullAllHandler(query, runHandler, connection, bookmarkHolder, tx); - return new AsyncResultCursorOnlyFactory( connection, runMessage, runHandler, runFuture, pullHandler ); + return new AsyncResultCursorOnlyFactory(connection, runMessage, runHandler, runFuture, pullHandler); } - protected void verifyDatabaseNameBeforeTransaction( DatabaseName databaseName ) - { - assertEmptyDatabaseName( databaseName, version() ); + protected void verifyDatabaseNameBeforeTransaction(DatabaseName databaseName) { + assertEmptyDatabaseName(databaseName, version()); } @Override - public BoltProtocolVersion version() - { + public BoltProtocolVersion version() { return VERSION; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/MessageFormatV3.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/MessageFormatV3.java index 0d108619a1..6471e1cb19 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/MessageFormatV3.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/MessageFormatV3.java @@ -23,17 +23,14 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -public class MessageFormatV3 implements MessageFormat -{ +public class MessageFormatV3 implements MessageFormat { @Override - public Writer newWriter( PackOutput output ) - { - return new MessageWriterV3( output ); + public Writer newWriter(PackOutput output) { + return new MessageWriterV3(output); } @Override - public Reader newReader( PackInput input ) - { - return new CommonMessageReader( input ); + public Reader newReader(PackInput input) { + return new CommonMessageReader(input); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3.java index 9d9a95fd57..1e9e577f0f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.messaging.v3; import java.util.Map; - import org.neo4j.driver.internal.messaging.AbstractMessageWriter; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.common.CommonValuePacker; @@ -44,27 +43,24 @@ import org.neo4j.driver.internal.packstream.PackOutput; import org.neo4j.driver.internal.util.Iterables; -public class MessageWriterV3 extends AbstractMessageWriter -{ - public MessageWriterV3( PackOutput output ) - { - super( new CommonValuePacker( output ), buildEncoders() ); +public class MessageWriterV3 extends AbstractMessageWriter { + public MessageWriterV3(PackOutput output) { + super(new CommonValuePacker(output), buildEncoders()); } - private static Map buildEncoders() - { - Map result = Iterables.newHashMapWithSize( 9 ); - result.put( HelloMessage.SIGNATURE, new HelloMessageEncoder() ); - result.put( GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder() ); + private static Map buildEncoders() { + Map result = Iterables.newHashMapWithSize(9); + result.put(HelloMessage.SIGNATURE, new HelloMessageEncoder()); + result.put(GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder()); - result.put( RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder() ); - result.put( DiscardAllMessage.SIGNATURE, new DiscardAllMessageEncoder() ); - result.put( PullAllMessage.SIGNATURE, new PullAllMessageEncoder() ); + result.put(RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder()); + result.put(DiscardAllMessage.SIGNATURE, new DiscardAllMessageEncoder()); + result.put(PullAllMessage.SIGNATURE, new PullAllMessageEncoder()); - result.put( BeginMessage.SIGNATURE, new BeginMessageEncoder() ); - result.put( CommitMessage.SIGNATURE, new CommitMessageEncoder() ); - result.put( RollbackMessage.SIGNATURE, new RollbackMessageEncoder() ); - result.put( ResetMessage.SIGNATURE, new ResetMessageEncoder() ); + result.put(BeginMessage.SIGNATURE, new BeginMessageEncoder()); + result.put(CommitMessage.SIGNATURE, new CommitMessageEncoder()); + result.put(RollbackMessage.SIGNATURE, new RollbackMessageEncoder()); + result.put(ResetMessage.SIGNATURE, new ResetMessageEncoder()); return result; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4.java index 11c89363d4..ee2585fbc6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4.java @@ -18,8 +18,10 @@ */ package org.neo4j.driver.internal.messaging.v4; -import java.util.concurrent.CompletableFuture; +import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV4AutoPullHandler; +import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV4BasicPullHandler; +import java.util.concurrent.CompletableFuture; import org.neo4j.driver.Query; import org.neo4j.driver.internal.BookmarkHolder; import org.neo4j.driver.internal.DatabaseName; @@ -36,42 +38,40 @@ import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; import org.neo4j.driver.internal.spi.Connection; -import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV4AutoPullHandler; -import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV4BasicPullHandler; - -public class BoltProtocolV4 extends BoltProtocolV3 -{ - public static final BoltProtocolVersion VERSION = new BoltProtocolVersion( 4, 0 ); +public class BoltProtocolV4 extends BoltProtocolV3 { + public static final BoltProtocolVersion VERSION = new BoltProtocolVersion(4, 0); public static final BoltProtocol INSTANCE = new BoltProtocolV4(); @Override - public MessageFormat createMessageFormat() - { + public MessageFormat createMessageFormat() { return new MessageFormatV4(); } @Override - protected ResultCursorFactory buildResultCursorFactory( Connection connection, Query query, BookmarkHolder bookmarkHolder, - UnmanagedTransaction tx, RunWithMetadataMessage runMessage, long fetchSize ) - { + protected ResultCursorFactory buildResultCursorFactory( + Connection connection, + Query query, + BookmarkHolder bookmarkHolder, + UnmanagedTransaction tx, + RunWithMetadataMessage runMessage, + long fetchSize) { CompletableFuture runFuture = new CompletableFuture<>(); - RunResponseHandler runHandler = new RunResponseHandler( runFuture, METADATA_EXTRACTOR, connection, tx ); + RunResponseHandler runHandler = new RunResponseHandler(runFuture, METADATA_EXTRACTOR, connection, tx); - PullAllResponseHandler pullAllHandler = newBoltV4AutoPullHandler( query, runHandler, connection, bookmarkHolder, tx, fetchSize ); - PullResponseHandler pullHandler = newBoltV4BasicPullHandler( query, runHandler, connection, bookmarkHolder, tx ); + PullAllResponseHandler pullAllHandler = + newBoltV4AutoPullHandler(query, runHandler, connection, bookmarkHolder, tx, fetchSize); + PullResponseHandler pullHandler = newBoltV4BasicPullHandler(query, runHandler, connection, bookmarkHolder, tx); - return new ResultCursorFactoryImpl( connection, runMessage, runHandler, runFuture, pullHandler, pullAllHandler ); + return new ResultCursorFactoryImpl(connection, runMessage, runHandler, runFuture, pullHandler, pullAllHandler); } @Override - protected void verifyDatabaseNameBeforeTransaction( DatabaseName databaseName ) - { + protected void verifyDatabaseNameBeforeTransaction(DatabaseName databaseName) { // Bolt V4 accepts database name } @Override - public BoltProtocolVersion version() - { + public BoltProtocolVersion version() { return VERSION; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/MessageFormatV4.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/MessageFormatV4.java index c93c80f3bc..117b81dc31 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/MessageFormatV4.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/MessageFormatV4.java @@ -23,17 +23,14 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -public class MessageFormatV4 implements MessageFormat -{ +public class MessageFormatV4 implements MessageFormat { @Override - public Writer newWriter( PackOutput output ) - { - return new MessageWriterV4( output ); + public Writer newWriter(PackOutput output) { + return new MessageWriterV4(output); } @Override - public Reader newReader( PackInput input ) - { - return new CommonMessageReader( input ); + public Reader newReader(PackInput input) { + return new CommonMessageReader(input); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4.java index c30ad18aa4..429d09583a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.messaging.v4; import java.util.Map; - import org.neo4j.driver.internal.messaging.AbstractMessageWriter; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.common.CommonValuePacker; @@ -44,28 +43,25 @@ import org.neo4j.driver.internal.packstream.PackOutput; import org.neo4j.driver.internal.util.Iterables; -public class MessageWriterV4 extends AbstractMessageWriter -{ - public MessageWriterV4( PackOutput output ) - { - super( new CommonValuePacker( output ), buildEncoders() ); +public class MessageWriterV4 extends AbstractMessageWriter { + public MessageWriterV4(PackOutput output) { + super(new CommonValuePacker(output), buildEncoders()); } - private static Map buildEncoders() - { - Map result = Iterables.newHashMapWithSize( 9 ); - result.put( HelloMessage.SIGNATURE, new HelloMessageEncoder() ); - result.put( GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder() ); - result.put( RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder() ); + private static Map buildEncoders() { + Map result = Iterables.newHashMapWithSize(9); + result.put(HelloMessage.SIGNATURE, new HelloMessageEncoder()); + result.put(GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder()); + result.put(RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder()); - result.put( DiscardMessage.SIGNATURE, new DiscardMessageEncoder() ); // new - result.put( PullMessage.SIGNATURE, new PullMessageEncoder() ); // new + result.put(DiscardMessage.SIGNATURE, new DiscardMessageEncoder()); // new + result.put(PullMessage.SIGNATURE, new PullMessageEncoder()); // new - result.put( BeginMessage.SIGNATURE, new BeginMessageEncoder() ); - result.put( CommitMessage.SIGNATURE, new CommitMessageEncoder() ); - result.put( RollbackMessage.SIGNATURE, new RollbackMessageEncoder() ); + result.put(BeginMessage.SIGNATURE, new BeginMessageEncoder()); + result.put(CommitMessage.SIGNATURE, new CommitMessageEncoder()); + result.put(RollbackMessage.SIGNATURE, new RollbackMessageEncoder()); - result.put( ResetMessage.SIGNATURE, new ResetMessageEncoder() ); + result.put(ResetMessage.SIGNATURE, new ResetMessageEncoder()); return result; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41.java index cd86cfbe9f..4700c76c23 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41.java @@ -18,8 +18,10 @@ */ package org.neo4j.driver.internal.messaging.v41; -import java.util.concurrent.CompletableFuture; +import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV4AutoPullHandler; +import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV4BasicPullHandler; +import java.util.concurrent.CompletableFuture; import org.neo4j.driver.Query; import org.neo4j.driver.internal.BookmarkHolder; import org.neo4j.driver.internal.DatabaseName; @@ -37,42 +39,40 @@ import org.neo4j.driver.internal.messaging.v4.MessageFormatV4; import org.neo4j.driver.internal.spi.Connection; -import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV4AutoPullHandler; -import static org.neo4j.driver.internal.handlers.PullHandlers.newBoltV4BasicPullHandler; - -public class BoltProtocolV41 extends BoltProtocolV4 -{ - public static final BoltProtocolVersion VERSION = new BoltProtocolVersion( 4, 1 ); +public class BoltProtocolV41 extends BoltProtocolV4 { + public static final BoltProtocolVersion VERSION = new BoltProtocolVersion(4, 1); public static final BoltProtocol INSTANCE = new BoltProtocolV41(); @Override - public MessageFormat createMessageFormat() - { + public MessageFormat createMessageFormat() { return new MessageFormatV4(); } @Override - protected ResultCursorFactory buildResultCursorFactory( Connection connection, Query query, BookmarkHolder bookmarkHolder, - UnmanagedTransaction tx, RunWithMetadataMessage runMessage, long fetchSize ) - { + protected ResultCursorFactory buildResultCursorFactory( + Connection connection, + Query query, + BookmarkHolder bookmarkHolder, + UnmanagedTransaction tx, + RunWithMetadataMessage runMessage, + long fetchSize) { CompletableFuture runFuture = new CompletableFuture<>(); - RunResponseHandler runHandler = new RunResponseHandler( runFuture, METADATA_EXTRACTOR, connection, tx ); + RunResponseHandler runHandler = new RunResponseHandler(runFuture, METADATA_EXTRACTOR, connection, tx); - PullAllResponseHandler pullAllHandler = newBoltV4AutoPullHandler( query, runHandler, connection, bookmarkHolder, tx, fetchSize ); - PullResponseHandler pullHandler = newBoltV4BasicPullHandler( query, runHandler, connection, bookmarkHolder, tx ); + PullAllResponseHandler pullAllHandler = + newBoltV4AutoPullHandler(query, runHandler, connection, bookmarkHolder, tx, fetchSize); + PullResponseHandler pullHandler = newBoltV4BasicPullHandler(query, runHandler, connection, bookmarkHolder, tx); - return new ResultCursorFactoryImpl( connection, runMessage, runHandler, runFuture, pullHandler, pullAllHandler ); + return new ResultCursorFactoryImpl(connection, runMessage, runHandler, runFuture, pullHandler, pullAllHandler); } @Override - protected void verifyDatabaseNameBeforeTransaction( DatabaseName databaseName ) - { + protected void verifyDatabaseNameBeforeTransaction(DatabaseName databaseName) { // Bolt V4.1 accepts database name } @Override - public BoltProtocolVersion version() - { + public BoltProtocolVersion version() { return VERSION; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42.java index d483573f10..257f59d8bf 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42.java @@ -25,14 +25,12 @@ /** * Bolt V4.2 is identical to V4.1 */ -public class BoltProtocolV42 extends BoltProtocolV41 -{ - public static final BoltProtocolVersion VERSION = new BoltProtocolVersion( 4, 2 ); +public class BoltProtocolV42 extends BoltProtocolV41 { + public static final BoltProtocolVersion VERSION = new BoltProtocolVersion(4, 2); public static final BoltProtocol INSTANCE = new BoltProtocolV42(); @Override - public BoltProtocolVersion version() - { + public BoltProtocolVersion version() { return VERSION; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43.java index 3fc74b23fa..85623c8713 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43.java @@ -28,20 +28,17 @@ * * The version 4.3 use most of the 4.2 behaviours, but it extends it with new messages such as ROUTE */ -public class BoltProtocolV43 extends BoltProtocolV42 -{ - public static final BoltProtocolVersion VERSION = new BoltProtocolVersion( 4, 3 ); +public class BoltProtocolV43 extends BoltProtocolV42 { + public static final BoltProtocolVersion VERSION = new BoltProtocolVersion(4, 3); public static final BoltProtocol INSTANCE = new BoltProtocolV43(); @Override - public MessageFormat createMessageFormat() - { + public MessageFormat createMessageFormat() { return new MessageFormatV43(); } @Override - public BoltProtocolVersion version() - { + public BoltProtocolVersion version() { return VERSION; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/MessageFormatV43.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/MessageFormatV43.java index bd6f7d6a70..6424e760b9 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/MessageFormatV43.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/MessageFormatV43.java @@ -26,17 +26,14 @@ /** * Bolt message format v4.3 */ -public class MessageFormatV43 implements MessageFormat -{ +public class MessageFormatV43 implements MessageFormat { @Override - public Writer newWriter( PackOutput output ) - { - return new MessageWriterV43( output ); + public Writer newWriter(PackOutput output) { + return new MessageWriterV43(output); } @Override - public Reader newReader( PackInput input ) - { - return new CommonMessageReader( input ); + public Reader newReader(PackInput input) { + return new CommonMessageReader(input); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43.java index fb477ea80c..f52eee3a60 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.messaging.v43; import java.util.Map; - import org.neo4j.driver.internal.messaging.AbstractMessageWriter; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.common.CommonValuePacker; @@ -52,29 +51,26 @@ * This version is able to encode all the versions existing on v4.2, but it encodes * new messages such as ROUTE */ -public class MessageWriterV43 extends AbstractMessageWriter -{ - public MessageWriterV43( PackOutput output ) - { - super( new CommonValuePacker( output ), buildEncoders() ); +public class MessageWriterV43 extends AbstractMessageWriter { + public MessageWriterV43(PackOutput output) { + super(new CommonValuePacker(output), buildEncoders()); } - private static Map buildEncoders() - { - Map result = Iterables.newHashMapWithSize( 9 ); - result.put( HelloMessage.SIGNATURE, new HelloMessageEncoder() ); - result.put( GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder() ); - result.put( RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder() ); - result.put( RouteMessage.SIGNATURE, new RouteMessageEncoder() ); // new + private static Map buildEncoders() { + Map result = Iterables.newHashMapWithSize(9); + result.put(HelloMessage.SIGNATURE, new HelloMessageEncoder()); + result.put(GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder()); + result.put(RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder()); + result.put(RouteMessage.SIGNATURE, new RouteMessageEncoder()); // new - result.put( DiscardMessage.SIGNATURE, new DiscardMessageEncoder() ); - result.put( PullMessage.SIGNATURE, new PullMessageEncoder() ); + result.put(DiscardMessage.SIGNATURE, new DiscardMessageEncoder()); + result.put(PullMessage.SIGNATURE, new PullMessageEncoder()); - result.put( BeginMessage.SIGNATURE, new BeginMessageEncoder() ); - result.put( CommitMessage.SIGNATURE, new CommitMessageEncoder() ); - result.put( RollbackMessage.SIGNATURE, new RollbackMessageEncoder() ); + result.put(BeginMessage.SIGNATURE, new BeginMessageEncoder()); + result.put(CommitMessage.SIGNATURE, new CommitMessageEncoder()); + result.put(RollbackMessage.SIGNATURE, new RollbackMessageEncoder()); - result.put( ResetMessage.SIGNATURE, new ResetMessageEncoder() ); + result.put(ResetMessage.SIGNATURE, new ResetMessageEncoder()); return result; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44.java index 735c2676db..7906414ee5 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44.java @@ -26,20 +26,17 @@ /** * Definition of the Bolt Protocol 4.4 */ -public class BoltProtocolV44 extends BoltProtocolV43 -{ - public static final BoltProtocolVersion VERSION = new BoltProtocolVersion( 4, 4 ); +public class BoltProtocolV44 extends BoltProtocolV43 { + public static final BoltProtocolVersion VERSION = new BoltProtocolVersion(4, 4); public static final BoltProtocol INSTANCE = new BoltProtocolV44(); @Override - public MessageFormat createMessageFormat() - { + public MessageFormat createMessageFormat() { return new MessageFormatV44(); } @Override - public BoltProtocolVersion version() - { + public BoltProtocolVersion version() { return VERSION; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/MessageFormatV44.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/MessageFormatV44.java index 7bca125094..0a980494e6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/MessageFormatV44.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/MessageFormatV44.java @@ -26,17 +26,14 @@ /** * Bolt message format v4.4 */ -public class MessageFormatV44 implements MessageFormat -{ +public class MessageFormatV44 implements MessageFormat { @Override - public MessageFormat.Writer newWriter( PackOutput output ) - { - return new MessageWriterV44( output ); + public MessageFormat.Writer newWriter(PackOutput output) { + return new MessageWriterV44(output); } @Override - public MessageFormat.Reader newReader( PackInput input ) - { - return new CommonMessageReader( input ); + public MessageFormat.Reader newReader(PackInput input) { + return new CommonMessageReader(input); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44.java index 4731da297b..1563323d7e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.messaging.v44; import java.util.Map; - import org.neo4j.driver.internal.messaging.AbstractMessageWriter; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.common.CommonValuePacker; @@ -49,29 +48,26 @@ /** * Bolt message writer v4.4 */ -public class MessageWriterV44 extends AbstractMessageWriter -{ - public MessageWriterV44( PackOutput output ) - { - super( new CommonValuePacker( output ), buildEncoders() ); +public class MessageWriterV44 extends AbstractMessageWriter { + public MessageWriterV44(PackOutput output) { + super(new CommonValuePacker(output), buildEncoders()); } - private static Map buildEncoders() - { - Map result = Iterables.newHashMapWithSize( 9 ); - result.put( HelloMessage.SIGNATURE, new HelloMessageEncoder() ); - result.put( GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder() ); - result.put( RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder() ); - result.put( RouteMessage.SIGNATURE, new RouteV44MessageEncoder() ); + private static Map buildEncoders() { + Map result = Iterables.newHashMapWithSize(9); + result.put(HelloMessage.SIGNATURE, new HelloMessageEncoder()); + result.put(GoodbyeMessage.SIGNATURE, new GoodbyeMessageEncoder()); + result.put(RunWithMetadataMessage.SIGNATURE, new RunWithMetadataMessageEncoder()); + result.put(RouteMessage.SIGNATURE, new RouteV44MessageEncoder()); - result.put( DiscardMessage.SIGNATURE, new DiscardMessageEncoder() ); - result.put( PullMessage.SIGNATURE, new PullMessageEncoder() ); + result.put(DiscardMessage.SIGNATURE, new DiscardMessageEncoder()); + result.put(PullMessage.SIGNATURE, new PullMessageEncoder()); - result.put( BeginMessage.SIGNATURE, new BeginMessageEncoder() ); - result.put( CommitMessage.SIGNATURE, new CommitMessageEncoder() ); - result.put( RollbackMessage.SIGNATURE, new RollbackMessageEncoder() ); + result.put(BeginMessage.SIGNATURE, new BeginMessageEncoder()); + result.put(CommitMessage.SIGNATURE, new CommitMessageEncoder()); + result.put(RollbackMessage.SIGNATURE, new RollbackMessageEncoder()); - result.put( ResetMessage.SIGNATURE, new ResetMessageEncoder() ); + result.put(ResetMessage.SIGNATURE, new ResetMessageEncoder()); return result; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionPoolMetricsListener.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionPoolMetricsListener.java index 3ca86713f6..b21ac24d8b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionPoolMetricsListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/ConnectionPoolMetricsListener.java @@ -18,17 +18,16 @@ */ package org.neo4j.driver.internal.metrics; -interface ConnectionPoolMetricsListener -{ +interface ConnectionPoolMetricsListener { /** * Invoked before a connection is creating. */ - void beforeCreating( ListenerEvent listenerEvent ); + void beforeCreating(ListenerEvent listenerEvent); /** * Invoked after a connection is created successfully. */ - void afterCreated( ListenerEvent listenerEvent ); + void afterCreated(ListenerEvent listenerEvent); /** * Invoked after a connection is failed to create due to timeout, any kind of error. @@ -45,7 +44,7 @@ interface ConnectionPoolMetricsListener * * @param acquireEvent */ - void beforeAcquiringOrCreating( ListenerEvent acquireEvent ); + void beforeAcquiringOrCreating(ListenerEvent acquireEvent); /** * Invoked after a connection is being acquired or created regardless weather it is successful or not. @@ -57,7 +56,7 @@ interface ConnectionPoolMetricsListener * * @param acquireEvent */ - void afterAcquiredOrCreated( ListenerEvent acquireEvent ); + void afterAcquiredOrCreated(ListenerEvent acquireEvent); /** * Invoked after it is timed out to acquire or create a connection. @@ -69,13 +68,12 @@ interface ConnectionPoolMetricsListener * * @param inUseEvent */ - void acquired( ListenerEvent inUseEvent ); + void acquired(ListenerEvent inUseEvent); /** * After a connection is released back to pool. * * @param inUseEvent */ - void released( ListenerEvent inUseEvent ); + void released(ListenerEvent inUseEvent); } - diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullListenerEvent.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullListenerEvent.java index 6c17eab971..c96823f7cb 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullListenerEvent.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullListenerEvent.java @@ -18,18 +18,14 @@ */ package org.neo4j.driver.internal.metrics; -enum DevNullListenerEvent implements ListenerEvent -{ +enum DevNullListenerEvent implements ListenerEvent { INSTANCE; @Override - public void start() - { - } + public void start() {} @Override - public Long getSample() - { + public Long getSample() { return 0L; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullMetricsListener.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullMetricsListener.java index 4915906800..bf9730fb75 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullMetricsListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullMetricsListener.java @@ -19,82 +19,55 @@ package org.neo4j.driver.internal.metrics; import java.util.function.IntSupplier; - import org.neo4j.driver.net.ServerAddress; -public enum DevNullMetricsListener implements MetricsListener -{ +public enum DevNullMetricsListener implements MetricsListener { INSTANCE; @Override - public void beforeCreating( String poolId, ListenerEvent creatingEvent ) - { - } + public void beforeCreating(String poolId, ListenerEvent creatingEvent) {} @Override - public void afterCreated( String poolId, ListenerEvent creatingEvent ) - { - } + public void afterCreated(String poolId, ListenerEvent creatingEvent) {} @Override - public void afterFailedToCreate( String poolId ) - { - } + public void afterFailedToCreate(String poolId) {} @Override - public void afterClosed( String poolId ) - { - } + public void afterClosed(String poolId) {} @Override - public void beforeAcquiringOrCreating( String poolId, ListenerEvent acquireEvent ) - { - } + public void beforeAcquiringOrCreating(String poolId, ListenerEvent acquireEvent) {} @Override - public void afterAcquiringOrCreating( String poolId ) - { - } + public void afterAcquiringOrCreating(String poolId) {} @Override - public void afterAcquiredOrCreated( String poolId, ListenerEvent acquireEvent ) - { - } + public void afterAcquiredOrCreated(String poolId, ListenerEvent acquireEvent) {} @Override - public void afterTimedOutToAcquireOrCreate( String poolId ) - { - } + public void afterTimedOutToAcquireOrCreate(String poolId) {} @Override - public void afterConnectionCreated( String poolId, ListenerEvent inUseEvent ) - { - } + public void afterConnectionCreated(String poolId, ListenerEvent inUseEvent) {} @Override - public void afterConnectionReleased( String poolId, ListenerEvent inUseEvent ) - { - } + public void afterConnectionReleased(String poolId, ListenerEvent inUseEvent) {} @Override - public ListenerEvent createListenerEvent() - { + public ListenerEvent createListenerEvent() { return DevNullListenerEvent.INSTANCE; } @Override - public void registerPoolMetrics( String poolId, ServerAddress serverAddress, IntSupplier inUseSupplier, IntSupplier idleSupplier ) - { - } + public void registerPoolMetrics( + String poolId, ServerAddress serverAddress, IntSupplier inUseSupplier, IntSupplier idleSupplier) {} @Override - public void removePoolMetrics( String poolId ) - { - } + public void removePoolMetrics(String poolId) {} @Override - public String toString() - { + public String toString() { return "Driver metrics are not available if they are not enabled."; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullMetricsProvider.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullMetricsProvider.java index 3cf250cb4d..e587f488d8 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullMetricsProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullMetricsProvider.java @@ -21,21 +21,18 @@ import org.neo4j.driver.Metrics; import org.neo4j.driver.exceptions.ClientException; -public enum DevNullMetricsProvider implements MetricsProvider -{ +public enum DevNullMetricsProvider implements MetricsProvider { INSTANCE; @Override - public Metrics metrics() - { + public Metrics metrics() { // To outside users, we forbid access to the metrics API throw new ClientException( - "Driver metrics are not enabled. You need to enable driver metrics in driver configuration in order to access them." ); + "Driver metrics are not enabled. You need to enable driver metrics in driver configuration in order to access them."); } @Override - public MetricsListener metricsListener() - { + public MetricsListener metricsListener() { // Internally we can still register callbacks to this empty metrics listener. return DevNullMetricsListener.INSTANCE; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullPoolMetricsListener.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullPoolMetricsListener.java index 3d4dcc74e6..25e9a54b3a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullPoolMetricsListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/DevNullPoolMetricsListener.java @@ -18,57 +18,36 @@ */ package org.neo4j.driver.internal.metrics; -enum DevNullPoolMetricsListener implements ConnectionPoolMetricsListener -{ +enum DevNullPoolMetricsListener implements ConnectionPoolMetricsListener { INSTANCE; @Override - public void beforeCreating( ListenerEvent listenerEvent ) - { - } + public void beforeCreating(ListenerEvent listenerEvent) {} @Override - public void afterCreated( ListenerEvent listenerEvent ) - { - } + public void afterCreated(ListenerEvent listenerEvent) {} @Override - public void afterFailedToCreate() - { - } + public void afterFailedToCreate() {} @Override - public void afterClosed() - { - } + public void afterClosed() {} @Override - public void beforeAcquiringOrCreating( ListenerEvent acquireEvent ) - { - } + public void beforeAcquiringOrCreating(ListenerEvent acquireEvent) {} @Override - public void afterAcquiringOrCreating() - { - } + public void afterAcquiringOrCreating() {} @Override - public void afterAcquiredOrCreated( ListenerEvent acquireEvent ) - { - } + public void afterAcquiredOrCreated(ListenerEvent acquireEvent) {} @Override - public void afterTimedOutToAcquireOrCreate() - { - } + public void afterTimedOutToAcquireOrCreate() {} @Override - public void acquired( ListenerEvent inUseEvent ) - { - } + public void acquired(ListenerEvent inUseEvent) {} @Override - public void released( ListenerEvent inUseEvent ) - { - } + public void released(ListenerEvent inUseEvent) {} } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java index ba9c80fef8..670083fb78 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java @@ -18,18 +18,16 @@ */ package org.neo4j.driver.internal.metrics; +import static java.lang.String.format; + import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.function.IntSupplier; - import org.neo4j.driver.ConnectionPoolMetrics; import org.neo4j.driver.net.ServerAddress; -import static java.lang.String.format; - -final class InternalConnectionPoolMetrics implements ConnectionPoolMetrics, ConnectionPoolMetricsListener -{ +final class InternalConnectionPoolMetrics implements ConnectionPoolMetrics, ConnectionPoolMetricsListener { private final ServerAddress address; private final IntSupplier inUseSupplier; private final IntSupplier idleSupplier; @@ -53,11 +51,11 @@ final class InternalConnectionPoolMetrics implements ConnectionPoolMetrics, Conn private final AtomicLong totalInUseCount = new AtomicLong(); private final String id; - InternalConnectionPoolMetrics( String poolId, ServerAddress address, IntSupplier inUseSupplier, IntSupplier idleSupplier ) - { - Objects.requireNonNull( address ); - Objects.requireNonNull( inUseSupplier ); - Objects.requireNonNull( idleSupplier ); + InternalConnectionPoolMetrics( + String poolId, ServerAddress address, IntSupplier inUseSupplier, IntSupplier idleSupplier) { + Objects.requireNonNull(address); + Objects.requireNonNull(inUseSupplier); + Objects.requireNonNull(idleSupplier); this.id = poolId; this.address = address; @@ -66,176 +64,162 @@ final class InternalConnectionPoolMetrics implements ConnectionPoolMetrics, Conn } @Override - public void beforeCreating( ListenerEvent connEvent ) - { + public void beforeCreating(ListenerEvent connEvent) { creating.incrementAndGet(); connEvent.start(); } @Override - public void afterFailedToCreate() - { + public void afterFailedToCreate() { failedToCreate.incrementAndGet(); creating.decrementAndGet(); } @Override - public void afterCreated( ListenerEvent connEvent ) - { + public void afterCreated(ListenerEvent connEvent) { created.incrementAndGet(); creating.decrementAndGet(); long sample = ((TimeRecorderListenerEvent) connEvent).getSample(); - totalConnectionTime.addAndGet( sample ); + totalConnectionTime.addAndGet(sample); } @Override - public void afterClosed() - { + public void afterClosed() { closed.incrementAndGet(); } @Override - public void beforeAcquiringOrCreating( ListenerEvent acquireEvent ) - { + public void beforeAcquiringOrCreating(ListenerEvent acquireEvent) { acquireEvent.start(); acquiring.incrementAndGet(); } @Override - public void afterAcquiringOrCreating() - { + public void afterAcquiringOrCreating() { acquiring.decrementAndGet(); } @Override - public void afterAcquiredOrCreated( ListenerEvent acquireEvent ) - { + public void afterAcquiredOrCreated(ListenerEvent acquireEvent) { acquired.incrementAndGet(); long sample = ((TimeRecorderListenerEvent) acquireEvent).getSample(); - totalAcquisitionTime.addAndGet( sample ); + totalAcquisitionTime.addAndGet(sample); } @Override - public void afterTimedOutToAcquireOrCreate() - { + public void afterTimedOutToAcquireOrCreate() { timedOutToAcquire.incrementAndGet(); } @Override - public void acquired( ListenerEvent inUseEvent ) - { + public void acquired(ListenerEvent inUseEvent) { inUseEvent.start(); } @Override - public void released( ListenerEvent inUseEvent ) - { + public void released(ListenerEvent inUseEvent) { totalInUseCount.incrementAndGet(); long sample = ((TimeRecorderListenerEvent) inUseEvent).getSample(); - totalInUseTime.addAndGet( sample ); + totalInUseTime.addAndGet(sample); } @Override - public String id() - { + public String id() { return this.id; } @Override - public int inUse() - { + public int inUse() { return inUseSupplier.getAsInt(); } @Override - public int idle() - { + public int idle() { return idleSupplier.getAsInt(); } @Override - public int creating() - { + public int creating() { return creating.get(); } @Override - public long created() - { + public long created() { return created.get(); } @Override - public long failedToCreate() - { + public long failedToCreate() { return failedToCreate.get(); } @Override - public long timedOutToAcquire() - { + public long timedOutToAcquire() { return timedOutToAcquire.get(); } @Override - public long totalAcquisitionTime() - { + public long totalAcquisitionTime() { return totalAcquisitionTime.get(); } @Override - public long totalConnectionTime() - { + public long totalConnectionTime() { return totalConnectionTime.get(); } @Override - public long totalInUseTime() - { + public long totalInUseTime() { return totalInUseTime.get(); } @Override - public long totalInUseCount() - { + public long totalInUseCount() { return totalInUseCount.get(); } @Override - public long closed() - { + public long closed() { return closed.get(); } @Override - public int acquiring() - { + public int acquiring() { return acquiring.get(); } @Override - public long acquired() - { + public long acquired() { return this.acquired.get(); } @Override - public String toString() - { - return format( "%s=[created=%s, closed=%s, creating=%s, failedToCreate=%s, acquiring=%s, acquired=%s, " + - "timedOutToAcquire=%s, inUse=%s, idle=%s, " + - "totalAcquisitionTime=%s, totalConnectionTime=%s, totalInUseTime=%s, totalInUseCount=%s]", - id(), created(), closed(), creating(), failedToCreate(), acquiring(), acquired(), - timedOutToAcquire(), inUse(), idle(), - totalAcquisitionTime(), totalConnectionTime(), totalInUseTime(), totalInUseCount() ); + public String toString() { + return format( + "%s=[created=%s, closed=%s, creating=%s, failedToCreate=%s, acquiring=%s, acquired=%s, " + + "timedOutToAcquire=%s, inUse=%s, idle=%s, " + + "totalAcquisitionTime=%s, totalConnectionTime=%s, totalInUseTime=%s, totalInUseCount=%s]", + id(), + created(), + closed(), + creating(), + failedToCreate(), + acquiring(), + acquired(), + timedOutToAcquire(), + inUse(), + idle(), + totalAcquisitionTime(), + totalConnectionTime(), + totalInUseTime(), + totalInUseCount()); } // This method is for testing purposes only - public ServerAddress getAddress() - { + public ServerAddress getAddress() { return address; } } 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 9cda445b71..266c0aa505 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 @@ -18,12 +18,14 @@ */ package org.neo4j.driver.internal.metrics; +import static java.lang.String.format; +import static java.util.Collections.unmodifiableCollection; + import java.util.Collection; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.function.IntSupplier; - import org.neo4j.driver.ConnectionPoolMetrics; import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; @@ -31,119 +33,100 @@ import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.net.ServerAddress; -import static java.lang.String.format; -import static java.util.Collections.unmodifiableCollection; - -final class InternalMetrics implements Metrics, MetricsListener -{ - private final Map connectionPoolMetrics; +final class InternalMetrics implements Metrics, MetricsListener { + private final Map connectionPoolMetrics; private final Clock clock; private final Logger log; - InternalMetrics( Clock clock, Logging logging ) - { - Objects.requireNonNull( clock ); + InternalMetrics(Clock clock, Logging logging) { + Objects.requireNonNull(clock); this.connectionPoolMetrics = new ConcurrentHashMap<>(); this.clock = clock; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); } @Override - public void registerPoolMetrics( String poolId, ServerAddress serverAddress, IntSupplier inUseSupplier, IntSupplier idleSupplier ) - { - this.connectionPoolMetrics.put( poolId, new InternalConnectionPoolMetrics( poolId, serverAddress, inUseSupplier, idleSupplier ) ); + public void registerPoolMetrics( + String poolId, ServerAddress serverAddress, IntSupplier inUseSupplier, IntSupplier idleSupplier) { + this.connectionPoolMetrics.put( + poolId, new InternalConnectionPoolMetrics(poolId, serverAddress, inUseSupplier, idleSupplier)); } @Override - public void removePoolMetrics( String id ) - { - this.connectionPoolMetrics.remove( id ); + public void removePoolMetrics(String id) { + this.connectionPoolMetrics.remove(id); } @Override - public void beforeCreating( String poolId, ListenerEvent creatingEvent ) - { - poolMetrics( poolId ).beforeCreating( creatingEvent ); + public void beforeCreating(String poolId, ListenerEvent creatingEvent) { + poolMetrics(poolId).beforeCreating(creatingEvent); } @Override - public void afterCreated( String poolId, ListenerEvent creatingEvent ) - { - poolMetrics( poolId ).afterCreated( creatingEvent ); + public void afterCreated(String poolId, ListenerEvent creatingEvent) { + poolMetrics(poolId).afterCreated(creatingEvent); } @Override - public void afterFailedToCreate( String poolId ) - { - poolMetrics( poolId ).afterFailedToCreate(); + public void afterFailedToCreate(String poolId) { + poolMetrics(poolId).afterFailedToCreate(); } @Override - public void afterClosed( String poolId ) - { - poolMetrics( poolId ).afterClosed(); + public void afterClosed(String poolId) { + poolMetrics(poolId).afterClosed(); } @Override - public void beforeAcquiringOrCreating( String poolId, ListenerEvent acquireEvent ) - { - poolMetrics( poolId ).beforeAcquiringOrCreating( acquireEvent ); + public void beforeAcquiringOrCreating(String poolId, ListenerEvent acquireEvent) { + poolMetrics(poolId).beforeAcquiringOrCreating(acquireEvent); } @Override - public void afterAcquiringOrCreating( String poolId ) - { - poolMetrics( poolId ).afterAcquiringOrCreating(); + public void afterAcquiringOrCreating(String poolId) { + poolMetrics(poolId).afterAcquiringOrCreating(); } @Override - public void afterAcquiredOrCreated( String poolId, ListenerEvent acquireEvent ) - { - poolMetrics( poolId ).afterAcquiredOrCreated( acquireEvent ); + public void afterAcquiredOrCreated(String poolId, ListenerEvent acquireEvent) { + poolMetrics(poolId).afterAcquiredOrCreated(acquireEvent); } @Override - public void afterConnectionCreated( String poolId, ListenerEvent inUseEvent ) - { - poolMetrics( poolId ).acquired( inUseEvent ); + public void afterConnectionCreated(String poolId, ListenerEvent inUseEvent) { + poolMetrics(poolId).acquired(inUseEvent); } @Override - public void afterConnectionReleased( String poolId, ListenerEvent inUseEvent ) - { - poolMetrics( poolId ).released( inUseEvent ); + public void afterConnectionReleased(String poolId, ListenerEvent inUseEvent) { + poolMetrics(poolId).released(inUseEvent); } @Override - public void afterTimedOutToAcquireOrCreate( String poolId ) - { - poolMetrics( poolId ).afterTimedOutToAcquireOrCreate(); + public void afterTimedOutToAcquireOrCreate(String poolId) { + poolMetrics(poolId).afterTimedOutToAcquireOrCreate(); } @Override - public ListenerEvent createListenerEvent() - { - return new TimeRecorderListenerEvent( clock ); + public ListenerEvent createListenerEvent() { + return new TimeRecorderListenerEvent(clock); } @Override - public Collection connectionPoolMetrics() - { - return unmodifiableCollection( this.connectionPoolMetrics.values() ); + public Collection connectionPoolMetrics() { + return unmodifiableCollection(this.connectionPoolMetrics.values()); } @Override - public String toString() - { - return format( "PoolMetrics=%s", connectionPoolMetrics ); + public String toString() { + return format("PoolMetrics=%s", connectionPoolMetrics); } - private ConnectionPoolMetricsListener poolMetrics( String poolId ) - { - InternalConnectionPoolMetrics poolMetrics = (InternalConnectionPoolMetrics) this.connectionPoolMetrics.get( poolId ); - if ( poolMetrics == null ) - { - log.warn( format( "Failed to find pool metrics with id `%s` in %s.", poolId, this.connectionPoolMetrics ) ); + private ConnectionPoolMetricsListener poolMetrics(String poolId) { + InternalConnectionPoolMetrics poolMetrics = + (InternalConnectionPoolMetrics) this.connectionPoolMetrics.get(poolId); + if (poolMetrics == null) { + log.warn(format("Failed to find pool metrics with id `%s` in %s.", poolId, this.connectionPoolMetrics)); return DevNullPoolMetricsListener.INSTANCE; } return poolMetrics; 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 0980dbf218..64204831f4 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 @@ -19,27 +19,23 @@ package org.neo4j.driver.internal.metrics; import org.neo4j.driver.Logging; -import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.Metrics; +import org.neo4j.driver.internal.util.Clock; -public final class InternalMetricsProvider implements MetricsProvider -{ +public final class InternalMetricsProvider implements MetricsProvider { private final InternalMetrics metrics; - public InternalMetricsProvider( Clock clock, Logging logging ) - { - this.metrics = new InternalMetrics( clock, logging ); + public InternalMetricsProvider(Clock clock, Logging logging) { + this.metrics = new InternalMetrics(clock, logging); } @Override - public Metrics metrics() - { + public Metrics metrics() { return metrics; } @Override - public MetricsListener metricsListener() - { + public MetricsListener metricsListener() { return metrics; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/ListenerEvent.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/ListenerEvent.java index 543ee0e723..cb777a638e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/ListenerEvent.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/ListenerEvent.java @@ -18,10 +18,8 @@ */ package org.neo4j.driver.internal.metrics; -public interface ListenerEvent -{ +public interface ListenerEvent { void start(); T getSample(); } - diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsListener.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsListener.java index 48e5710b2a..5a828e6027 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsListener.java @@ -20,38 +20,36 @@ import java.util.concurrent.TimeUnit; import java.util.function.IntSupplier; - import org.neo4j.driver.Config; import org.neo4j.driver.net.ServerAddress; -public interface MetricsListener -{ +public interface MetricsListener { /** * Before creating a netty channel. * * @param poolId the id of the pool where the netty channel lives. * @param creatingEvent a connection listener event registered when a connection is creating. */ - void beforeCreating( String poolId, ListenerEvent creatingEvent ); + void beforeCreating(String poolId, ListenerEvent creatingEvent); /** * After a netty channel is created successfully. * * @param poolId the id of the pool where the netty channel lives. */ - void afterCreated( String poolId, ListenerEvent creatingEvent ); + void afterCreated(String poolId, ListenerEvent creatingEvent); /** * After a netty channel is created with a failure. * @param poolId the id of the pool where the netty channel lives. */ - void afterFailedToCreate( String poolId ); + void afterFailedToCreate(String poolId); /** * After a netty channel is closed successfully. * @param poolId the id of the pool where the netty channel lives. */ - void afterClosed( String poolId ); + void afterClosed(String poolId); /** * Before acquiring or creating a new netty channel from pool. @@ -59,13 +57,13 @@ public interface MetricsListener * @param poolId the id of the pool where the netty channel lives. * @param acquireEvent a pool listener event registered in pool for this acquire event. */ - void beforeAcquiringOrCreating( String poolId, ListenerEvent acquireEvent ); + void beforeAcquiringOrCreating(String poolId, ListenerEvent acquireEvent); /** * After acquiring or creating a new netty channel from pool regardless it is successful or not. * @param poolId the id of the pool where the netty channel lives. */ - void afterAcquiringOrCreating( String poolId ); + void afterAcquiringOrCreating(String poolId); /** * After acquiring or creating a new netty channel from pool successfully. @@ -73,14 +71,14 @@ public interface MetricsListener * @param poolId the id of the pool where the netty channel lives. * @param acquireEvent a pool listener event registered in pool for this acquire event. */ - void afterAcquiredOrCreated( String poolId, ListenerEvent acquireEvent ); + void afterAcquiredOrCreated(String poolId, ListenerEvent acquireEvent); /** * After we failed to acquire a connection from pool within maximum connection acquisition timeout set by * {@link Config.ConfigBuilder#withConnectionAcquisitionTimeout(long, TimeUnit)}. * @param poolId the id of the pool where the netty channel lives. */ - void afterTimedOutToAcquireOrCreate( String poolId ); + void afterTimedOutToAcquireOrCreate(String poolId); /** * After acquiring or creating a new netty channel from pool successfully. @@ -88,7 +86,7 @@ public interface MetricsListener * @param poolId the id of the pool where the netty channel lives. * @param inUseEvent a connection listener event fired from the newly created connection. */ - void afterConnectionCreated( String poolId, ListenerEvent inUseEvent ); + void afterConnectionCreated(String poolId, ListenerEvent inUseEvent); /** * After releasing a netty channel back to pool successfully. @@ -96,11 +94,12 @@ public interface MetricsListener * @param poolId the id of the pool where the netty channel lives. * @param inUseEvent a connection listener event fired from the connection being released. */ - void afterConnectionReleased( String poolId, ListenerEvent inUseEvent ); + void afterConnectionReleased(String poolId, ListenerEvent inUseEvent); ListenerEvent createListenerEvent(); - void registerPoolMetrics( String poolId, ServerAddress serverAddress, IntSupplier inUseSupplier, IntSupplier idleSupplier ); + void registerPoolMetrics( + String poolId, ServerAddress serverAddress, IntSupplier inUseSupplier, IntSupplier idleSupplier); - void removePoolMetrics( String poolId ); + void removePoolMetrics(String poolId); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsProvider.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsProvider.java index a2cfb5e1b7..c416237625 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/MetricsProvider.java @@ -23,8 +23,7 @@ /** * An adapter that collects driver metrics via {@link MetricsListener} and publishes them via {@link Metrics} instance. */ -public interface MetricsProvider -{ +public interface MetricsProvider { /** * @return The actual metrics type to use */ diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerConnectionPoolMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerConnectionPoolMetrics.java index 0e53c15f3b..12429c484d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerConnectionPoolMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerConnectionPoolMetrics.java @@ -18,26 +18,23 @@ */ package org.neo4j.driver.internal.metrics; +import static java.lang.String.format; + import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.Timer; - import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.IntSupplier; - import org.neo4j.driver.ConnectionPoolMetrics; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.net.ServerAddress; -import static java.lang.String.format; - -final class MicrometerConnectionPoolMetrics implements ConnectionPoolMetricsListener, ConnectionPoolMetrics -{ +final class MicrometerConnectionPoolMetrics implements ConnectionPoolMetricsListener, ConnectionPoolMetrics { public static final String PREFIX = "neo4j.driver.connections"; public static final String IN_USE = PREFIX + ".in.use"; public static final String IDLE = PREFIX + ".idle"; @@ -64,202 +61,197 @@ final class MicrometerConnectionPoolMetrics implements ConnectionPoolMetricsList private final Timer totalConnectionTimer; private final Timer totalInUseTimer; - MicrometerConnectionPoolMetrics( String poolId, ServerAddress address, IntSupplier inUseSupplier, IntSupplier idleSupplier, MeterRegistry registry ) - { - this( poolId, address, inUseSupplier, idleSupplier, registry, Tags.empty() ); + MicrometerConnectionPoolMetrics( + String poolId, + ServerAddress address, + IntSupplier inUseSupplier, + IntSupplier idleSupplier, + MeterRegistry registry) { + this(poolId, address, inUseSupplier, idleSupplier, registry, Tags.empty()); } - MicrometerConnectionPoolMetrics( String poolId, ServerAddress address, IntSupplier inUseSupplier, IntSupplier idleSupplier, MeterRegistry registry, Iterable initialTags ) - { - Objects.requireNonNull( poolId ); - Objects.requireNonNull( address ); - Objects.requireNonNull( inUseSupplier ); - Objects.requireNonNull( idleSupplier ); - Objects.requireNonNull( registry ); + MicrometerConnectionPoolMetrics( + String poolId, + ServerAddress address, + IntSupplier inUseSupplier, + IntSupplier idleSupplier, + MeterRegistry registry, + Iterable initialTags) { + Objects.requireNonNull(poolId); + Objects.requireNonNull(address); + Objects.requireNonNull(inUseSupplier); + Objects.requireNonNull(idleSupplier); + Objects.requireNonNull(registry); this.id = poolId; this.inUseSupplier = inUseSupplier; this.idleSupplier = idleSupplier; - String host = address instanceof BoltServerAddress ? ((BoltServerAddress) address).connectionHost() : address.host(); - Iterable tags = Tags.concat( initialTags, - "address", String.format( "%s:%d", host, address.port() ) ); - - Gauge.builder( IN_USE, this::inUse ).tags( tags ).register( registry ); - Gauge.builder( IDLE, this::idle ).tags( tags ).register( registry ); - Gauge.builder( CREATING, creating, AtomicInteger::get ).tags( tags ).register( registry ); - failedToCreate = Counter.builder( FAILED ).tags( tags ).register( registry ); - closed = Counter.builder( CLOSED ).tags( tags ).register( registry ); - Gauge.builder( ACQUIRING, acquiring, AtomicInteger::get ).tags( tags ).register( registry ); - timedOutToAcquire = Counter.builder( ACQUISITION_TIMEOUT ).tags( tags ).register( registry ); - totalAcquisitionTimer = Timer.builder( ACQUISITION ).tags( tags ).register( registry ); - totalConnectionTimer = Timer.builder( CREATION ).tags( tags ).register( registry ); - totalInUseTimer = Timer.builder( USAGE ).tags( tags ).register( registry ); + String host = + address instanceof BoltServerAddress ? ((BoltServerAddress) address).connectionHost() : address.host(); + Iterable tags = Tags.concat(initialTags, "address", String.format("%s:%d", host, address.port())); + + Gauge.builder(IN_USE, this::inUse).tags(tags).register(registry); + Gauge.builder(IDLE, this::idle).tags(tags).register(registry); + Gauge.builder(CREATING, creating, AtomicInteger::get).tags(tags).register(registry); + failedToCreate = Counter.builder(FAILED).tags(tags).register(registry); + closed = Counter.builder(CLOSED).tags(tags).register(registry); + Gauge.builder(ACQUIRING, acquiring, AtomicInteger::get).tags(tags).register(registry); + timedOutToAcquire = Counter.builder(ACQUISITION_TIMEOUT).tags(tags).register(registry); + totalAcquisitionTimer = Timer.builder(ACQUISITION).tags(tags).register(registry); + totalConnectionTimer = Timer.builder(CREATION).tags(tags).register(registry); + totalInUseTimer = Timer.builder(USAGE).tags(tags).register(registry); } @Override - public void beforeCreating( ListenerEvent connEvent ) - { + public void beforeCreating(ListenerEvent connEvent) { creating.incrementAndGet(); connEvent.start(); } @Override - public void afterFailedToCreate() - { + public void afterFailedToCreate() { failedToCreate.increment(); creating.decrementAndGet(); } @Override - public void afterCreated( ListenerEvent connEvent ) - { + public void afterCreated(ListenerEvent connEvent) { creating.decrementAndGet(); Timer.Sample sample = ((MicrometerTimerListenerEvent) connEvent).getSample(); - sample.stop( totalConnectionTimer ); + sample.stop(totalConnectionTimer); } @Override - public void afterClosed() - { + public void afterClosed() { closed.increment(); } @Override - public void beforeAcquiringOrCreating( ListenerEvent acquireEvent ) - { + public void beforeAcquiringOrCreating(ListenerEvent acquireEvent) { acquireEvent.start(); acquiring.incrementAndGet(); } @Override - public void afterAcquiringOrCreating() - { + public void afterAcquiringOrCreating() { acquiring.decrementAndGet(); } @Override - public void afterAcquiredOrCreated( ListenerEvent acquireEvent ) - { + public void afterAcquiredOrCreated(ListenerEvent acquireEvent) { Timer.Sample sample = ((MicrometerTimerListenerEvent) acquireEvent).getSample(); - sample.stop( totalAcquisitionTimer ); + sample.stop(totalAcquisitionTimer); } @Override - public void afterTimedOutToAcquireOrCreate() - { + public void afterTimedOutToAcquireOrCreate() { timedOutToAcquire.increment(); } @Override - public void acquired( ListenerEvent inUseEvent ) - { + public void acquired(ListenerEvent inUseEvent) { inUseEvent.start(); } @Override - public void released( ListenerEvent inUseEvent ) - { + public void released(ListenerEvent inUseEvent) { Timer.Sample sample = ((MicrometerTimerListenerEvent) inUseEvent).getSample(); - sample.stop( totalInUseTimer ); + sample.stop(totalInUseTimer); } @Override - public String id() - { + public String id() { return this.id; } @Override - public int inUse() - { + public int inUse() { return inUseSupplier.getAsInt(); } @Override - public int idle() - { + public int idle() { return idleSupplier.getAsInt(); } @Override - public int creating() - { + public int creating() { return creating.get(); } @Override - public long created() - { + public long created() { return totalConnectionTimer.count(); } @Override - public long failedToCreate() - { - return count( failedToCreate ); + public long failedToCreate() { + return count(failedToCreate); } @Override - public long closed() - { - return count( closed ); + public long closed() { + return count(closed); } @Override - public int acquiring() - { + public int acquiring() { return acquiring.get(); } @Override - public long acquired() - { + public long acquired() { return totalAcquisitionTimer.count(); } @Override - public long timedOutToAcquire() - { - return count( timedOutToAcquire ); + public long timedOutToAcquire() { + return count(timedOutToAcquire); } @Override - public long totalAcquisitionTime() - { - return (long) totalAcquisitionTimer.totalTime( TimeUnit.MILLISECONDS ); + public long totalAcquisitionTime() { + return (long) totalAcquisitionTimer.totalTime(TimeUnit.MILLISECONDS); } @Override - public long totalConnectionTime() - { - return (long) totalConnectionTimer.totalTime( TimeUnit.MILLISECONDS ); + public long totalConnectionTime() { + return (long) totalConnectionTimer.totalTime(TimeUnit.MILLISECONDS); } @Override - public long totalInUseTime() - { - return (long) totalInUseTimer.totalTime( TimeUnit.MILLISECONDS ); + public long totalInUseTime() { + return (long) totalInUseTimer.totalTime(TimeUnit.MILLISECONDS); } @Override - public long totalInUseCount() - { + public long totalInUseCount() { return totalInUseTimer.count(); } @Override - public String toString() - { - return format( "%s=[created=%s, closed=%s, creating=%s, failedToCreate=%s, acquiring=%s, acquired=%s, " + - "timedOutToAcquire=%s, inUse=%s, idle=%s, " + - "totalAcquisitionTime=%s, totalConnectionTime=%s, totalInUseTime=%s, totalInUseCount=%s]", - id(), created(), closed(), creating(), failedToCreate(), acquiring(), acquired(), - timedOutToAcquire(), inUse(), idle(), - totalAcquisitionTime(), totalConnectionTime(), totalInUseTime(), totalInUseCount() ); + public String toString() { + return format( + "%s=[created=%s, closed=%s, creating=%s, failedToCreate=%s, acquiring=%s, acquired=%s, " + + "timedOutToAcquire=%s, inUse=%s, idle=%s, " + + "totalAcquisitionTime=%s, totalConnectionTime=%s, totalInUseTime=%s, totalInUseCount=%s]", + id(), + created(), + closed(), + creating(), + failedToCreate(), + acquiring(), + acquired(), + timedOutToAcquire(), + inUse(), + idle(), + totalAcquisitionTime(), + totalConnectionTime(), + totalInUseTime(), + totalInUseCount()); } - private long count( Counter counter ) - { + private long count(Counter counter) { return (long) counter.count(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerMetrics.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerMetrics.java index f3b4eaf134..8d064e5064 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerMetrics.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerMetrics.java @@ -19,123 +19,106 @@ package org.neo4j.driver.internal.metrics; import io.micrometer.core.instrument.MeterRegistry; - import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.IntSupplier; - import org.neo4j.driver.ConnectionPoolMetrics; import org.neo4j.driver.Metrics; import org.neo4j.driver.net.ServerAddress; -final class MicrometerMetrics implements Metrics, MetricsListener -{ +final class MicrometerMetrics implements Metrics, MetricsListener { private final MeterRegistry meterRegistry; - private final Map connectionPoolMetrics; + private final Map connectionPoolMetrics; - public MicrometerMetrics( MeterRegistry meterRegistry ) - { + public MicrometerMetrics(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; this.connectionPoolMetrics = new ConcurrentHashMap<>(); } @Override - public Collection connectionPoolMetrics() - { - return Collections.unmodifiableCollection( this.connectionPoolMetrics.values() ); + public Collection connectionPoolMetrics() { + return Collections.unmodifiableCollection(this.connectionPoolMetrics.values()); } @Override - public void beforeCreating( String poolId, ListenerEvent creatingEvent ) - { - poolMetricsListener( poolId ).beforeCreating( creatingEvent ); + public void beforeCreating(String poolId, ListenerEvent creatingEvent) { + poolMetricsListener(poolId).beforeCreating(creatingEvent); } @Override - public void afterCreated( String poolId, ListenerEvent creatingEvent ) - { - poolMetricsListener( poolId ).afterCreated( creatingEvent ); + public void afterCreated(String poolId, ListenerEvent creatingEvent) { + poolMetricsListener(poolId).afterCreated(creatingEvent); } @Override - public void afterFailedToCreate( String poolId ) - { - poolMetricsListener( poolId ).afterFailedToCreate(); + public void afterFailedToCreate(String poolId) { + poolMetricsListener(poolId).afterFailedToCreate(); } @Override - public void afterClosed( String poolId ) - { - poolMetricsListener( poolId ).afterClosed(); + public void afterClosed(String poolId) { + poolMetricsListener(poolId).afterClosed(); } @Override - public void beforeAcquiringOrCreating( String poolId, ListenerEvent acquireEvent ) - { - poolMetricsListener( poolId ).beforeAcquiringOrCreating( acquireEvent ); + public void beforeAcquiringOrCreating(String poolId, ListenerEvent acquireEvent) { + poolMetricsListener(poolId).beforeAcquiringOrCreating(acquireEvent); } @Override - public void afterAcquiringOrCreating( String poolId ) - { - poolMetricsListener( poolId ).afterAcquiringOrCreating(); + public void afterAcquiringOrCreating(String poolId) { + poolMetricsListener(poolId).afterAcquiringOrCreating(); } @Override - public void afterAcquiredOrCreated( String poolId, ListenerEvent acquireEvent ) - { - poolMetricsListener( poolId ).afterAcquiredOrCreated( acquireEvent ); + public void afterAcquiredOrCreated(String poolId, ListenerEvent acquireEvent) { + poolMetricsListener(poolId).afterAcquiredOrCreated(acquireEvent); } @Override - public void afterTimedOutToAcquireOrCreate( String poolId ) - { - poolMetricsListener( poolId ).afterTimedOutToAcquireOrCreate(); + public void afterTimedOutToAcquireOrCreate(String poolId) { + poolMetricsListener(poolId).afterTimedOutToAcquireOrCreate(); } @Override - public void afterConnectionCreated( String poolId, ListenerEvent inUseEvent ) - { - poolMetricsListener( poolId ).acquired( inUseEvent ); + public void afterConnectionCreated(String poolId, ListenerEvent inUseEvent) { + poolMetricsListener(poolId).acquired(inUseEvent); } @Override - public void afterConnectionReleased( String poolId, ListenerEvent inUseEvent ) - { - poolMetricsListener( poolId ).released( inUseEvent ); + public void afterConnectionReleased(String poolId, ListenerEvent inUseEvent) { + poolMetricsListener(poolId).released(inUseEvent); } @Override - public ListenerEvent createListenerEvent() - { - return new MicrometerTimerListenerEvent( this.meterRegistry ); + public ListenerEvent createListenerEvent() { + return new MicrometerTimerListenerEvent(this.meterRegistry); } @Override - public void registerPoolMetrics( String poolId, ServerAddress address, IntSupplier inUseSupplier, IntSupplier idleSupplier ) - { - this.connectionPoolMetrics.put( poolId, new MicrometerConnectionPoolMetrics( poolId, address, inUseSupplier, idleSupplier, this.meterRegistry ) ); + public void registerPoolMetrics( + String poolId, ServerAddress address, IntSupplier inUseSupplier, IntSupplier idleSupplier) { + this.connectionPoolMetrics.put( + poolId, + new MicrometerConnectionPoolMetrics(poolId, address, inUseSupplier, idleSupplier, this.meterRegistry)); } // For testing purposes only - void putPoolMetrics( String poolId, ConnectionPoolMetrics poolMetrics ) - { - this.connectionPoolMetrics.put( poolId, poolMetrics ); + void putPoolMetrics(String poolId, ConnectionPoolMetrics poolMetrics) { + this.connectionPoolMetrics.put(poolId, poolMetrics); } @Override - public void removePoolMetrics( String poolId ) - { - this.connectionPoolMetrics.remove( poolId ); + public void removePoolMetrics(String poolId) { + this.connectionPoolMetrics.remove(poolId); } - private ConnectionPoolMetricsListener poolMetricsListener( String poolId ) - { - ConnectionPoolMetricsListener poolMetrics = (ConnectionPoolMetricsListener) this.connectionPoolMetrics.get( poolId ); - if ( poolMetrics == null ) - { + private ConnectionPoolMetricsListener poolMetricsListener(String poolId) { + ConnectionPoolMetricsListener poolMetrics = + (ConnectionPoolMetricsListener) this.connectionPoolMetrics.get(poolId); + if (poolMetrics == null) { return DevNullPoolMetricsListener.INSTANCE; } return poolMetrics; diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerMetricsProvider.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerMetricsProvider.java index 3b766a6bfd..e954cf4f80 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerMetricsProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerMetricsProvider.java @@ -19,40 +19,33 @@ package org.neo4j.driver.internal.metrics; import io.micrometer.core.instrument.MeterRegistry; - import org.neo4j.driver.Metrics; /** * An adapter to bridge between driver metrics and Micrometer {@link MeterRegistry meter registry}. */ -public final class MicrometerMetricsProvider implements MetricsProvider -{ +public final class MicrometerMetricsProvider implements MetricsProvider { private final MicrometerMetrics metrics; - public static MetricsProvider forGlobalRegistry() - { - return of( io.micrometer.core.instrument.Metrics.globalRegistry ); + public static MetricsProvider forGlobalRegistry() { + return of(io.micrometer.core.instrument.Metrics.globalRegistry); } - public static MetricsProvider of( MeterRegistry meterRegistry ) - { - return new MicrometerMetricsProvider( meterRegistry ); + public static MetricsProvider of(MeterRegistry meterRegistry) { + return new MicrometerMetricsProvider(meterRegistry); } - private MicrometerMetricsProvider( MeterRegistry meterRegistry ) - { - this.metrics = new MicrometerMetrics( meterRegistry ); + private MicrometerMetricsProvider(MeterRegistry meterRegistry) { + this.metrics = new MicrometerMetrics(meterRegistry); } @Override - public Metrics metrics() - { + public Metrics metrics() { return this.metrics; } @Override - public MetricsListener metricsListener() - { + public MetricsListener metricsListener() { return this.metrics; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerTimerListenerEvent.java b/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerTimerListenerEvent.java index 9258666783..eb001b7109 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerTimerListenerEvent.java +++ b/driver/src/main/java/org/neo4j/driver/internal/metrics/MicrometerTimerListenerEvent.java @@ -21,25 +21,21 @@ import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; -final class MicrometerTimerListenerEvent implements ListenerEvent -{ +final class MicrometerTimerListenerEvent implements ListenerEvent { private final MeterRegistry meterRegistry; private Timer.Sample sample; - public MicrometerTimerListenerEvent( MeterRegistry meterRegistry ) - { + public MicrometerTimerListenerEvent(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; } @Override - public void start() - { - this.sample = Timer.start( this.meterRegistry ); + public void start() { + this.sample = Timer.start(this.meterRegistry); } @Override - public Timer.Sample getSample() - { + public Timer.Sample getSample() { return this.sample; } } 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 c286de7001..b7bd3c8e06 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 @@ -20,25 +20,21 @@ import org.neo4j.driver.internal.util.Clock; -final class TimeRecorderListenerEvent implements ListenerEvent -{ +final class TimeRecorderListenerEvent implements ListenerEvent { private final Clock clock; private long startTime; - TimeRecorderListenerEvent( Clock clock ) - { + TimeRecorderListenerEvent(Clock clock) { this.clock = clock; } @Override - public void start() - { + public void start() { startTime = clock.millis(); } @Override - public Long getSample() - { + public Long getSample() { return clock.millis() - startTime; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/packstream/ByteArrayIncompatiblePacker.java b/driver/src/main/java/org/neo4j/driver/internal/packstream/ByteArrayIncompatiblePacker.java index dfec7fd039..aa8a115eba 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/packstream/ByteArrayIncompatiblePacker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/packstream/ByteArrayIncompatiblePacker.java @@ -20,17 +20,14 @@ import java.io.IOException; -public class ByteArrayIncompatiblePacker extends PackStream.Packer -{ - public ByteArrayIncompatiblePacker( PackOutput out ) - { - super( out ); +public class ByteArrayIncompatiblePacker extends PackStream.Packer { + public ByteArrayIncompatiblePacker(PackOutput out) { + super(out); } @Override - public void packBytesHeader( int size ) throws IOException - { - throw new PackStream.UnPackable( "Packing bytes is not supported " + - "as the current server this driver connected to does not support unpack bytes." ); + public void packBytesHeader(int size) throws IOException { + throw new PackStream.UnPackable("Packing bytes is not supported " + + "as the current server this driver connected to does not support unpack bytes."); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/packstream/PackInput.java b/driver/src/main/java/org/neo4j/driver/internal/packstream/PackInput.java index a9532c509e..6c718f0ddf 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/packstream/PackInput.java +++ b/driver/src/main/java/org/neo4j/driver/internal/packstream/PackInput.java @@ -24,8 +24,7 @@ * This is what {@link PackStream} uses to ingest data, implement this on top of any data source of your choice to * deserialize the stream with {@link PackStream}. */ -public interface PackInput -{ +public interface PackInput { /** Consume one byte */ byte readByte() throws IOException; @@ -42,7 +41,7 @@ public interface PackInput double readDouble() throws IOException; /** Consume a specified number of bytes */ - void readBytes( byte[] into, int offset, int toRead ) throws IOException; + void readBytes(byte[] into, int offset, int toRead) throws IOException; /** Get the next byte without forwarding the internal pointer */ byte peekByte() throws IOException; diff --git a/driver/src/main/java/org/neo4j/driver/internal/packstream/PackOutput.java b/driver/src/main/java/org/neo4j/driver/internal/packstream/PackOutput.java index 74a9854865..22f355f513 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/packstream/PackOutput.java +++ b/driver/src/main/java/org/neo4j/driver/internal/packstream/PackOutput.java @@ -23,23 +23,22 @@ /** * This is where {@link PackStream} writes its output to. */ -public interface PackOutput -{ +public interface PackOutput { /** Produce a single byte */ - PackOutput writeByte( byte value ) throws IOException; + PackOutput writeByte(byte value) throws IOException; /** Produce binary data */ - PackOutput writeBytes( byte[] data ) throws IOException; + PackOutput writeBytes(byte[] data) throws IOException; /** Produce a 4-byte signed integer */ - PackOutput writeShort( short value ) throws IOException; + PackOutput writeShort(short value) throws IOException; /** Produce a 4-byte signed integer */ - PackOutput writeInt( int value ) throws IOException; + PackOutput writeInt(int value) throws IOException; /** Produce an 8-byte signed integer */ - PackOutput writeLong( long value ) throws IOException; + PackOutput writeLong(long value) throws IOException; /** Produce an 8-byte IEEE 754 "double format" floating-point number */ - PackOutput writeDouble( double value ) throws IOException; + PackOutput writeDouble(double value) throws IOException; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/packstream/PackStream.java b/driver/src/main/java/org/neo4j/driver/internal/packstream/PackStream.java index 7ecd99f5bc..5af4f15490 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/packstream/PackStream.java +++ b/driver/src/main/java/org/neo4j/driver/internal/packstream/PackStream.java @@ -18,15 +18,15 @@ */ package org.neo4j.driver.internal.packstream; +import static java.lang.Integer.toHexString; +import static java.lang.String.format; +import static java.util.Collections.singletonList; + import java.io.IOException; import java.nio.charset.Charset; import java.util.List; import java.util.Map; -import static java.lang.Integer.toHexString; -import static java.lang.String.format; -import static java.util.Collections.singletonList; - /** * PackStream is a messaging serialisation format heavily inspired by MessagePack. * The key differences are in the type system itself which (among other things) replaces extensions with structures. @@ -79,8 +79,7 @@ * * */ -public class PackStream -{ +public class PackStream { public static final byte TINY_STRING = (byte) 0x80; public static final byte TINY_LIST = (byte) 0x90; @@ -135,381 +134,326 @@ public class PackStream public static final byte RESERVED_EE = (byte) 0xEE; public static final byte RESERVED_EF = (byte) 0xEF; - private static final long PLUS_2_TO_THE_31 = 2147483648L; - private static final long PLUS_2_TO_THE_16 = 65536L; - private static final long PLUS_2_TO_THE_15 = 32768L; - private static final long PLUS_2_TO_THE_7 = 128L; - private static final long MINUS_2_TO_THE_4 = -16L; - private static final long MINUS_2_TO_THE_7 = -128L; + private static final long PLUS_2_TO_THE_31 = 2147483648L; + private static final long PLUS_2_TO_THE_16 = 65536L; + private static final long PLUS_2_TO_THE_15 = 32768L; + private static final long PLUS_2_TO_THE_7 = 128L; + private static final long MINUS_2_TO_THE_4 = -16L; + private static final long MINUS_2_TO_THE_7 = -128L; private static final long MINUS_2_TO_THE_15 = -32768L; private static final long MINUS_2_TO_THE_31 = -2147483648L; private static final String EMPTY_STRING = ""; private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - private static final Charset UTF_8 = Charset.forName( "UTF-8" ); + private static final Charset UTF_8 = Charset.forName("UTF-8"); private PackStream() {} - public static class Packer - { + public static class Packer { private PackOutput out; - public Packer( PackOutput out ) - { + public Packer(PackOutput out) { this.out = out; } - private void packRaw( byte[] data ) throws IOException - { - out.writeBytes( data ); + private void packRaw(byte[] data) throws IOException { + out.writeBytes(data); } - public void packNull() throws IOException - { - out.writeByte( NULL ); + public void packNull() throws IOException { + out.writeByte(NULL); } - public void pack( boolean value ) throws IOException - { - out.writeByte( value ? TRUE : FALSE ); + public void pack(boolean value) throws IOException { + out.writeByte(value ? TRUE : FALSE); } - public void pack( long value ) throws IOException - { - if ( value >= MINUS_2_TO_THE_4 && value < PLUS_2_TO_THE_7) - { - out.writeByte( (byte) value ); - } - else if ( value >= MINUS_2_TO_THE_7 && value < MINUS_2_TO_THE_4 ) - { - out.writeByte( INT_8 ) - .writeByte( (byte) value ); - } - else if ( value >= MINUS_2_TO_THE_15 && value < PLUS_2_TO_THE_15 ) - { - out.writeByte( INT_16 ) - .writeShort( (short) value ); - } - else if ( value >= MINUS_2_TO_THE_31 && value < PLUS_2_TO_THE_31 ) - { - out.writeByte( INT_32 ) - .writeInt( (int) value ); - } - else - { - out.writeByte( INT_64 ) - .writeLong( value ); + public void pack(long value) throws IOException { + if (value >= MINUS_2_TO_THE_4 && value < PLUS_2_TO_THE_7) { + out.writeByte((byte) value); + } else if (value >= MINUS_2_TO_THE_7 && value < MINUS_2_TO_THE_4) { + out.writeByte(INT_8).writeByte((byte) value); + } else if (value >= MINUS_2_TO_THE_15 && value < PLUS_2_TO_THE_15) { + out.writeByte(INT_16).writeShort((short) value); + } else if (value >= MINUS_2_TO_THE_31 && value < PLUS_2_TO_THE_31) { + out.writeByte(INT_32).writeInt((int) value); + } else { + out.writeByte(INT_64).writeLong(value); } } - public void pack( double value ) throws IOException - { - out.writeByte( FLOAT_64 ) - .writeDouble( value ); + public void pack(double value) throws IOException { + out.writeByte(FLOAT_64).writeDouble(value); } - public void pack( byte[] values ) throws IOException - { - if ( values == null ) { packNull(); } - else - { - packBytesHeader( values.length ); - packRaw( values ); + public void pack(byte[] values) throws IOException { + if (values == null) { + packNull(); + } else { + packBytesHeader(values.length); + packRaw(values); } } - public void pack( String value ) throws IOException - { - if ( value == null ) { packNull(); } - else - { - byte[] utf8 = value.getBytes( UTF_8 ); - packStringHeader( utf8.length ); - packRaw( utf8 ); + public void pack(String value) throws IOException { + if (value == null) { + packNull(); + } else { + byte[] utf8 = value.getBytes(UTF_8); + packStringHeader(utf8.length); + packRaw(utf8); } } - private void pack( List values ) throws IOException - { - if ( values == null ) { packNull(); } - else - { - packListHeader( values.size() ); - for ( Object value : values ) - { - pack( value ); + private void pack(List values) throws IOException { + if (values == null) { + packNull(); + } else { + packListHeader(values.size()); + for (Object value : values) { + pack(value); } } } - private void pack( Map values ) throws IOException - { - if ( values == null ) { packNull(); } - else - { - packMapHeader( values.size() ); - for ( Object key : values.keySet() ) - { - pack( key ); - pack( values.get( key ) ); + private void pack(Map values) throws IOException { + if (values == null) { + packNull(); + } else { + packMapHeader(values.size()); + for (Object key : values.keySet()) { + pack(key); + pack(values.get(key)); } } } - public void pack( Object value ) throws IOException - { - if ( value == null ) { packNull(); } - else if ( value instanceof Boolean ) { pack( (boolean) value ); } - else if ( value instanceof boolean[] ) { pack( singletonList( value ) ); } - else if ( value instanceof Byte ) { pack( (byte) value ); } - else if ( value instanceof byte[] ) { pack( (byte[]) value ); } - else if ( value instanceof Short ) { pack( (short) value ); } - else if ( value instanceof short[] ) { pack( singletonList( value ) ); } - else if ( value instanceof Integer ) { pack( (int) value ); } - else if ( value instanceof int[] ) { pack( singletonList( value ) ); } - else if ( value instanceof Long ) { pack( (long) value ); } - else if ( value instanceof long[] ) { pack( singletonList( value ) ); } - else if ( value instanceof Float ) { pack( (float) value ); } - else if ( value instanceof float[] ) { pack( singletonList( value ) ); } - else if ( value instanceof Double ) { pack( (double) value ); } - else if ( value instanceof double[] ) { pack( singletonList( value ) ); } - else if ( value instanceof Character ) { pack( Character.toString( (char) value ) ); } - else if ( value instanceof char[] ) { pack( new String( (char[]) value ) ); } - else if ( value instanceof String ) { pack( (String) value ); } - else if ( value instanceof String[] ) { pack( singletonList( value ) ); } - else if ( value instanceof List ) { pack( (List) value ); } - else if ( value instanceof Map ) { pack( (Map) value ); } - else { throw new UnPackable( format( "Cannot pack object %s", value ) );} - } - - public void packBytesHeader( int size ) throws IOException - { - if ( size <= Byte.MAX_VALUE ) - { - out.writeByte( BYTES_8 ) - .writeByte( (byte) size ); - } - else if ( size < PLUS_2_TO_THE_16 ) - { - out.writeByte( BYTES_16 ) - .writeShort( (short) size ); - } - else - { - out.writeByte( BYTES_32 ) - .writeInt( size ); + public void pack(Object value) throws IOException { + if (value == null) { + packNull(); + } else if (value instanceof Boolean) { + pack((boolean) value); + } else if (value instanceof boolean[]) { + pack(singletonList(value)); + } else if (value instanceof Byte) { + pack((byte) value); + } else if (value instanceof byte[]) { + pack((byte[]) value); + } else if (value instanceof Short) { + pack((short) value); + } else if (value instanceof short[]) { + pack(singletonList(value)); + } else if (value instanceof Integer) { + pack((int) value); + } else if (value instanceof int[]) { + pack(singletonList(value)); + } else if (value instanceof Long) { + pack((long) value); + } else if (value instanceof long[]) { + pack(singletonList(value)); + } else if (value instanceof Float) { + pack((float) value); + } else if (value instanceof float[]) { + pack(singletonList(value)); + } else if (value instanceof Double) { + pack((double) value); + } else if (value instanceof double[]) { + pack(singletonList(value)); + } else if (value instanceof Character) { + pack(Character.toString((char) value)); + } else if (value instanceof char[]) { + pack(new String((char[]) value)); + } else if (value instanceof String) { + pack((String) value); + } else if (value instanceof String[]) { + pack(singletonList(value)); + } else if (value instanceof List) { + pack((List) value); + } else if (value instanceof Map) { + pack((Map) value); + } else { + throw new UnPackable(format("Cannot pack object %s", value)); + } + } + + public void packBytesHeader(int size) throws IOException { + if (size <= Byte.MAX_VALUE) { + out.writeByte(BYTES_8).writeByte((byte) size); + } else if (size < PLUS_2_TO_THE_16) { + out.writeByte(BYTES_16).writeShort((short) size); + } else { + out.writeByte(BYTES_32).writeInt(size); + } + } + + private void packStringHeader(int size) throws IOException { + if (size < 0x10) { + out.writeByte((byte) (TINY_STRING | size)); + } else if (size <= Byte.MAX_VALUE) { + out.writeByte(STRING_8).writeByte((byte) size); + } else if (size < PLUS_2_TO_THE_16) { + out.writeByte(STRING_16).writeShort((short) size); + } else { + out.writeByte(STRING_32).writeInt(size); + } + } + + public void packListHeader(int size) throws IOException { + if (size < 0x10) { + out.writeByte((byte) (TINY_LIST | size)); + } else if (size <= Byte.MAX_VALUE) { + out.writeByte(LIST_8).writeByte((byte) size); + } else if (size < PLUS_2_TO_THE_16) { + out.writeByte(LIST_16).writeShort((short) size); + } else { + out.writeByte(LIST_32).writeInt(size); + } + } + + public void packMapHeader(int size) throws IOException { + if (size < 0x10) { + out.writeByte((byte) (TINY_MAP | size)); + } else if (size <= Byte.MAX_VALUE) { + out.writeByte(MAP_8).writeByte((byte) size); + } else if (size < PLUS_2_TO_THE_16) { + out.writeByte(MAP_16).writeShort((short) size); + } else { + out.writeByte(MAP_32).writeInt(size); + } + } + + public void packStructHeader(int size, byte signature) throws IOException { + if (size < 0x10) { + out.writeByte((byte) (TINY_STRUCT | size)).writeByte(signature); + } else if (size <= Byte.MAX_VALUE) { + out.writeByte(STRUCT_8).writeByte((byte) size).writeByte(signature); + } else if (size < PLUS_2_TO_THE_16) { + out.writeByte(STRUCT_16).writeShort((short) size).writeByte(signature); + } else { + throw new Overflow("Structures cannot have more than " + (PLUS_2_TO_THE_16 - 1) + " fields"); } } - - private void packStringHeader( int size ) throws IOException - { - if ( size < 0x10 ) - { - out.writeByte( (byte) (TINY_STRING | size) ); - } - else if ( size <= Byte.MAX_VALUE ) - { - out.writeByte( STRING_8 ) - .writeByte( (byte) size ); - } - else if ( size < PLUS_2_TO_THE_16 ) - { - out.writeByte( STRING_16 ) - .writeShort( (short) size ); - } - else - { - out.writeByte( STRING_32 ) - .writeInt( size ); - } - } - - public void packListHeader( int size ) throws IOException - { - if ( size < 0x10 ) - { - out.writeByte( (byte) (TINY_LIST | size) ); - } - else if ( size <= Byte.MAX_VALUE ) - { - out.writeByte( LIST_8 ) - .writeByte( (byte) size ); - } - else if ( size < PLUS_2_TO_THE_16 ) - { - out.writeByte( LIST_16 ) - .writeShort( (short) size ); - } - else - { - out.writeByte( LIST_32 ) - .writeInt( size ); - } - } - - public void packMapHeader( int size ) throws IOException - { - if ( size < 0x10 ) - { - out.writeByte( (byte) (TINY_MAP | size) ); - } - else if ( size <= Byte.MAX_VALUE ) - { - out.writeByte( MAP_8 ) - .writeByte( (byte) size ); - } - else if ( size < PLUS_2_TO_THE_16 ) - { - out.writeByte( MAP_16 ) - .writeShort( (short) size ); - } - else - { - out.writeByte( MAP_32 ) - .writeInt( size ); - } - } - - public void packStructHeader( int size, byte signature ) throws IOException - { - if ( size < 0x10 ) - { - out.writeByte( (byte) (TINY_STRUCT | size) ) - .writeByte( signature ); - } - else if ( size <= Byte.MAX_VALUE ) - { - out.writeByte( STRUCT_8 ) - .writeByte( (byte) size ) - .writeByte( signature ); - } - else if ( size < PLUS_2_TO_THE_16 ) - { - out.writeByte( STRUCT_16 ) - .writeShort( (short) size ) - .writeByte( signature ); - } - else - { - throw new Overflow( - "Structures cannot have more than " + (PLUS_2_TO_THE_16 - 1) + " fields" ); - } - } - } - public static class Unpacker - { + public static class Unpacker { private PackInput in; - public Unpacker( PackInput in ) - { + public Unpacker(PackInput in) { this.in = in; } - public long unpackStructHeader() throws IOException - { + public long unpackStructHeader() throws IOException { final byte markerByte = in.readByte(); final byte markerHighNibble = (byte) (markerByte & 0xF0); final byte markerLowNibble = (byte) (markerByte & 0x0F); - if ( markerHighNibble == TINY_STRUCT ) { return markerLowNibble; } - switch(markerByte) - { - case STRUCT_8: return unpackUINT8(); - case STRUCT_16: return unpackUINT16(); - default: throw new Unexpected( "Expected a struct, but got: " + toHexString( markerByte )); + if (markerHighNibble == TINY_STRUCT) { + return markerLowNibble; + } + switch (markerByte) { + case STRUCT_8: + return unpackUINT8(); + case STRUCT_16: + return unpackUINT16(); + default: + throw new Unexpected("Expected a struct, but got: " + toHexString(markerByte)); } } - public byte unpackStructSignature() throws IOException - { + public byte unpackStructSignature() throws IOException { return in.readByte(); } - public long unpackListHeader() throws IOException - { + public long unpackListHeader() throws IOException { final byte markerByte = in.readByte(); final byte markerHighNibble = (byte) (markerByte & 0xF0); - final byte markerLowNibble = (byte) (markerByte & 0x0F); + final byte markerLowNibble = (byte) (markerByte & 0x0F); - if ( markerHighNibble == TINY_LIST ) { return markerLowNibble; } - switch(markerByte) - { - case LIST_8: return unpackUINT8(); - case LIST_16: return unpackUINT16(); - case LIST_32: return unpackUINT32(); - default: throw new Unexpected( "Expected a list, but got: " + toHexString( markerByte & 0xFF )); + if (markerHighNibble == TINY_LIST) { + return markerLowNibble; + } + switch (markerByte) { + case LIST_8: + return unpackUINT8(); + case LIST_16: + return unpackUINT16(); + case LIST_32: + return unpackUINT32(); + default: + throw new Unexpected("Expected a list, but got: " + toHexString(markerByte & 0xFF)); } } - public long unpackMapHeader() throws IOException - { + public long unpackMapHeader() throws IOException { final byte markerByte = in.readByte(); final byte markerHighNibble = (byte) (markerByte & 0xF0); final byte markerLowNibble = (byte) (markerByte & 0x0F); - if ( markerHighNibble == TINY_MAP ) { return markerLowNibble; } - switch(markerByte) - { - case MAP_8: return unpackUINT8(); - case MAP_16: return unpackUINT16(); - case MAP_32: return unpackUINT32(); - default: throw new Unexpected( "Expected a map, but got: " + toHexString( markerByte )); + if (markerHighNibble == TINY_MAP) { + return markerLowNibble; + } + switch (markerByte) { + case MAP_8: + return unpackUINT8(); + case MAP_16: + return unpackUINT16(); + case MAP_32: + return unpackUINT32(); + default: + throw new Unexpected("Expected a map, but got: " + toHexString(markerByte)); } } - public long unpackLong() throws IOException - { + public long unpackLong() throws IOException { final byte markerByte = in.readByte(); - if ( markerByte >= MINUS_2_TO_THE_4) { return markerByte; } - switch(markerByte) - { - case INT_8: return in.readByte(); - case INT_16: return in.readShort(); - case INT_32: return in.readInt(); - case INT_64: return in.readLong(); - default: throw new Unexpected( "Expected an integer, but got: " + toHexString( markerByte )); + if (markerByte >= MINUS_2_TO_THE_4) { + return markerByte; + } + switch (markerByte) { + case INT_8: + return in.readByte(); + case INT_16: + return in.readShort(); + case INT_32: + return in.readInt(); + case INT_64: + return in.readLong(); + default: + throw new Unexpected("Expected an integer, but got: " + toHexString(markerByte)); } } - public double unpackDouble() throws IOException - { + public double unpackDouble() throws IOException { final byte markerByte = in.readByte(); - if(markerByte == FLOAT_64) - { + if (markerByte == FLOAT_64) { return in.readDouble(); } - throw new Unexpected( "Expected a double, but got: " + toHexString( markerByte )); + throw new Unexpected("Expected a double, but got: " + toHexString(markerByte)); } - public byte[] unpackBytes() throws IOException - { + public byte[] unpackBytes() throws IOException { final byte markerByte = in.readByte(); - switch(markerByte) - { - case BYTES_8: return unpackRawBytes( unpackUINT8() ); - case BYTES_16: return unpackRawBytes( unpackUINT16() ); - case BYTES_32: - { - long size = unpackUINT32(); - if ( size <= Integer.MAX_VALUE ) - { - return unpackRawBytes( (int) size ); - } - else - { - throw new Overflow( "BYTES_32 too long for Java" ); + switch (markerByte) { + case BYTES_8: + return unpackRawBytes(unpackUINT8()); + case BYTES_16: + return unpackRawBytes(unpackUINT16()); + case BYTES_32: { + long size = unpackUINT32(); + if (size <= Integer.MAX_VALUE) { + return unpackRawBytes((int) size); + } else { + throw new Overflow("BYTES_32 too long for Java"); + } } - } - default: throw new Unexpected( "Expected bytes, but got: 0x" + toHexString( markerByte & 0xFF )); + default: + throw new Unexpected("Expected bytes, but got: 0x" + toHexString(markerByte & 0xFF)); } } - public String unpackString() throws IOException - { + public String unpackString() throws IOException { final byte markerByte = in.readByte(); - if( markerByte == TINY_STRING ) // Note no mask, so we compare to 0x80. + if (markerByte == TINY_STRING) // Note no mask, so we compare to 0x80. { return EMPTY_STRING; } @@ -524,97 +468,88 @@ public String unpackString() throws IOException * @return null * @throws IOException if the unpacked value was not null */ - public Object unpackNull() throws IOException - { + public Object unpackNull() throws IOException { final byte markerByte = in.readByte(); - if ( markerByte != NULL ) - { - throw new Unexpected( "Expected a null, but got: 0x" + toHexString( markerByte & 0xFF ) ); + if (markerByte != NULL) { + throw new Unexpected("Expected a null, but got: 0x" + toHexString(markerByte & 0xFF)); } return null; } - private byte[] unpackUtf8(byte markerByte) throws IOException - { + private byte[] unpackUtf8(byte markerByte) throws IOException { final byte markerHighNibble = (byte) (markerByte & 0xF0); final byte markerLowNibble = (byte) (markerByte & 0x0F); - if ( markerHighNibble == TINY_STRING ) { return unpackRawBytes( markerLowNibble ); } - switch(markerByte) - { - case STRING_8: return unpackRawBytes( unpackUINT8() ); - case STRING_16: return unpackRawBytes( unpackUINT16() ); - case STRING_32: - { + if (markerHighNibble == TINY_STRING) { + return unpackRawBytes(markerLowNibble); + } + switch (markerByte) { + case STRING_8: + return unpackRawBytes(unpackUINT8()); + case STRING_16: + return unpackRawBytes(unpackUINT16()); + case STRING_32: { long size = unpackUINT32(); - if ( size <= Integer.MAX_VALUE ) - { - return unpackRawBytes( (int) size ); - } - else - { - throw new Overflow( "STRING_32 too long for Java" ); + if (size <= Integer.MAX_VALUE) { + return unpackRawBytes((int) size); + } else { + throw new Overflow("STRING_32 too long for Java"); } } - default: throw new Unexpected( "Expected a string, but got: 0x" + toHexString( markerByte & 0xFF )); + default: + throw new Unexpected("Expected a string, but got: 0x" + toHexString(markerByte & 0xFF)); } } - public boolean unpackBoolean() throws IOException - { + public boolean unpackBoolean() throws IOException { final byte markerByte = in.readByte(); - switch ( markerByte ) - { + switch (markerByte) { case TRUE: return true; case FALSE: return false; default: - throw new Unexpected( "Expected a boolean, but got: 0x" + toHexString( markerByte & 0xFF ) ); + throw new Unexpected("Expected a boolean, but got: 0x" + toHexString(markerByte & 0xFF)); } } - private int unpackUINT8() throws IOException - { + private int unpackUINT8() throws IOException { return in.readByte() & 0xFF; } - private int unpackUINT16() throws IOException - { + private int unpackUINT16() throws IOException { return in.readShort() & 0xFFFF; } - private long unpackUINT32() throws IOException - { + private long unpackUINT32() throws IOException { return in.readInt() & 0xFFFFFFFFL; } - private byte[] unpackRawBytes(int size ) throws IOException - { - if ( size == 0 ) - { + private byte[] unpackRawBytes(int size) throws IOException { + if (size == 0) { return EMPTY_BYTE_ARRAY; } byte[] heapBuffer = new byte[size]; - in.readBytes( heapBuffer, 0, heapBuffer.length ); + in.readBytes(heapBuffer, 0, heapBuffer.length); return heapBuffer; } - public PackType peekNextType() throws IOException - { + public PackType peekNextType() throws IOException { final byte markerByte = in.peekByte(); final byte markerHighNibble = (byte) (markerByte & 0xF0); - switch(markerHighNibble) - { - case TINY_STRING: return PackType.STRING; - case TINY_LIST: return PackType.LIST; - case TINY_MAP: return PackType.MAP; - case TINY_STRUCT: return PackType.STRUCT; + switch (markerHighNibble) { + case TINY_STRING: + return PackType.STRING; + case TINY_LIST: + return PackType.LIST; + case TINY_MAP: + return PackType.MAP; + case TINY_STRUCT: + return PackType.STRUCT; } - switch(markerByte) - { + switch (markerByte) { case NULL: return PackType.NULL; case TRUE: @@ -647,53 +582,43 @@ public PackType peekNextType() throws IOException } } - public static class PackStreamException extends IOException - { + public static class PackStreamException extends IOException { private static final long serialVersionUID = -1491422133282345421L; - protected PackStreamException( String message ) - { - super( message ); + protected PackStreamException(String message) { + super(message); } } - public static class EndOfStream extends PackStreamException - { + public static class EndOfStream extends PackStreamException { private static final long serialVersionUID = 5102836237108105603L; - public EndOfStream( String message ) - { - super( message ); + public EndOfStream(String message) { + super(message); } } - public static class Overflow extends PackStreamException - { + public static class Overflow extends PackStreamException { private static final long serialVersionUID = -923071934446993659L; - public Overflow( String message ) - { - super( message ); + public Overflow(String message) { + super(message); } } - public static class Unexpected extends PackStreamException - { + public static class Unexpected extends PackStreamException { private static final long serialVersionUID = 5004685868740125469L; - public Unexpected( String message ) - { - super( message ); + public Unexpected(String message) { + super(message); } } - public static class UnPackable extends PackStreamException - { + public static class UnPackable extends PackStreamException { private static final long serialVersionUID = 2408740707769711365L; - public UnPackable( String message ) - { - super( message ); + public UnPackable(String message) { + super(message); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/packstream/PackType.java b/driver/src/main/java/org/neo4j/driver/internal/packstream/PackType.java index 4517a829fc..8b1c0bff22 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/packstream/PackType.java +++ b/driver/src/main/java/org/neo4j/driver/internal/packstream/PackType.java @@ -18,8 +18,14 @@ */ package org.neo4j.driver.internal.packstream; -public enum PackType -{ - NULL, BOOLEAN, INTEGER, FLOAT, BYTES, - STRING, LIST, MAP, STRUCT +public enum PackType { + NULL, + BOOLEAN, + INTEGER, + FLOAT, + BYTES, + STRING, + LIST, + MAP, + STRUCT } diff --git a/driver/src/main/java/org/neo4j/driver/internal/reactive/AbstractRxQueryRunner.java b/driver/src/main/java/org/neo4j/driver/internal/reactive/AbstractRxQueryRunner.java index 3f86858cb2..ad66deb517 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/reactive/AbstractRxQueryRunner.java +++ b/driver/src/main/java/org/neo4j/driver/internal/reactive/AbstractRxQueryRunner.java @@ -18,39 +18,33 @@ */ package org.neo4j.driver.internal.reactive; -import java.util.Map; +import static org.neo4j.driver.internal.AbstractQueryRunner.parameters; +import java.util.Map; import org.neo4j.driver.Query; -import org.neo4j.driver.reactive.RxResult; -import org.neo4j.driver.reactive.RxQueryRunner; import org.neo4j.driver.Record; import org.neo4j.driver.Value; +import org.neo4j.driver.reactive.RxQueryRunner; +import org.neo4j.driver.reactive.RxResult; -import static org.neo4j.driver.internal.AbstractQueryRunner.parameters; - -public abstract class AbstractRxQueryRunner implements RxQueryRunner -{ +public abstract class AbstractRxQueryRunner implements RxQueryRunner { @Override - public final RxResult run(String query, Value parameters ) - { - return run( new Query( query, parameters ) ); + public final RxResult run(String query, Value parameters) { + return run(new Query(query, parameters)); } @Override - public final RxResult run(String query, Map parameters ) - { - return run( query, parameters( parameters ) ); + public final RxResult run(String query, Map parameters) { + return run(query, parameters(parameters)); } @Override - public final RxResult run(String query, Record parameters ) - { - return run( query, parameters( parameters ) ); + public final RxResult run(String query, Record parameters) { + return run(query, parameters(parameters)); } @Override - public final RxResult run(String query ) - { - return run( new Query( query ) ); + public final RxResult run(String query) { + return run(new Query(query)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxResult.java b/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxResult.java index ad768ff77c..4008fba413 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxResult.java +++ b/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxResult.java @@ -18,65 +18,56 @@ */ package org.neo4j.driver.internal.reactive; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.FluxSink; -import reactor.core.publisher.Mono; +import static org.neo4j.driver.internal.util.ErrorUtil.newResultConsumedError; +import static reactor.core.publisher.FluxSink.OverflowStrategy.IGNORE; import java.util.List; import java.util.concurrent.CompletionStage; import java.util.function.BiConsumer; import java.util.function.Supplier; - import org.neo4j.driver.Record; import org.neo4j.driver.internal.cursor.RxResultCursor; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.summary.ResultSummary; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.FluxSink; +import reactor.core.publisher.Mono; -import static org.neo4j.driver.internal.util.ErrorUtil.newResultConsumedError; -import static reactor.core.publisher.FluxSink.OverflowStrategy.IGNORE; - -public class InternalRxResult implements RxResult -{ +public class InternalRxResult implements RxResult { private Supplier> cursorFutureSupplier; private volatile CompletionStage cursorFuture; - public InternalRxResult(Supplier> cursorFuture ) - { + public InternalRxResult(Supplier> cursorFuture) { this.cursorFutureSupplier = cursorFuture; } @Override - public Publisher> keys() - { - return Mono.defer( () -> Mono.fromCompletionStage( getCursorFuture() ).map( RxResultCursor::keys ) - .onErrorMap( Futures::completionExceptionCause ) ); + public Publisher> keys() { + return Mono.defer(() -> Mono.fromCompletionStage(getCursorFuture()) + .map(RxResultCursor::keys) + .onErrorMap(Futures::completionExceptionCause)); } @Override - public Publisher records() - { - return Flux.create( sink -> getCursorFuture().whenComplete( ( cursor, completionError ) -> { - if( cursor != null ) - { - if( cursor.isDone() ) - { - sink.error( newResultConsumedError() ); - } - else - { - cursor.installRecordConsumer( createRecordConsumer( sink ) ); - sink.onCancel( cursor::cancel ); - sink.onRequest( cursor::request ); - } - } - else - { - Throwable error = Futures.completionExceptionCause( completionError ); - sink.error( error ); - } - } ), IGNORE ); + public Publisher records() { + return Flux.create( + sink -> getCursorFuture().whenComplete((cursor, completionError) -> { + if (cursor != null) { + if (cursor.isDone()) { + sink.error(newResultConsumedError()); + } else { + cursor.installRecordConsumer(createRecordConsumer(sink)); + sink.onCancel(cursor::cancel); + sink.onRequest(cursor::request); + } + } else { + Throwable error = Futures.completionExceptionCause(completionError); + sink.error(error); + } + }), + IGNORE); } /** @@ -87,38 +78,28 @@ public Publisher records() * @param sink the subscriber * @return a record consumer. */ - private BiConsumer createRecordConsumer( FluxSink sink ) - { - return ( r, e ) -> { - if ( r != null ) - { - sink.next( r ); - } - else if ( e != null ) - { - sink.error( e ); - } - else - { + private BiConsumer createRecordConsumer(FluxSink sink) { + return (r, e) -> { + if (r != null) { + sink.next(r); + } else if (e != null) { + sink.error(e); + } else { sink.complete(); } }; } - private CompletionStage getCursorFuture() - { - if ( cursorFuture != null ) - { + private CompletionStage getCursorFuture() { + if (cursorFuture != null) { return cursorFuture; } return initCursorFuture(); } - synchronized CompletionStage initCursorFuture() - { + synchronized CompletionStage initCursorFuture() { // A quick path to return - if ( cursorFuture != null ) - { + if (cursorFuture != null) { return cursorFuture; } @@ -129,34 +110,26 @@ synchronized CompletionStage initCursorFuture() } @Override - public Publisher consume() - { - return Mono.create( sink -> getCursorFuture().whenComplete( ( cursor, completionError ) -> { - if ( cursor != null ) - { - cursor.summaryAsync().whenComplete( ( summary, summaryCompletionError ) -> { - Throwable error = Futures.completionExceptionCause( summaryCompletionError ); - if ( summary != null ) - { - sink.success( summary ); + public Publisher consume() { + return Mono.create(sink -> getCursorFuture().whenComplete((cursor, completionError) -> { + if (cursor != null) { + cursor.summaryAsync().whenComplete((summary, summaryCompletionError) -> { + Throwable error = Futures.completionExceptionCause(summaryCompletionError); + if (summary != null) { + sink.success(summary); + } else { + sink.error(error); } - else - { - sink.error( error ); - } - } ); - } - else - { - Throwable error = Futures.completionExceptionCause( completionError ); - sink.error( error ); + }); + } else { + Throwable error = Futures.completionExceptionCause(completionError); + sink.error(error); } - } ) ); + })); } // For testing purpose - Supplier> cursorFutureSupplier() - { + Supplier> cursorFutureSupplier() { return this.cursorFutureSupplier; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxSession.java b/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxSession.java index 222b64562d..1e5aeb7d91 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxSession.java +++ b/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxSession.java @@ -18,12 +18,11 @@ */ package org.neo4j.driver.internal.reactive; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; +import static org.neo4j.driver.internal.reactive.RxUtils.createEmptyPublisher; +import static org.neo4j.driver.internal.reactive.RxUtils.createSingleItemPublisher; import java.util.Map; import java.util.concurrent.CompletableFuture; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -36,174 +35,149 @@ import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.reactive.RxTransaction; import org.neo4j.driver.reactive.RxTransactionWork; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; -import static org.neo4j.driver.internal.reactive.RxUtils.createEmptyPublisher; -import static org.neo4j.driver.internal.reactive.RxUtils.createSingleItemPublisher; - -public class InternalRxSession extends AbstractRxQueryRunner implements RxSession -{ +public class InternalRxSession extends AbstractRxQueryRunner implements RxSession { private final NetworkSession session; - public InternalRxSession( NetworkSession session ) - { + public InternalRxSession(NetworkSession session) { // RxSession accept a network session as input. // The network session different from async session that it provides ways to both run for Rx and Async - // Note: Blocking result could just build on top of async result. However Rx result cannot just build on top of async result. + // Note: Blocking result could just build on top of async result. However Rx result cannot just build on top of + // async result. this.session = session; } @Override - public Publisher beginTransaction() - { - return beginTransaction( TransactionConfig.empty() ); + public Publisher beginTransaction() { + return beginTransaction(TransactionConfig.empty()); } @Override - public Publisher beginTransaction( TransactionConfig config ) - { + public Publisher beginTransaction(TransactionConfig config) { return createSingleItemPublisher( - () -> - { + () -> { CompletableFuture txFuture = new CompletableFuture<>(); - session.beginTransactionAsync( config ).whenComplete( - ( tx, completionError ) -> - { - if ( tx != null ) - { - txFuture.complete( new InternalRxTransaction( tx ) ); - } - else - { - releaseConnectionBeforeReturning( txFuture, completionError ); - } - } ); + session.beginTransactionAsync(config).whenComplete((tx, completionError) -> { + if (tx != null) { + txFuture.complete(new InternalRxTransaction(tx)); + } else { + releaseConnectionBeforeReturning(txFuture, completionError); + } + }); return txFuture; - }, () -> new IllegalStateException( "Unexpected condition, begin transaction call has completed successfully with transaction being null" ) ); + }, + () -> new IllegalStateException( + "Unexpected condition, begin transaction call has completed successfully with transaction being null")); } - private Publisher beginTransaction( AccessMode mode, TransactionConfig config ) - { + private Publisher beginTransaction(AccessMode mode, TransactionConfig config) { return createSingleItemPublisher( - () -> - { + () -> { CompletableFuture txFuture = new CompletableFuture<>(); - session.beginTransactionAsync( mode, config ).whenComplete( - ( tx, completionError ) -> - { - if ( tx != null ) - { - txFuture.complete( new InternalRxTransaction( tx ) ); - } - else - { - releaseConnectionBeforeReturning( txFuture, completionError ); - } - } ); + session.beginTransactionAsync(mode, config).whenComplete((tx, completionError) -> { + if (tx != null) { + txFuture.complete(new InternalRxTransaction(tx)); + } else { + releaseConnectionBeforeReturning(txFuture, completionError); + } + }); return txFuture; - }, () -> new IllegalStateException( "Unexpected condition, begin transaction call has completed successfully with transaction being null" ) ); + }, + () -> new IllegalStateException( + "Unexpected condition, begin transaction call has completed successfully with transaction being null")); } @Override - public Publisher readTransaction( RxTransactionWork> work ) - { - return readTransaction( work, TransactionConfig.empty() ); + public Publisher readTransaction(RxTransactionWork> work) { + return readTransaction(work, TransactionConfig.empty()); } @Override - public Publisher readTransaction( RxTransactionWork> work, TransactionConfig config ) - { - return runTransaction( AccessMode.READ, work, config ); + public Publisher readTransaction(RxTransactionWork> work, TransactionConfig config) { + return runTransaction(AccessMode.READ, work, config); } @Override - public Publisher writeTransaction( RxTransactionWork> work ) - { - return writeTransaction( work, TransactionConfig.empty() ); + public Publisher writeTransaction(RxTransactionWork> work) { + return writeTransaction(work, TransactionConfig.empty()); } @Override - public Publisher writeTransaction( RxTransactionWork> work, TransactionConfig config ) - { - return runTransaction( AccessMode.WRITE, work, config ); + public Publisher writeTransaction(RxTransactionWork> work, TransactionConfig config) { + return runTransaction(AccessMode.WRITE, work, config); } - private Publisher runTransaction( AccessMode mode, RxTransactionWork> work, TransactionConfig config ) - { - Flux repeatableWork = Flux.usingWhen( beginTransaction( mode, config ), work::execute, - tx -> tx.close( true ), ( tx, error ) -> tx.close(), InternalRxTransaction::close ); - return session.retryLogic().retryRx( repeatableWork ); + private Publisher runTransaction( + AccessMode mode, RxTransactionWork> work, TransactionConfig config) { + Flux repeatableWork = Flux.usingWhen( + beginTransaction(mode, config), + work::execute, + tx -> tx.close(true), + (tx, error) -> tx.close(), + InternalRxTransaction::close); + return session.retryLogic().retryRx(repeatableWork); } @Override - public RxResult run(String query, TransactionConfig config ) - { - return run( new Query( query ), config ); + public RxResult run(String query, TransactionConfig config) { + return run(new Query(query), config); } @Override - public RxResult run(String query, Map parameters, TransactionConfig config ) - { - return run( new Query( query, parameters ), config ); + public RxResult run(String query, Map parameters, TransactionConfig config) { + return run(new Query(query, parameters), config); } @Override - public RxResult run(Query query) - { - return run(query, TransactionConfig.empty() ); + public RxResult run(Query query) { + return run(query, TransactionConfig.empty()); } @Override - public RxResult run(Query query, TransactionConfig config ) - { - return new InternalRxResult( () -> { + public RxResult run(Query query, TransactionConfig config) { + return new InternalRxResult(() -> { CompletableFuture resultCursorFuture = new CompletableFuture<>(); - session.runRx(query, config ).whenComplete( (cursor, completionError ) -> { - if ( cursor != null ) - { - resultCursorFuture.complete( cursor ); - } - else - { - releaseConnectionBeforeReturning( resultCursorFuture, completionError ); + session.runRx(query, config).whenComplete((cursor, completionError) -> { + if (cursor != null) { + resultCursorFuture.complete(cursor); + } else { + releaseConnectionBeforeReturning(resultCursorFuture, completionError); } - } ); + }); return resultCursorFuture; - } ); + }); } - private void releaseConnectionBeforeReturning( CompletableFuture returnFuture, Throwable completionError ) - { + private void releaseConnectionBeforeReturning(CompletableFuture returnFuture, Throwable completionError) { // We failed to create a result cursor so we cannot rely on result cursor to cleanup resources. - // Therefore we will first release the connection that might have been created in the session and then notify the error. + // Therefore we will first release the connection that might have been created in the session and then notify + // the error. // The logic here shall be the same as `SessionPullResponseHandler#afterFailure`. // The reason we need to release connection in session is that we made `rxSession.close()` optional; // Otherwise, session.close shall handle everything for us. - Throwable error = Futures.completionExceptionCause( completionError ); - if ( error instanceof TransactionNestingException ) - { - returnFuture.completeExceptionally( error ); - } - else - { - session.releaseConnectionAsync().whenComplete( ( ignored, closeError ) -> - returnFuture.completeExceptionally( Futures.combineErrors( error, closeError ) ) ); + Throwable error = Futures.completionExceptionCause(completionError); + if (error instanceof TransactionNestingException) { + returnFuture.completeExceptionally(error); + } else { + session.releaseConnectionAsync() + .whenComplete((ignored, closeError) -> + returnFuture.completeExceptionally(Futures.combineErrors(error, closeError))); } } @Override - public Bookmark lastBookmark() - { + public Bookmark lastBookmark() { return session.lastBookmark(); } - public Publisher reset() - { - return createEmptyPublisher( session::resetAsync ); + public Publisher reset() { + return createEmptyPublisher(session::resetAsync); } @Override - public Publisher close() - { - return createEmptyPublisher( session::closeAsync ); + public Publisher close() { + return createEmptyPublisher(session::closeAsync); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxTransaction.java b/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxTransaction.java index 70aee517bf..e5742bac9b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxTransaction.java +++ b/driver/src/main/java/org/neo4j/driver/internal/reactive/InternalRxTransaction.java @@ -18,71 +18,61 @@ */ package org.neo4j.driver.internal.reactive; -import org.reactivestreams.Publisher; +import static org.neo4j.driver.internal.reactive.RxUtils.createEmptyPublisher; import java.util.concurrent.CompletableFuture; - import org.neo4j.driver.Query; import org.neo4j.driver.internal.async.UnmanagedTransaction; import org.neo4j.driver.internal.cursor.RxResultCursor; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxTransaction; +import org.reactivestreams.Publisher; -import static org.neo4j.driver.internal.reactive.RxUtils.createEmptyPublisher; - -public class InternalRxTransaction extends AbstractRxQueryRunner implements RxTransaction -{ +public class InternalRxTransaction extends AbstractRxQueryRunner implements RxTransaction { private final UnmanagedTransaction tx; - public InternalRxTransaction( UnmanagedTransaction tx ) - { + public InternalRxTransaction(UnmanagedTransaction tx) { this.tx = tx; } @Override - public RxResult run(Query query) - { - return new InternalRxResult( () -> { + public RxResult run(Query query) { + return new InternalRxResult(() -> { CompletableFuture cursorFuture = new CompletableFuture<>(); - tx.runRx(query).whenComplete( (cursor, completionError ) -> { - if ( cursor != null ) - { - cursorFuture.complete( cursor ); - } - else - { + tx.runRx(query).whenComplete((cursor, completionError) -> { + if (cursor != null) { + cursorFuture.complete(cursor); + } else { // We failed to create a result cursor so we cannot rely on result cursor to handle failure. - // The logic here shall be the same as `TransactionPullResponseHandler#afterFailure` as that is where cursor handling failure - // This is optional as tx still holds a reference to all cursor futures and they will be clean up properly in commit - Throwable error = Futures.completionExceptionCause( completionError ); - tx.markTerminated( error ); - cursorFuture.completeExceptionally( error ); + // The logic here shall be the same as `TransactionPullResponseHandler#afterFailure` as that is + // where cursor handling failure + // This is optional as tx still holds a reference to all cursor futures and they will be clean up + // properly in commit + Throwable error = Futures.completionExceptionCause(completionError); + tx.markTerminated(error); + cursorFuture.completeExceptionally(error); } - } ); + }); return cursorFuture; - } ); + }); } @Override - public Publisher commit() - { - return createEmptyPublisher( tx::commitAsync ); + public Publisher commit() { + return createEmptyPublisher(tx::commitAsync); } @Override - public Publisher rollback() - { - return createEmptyPublisher( tx::rollbackAsync ); + public Publisher rollback() { + return createEmptyPublisher(tx::rollbackAsync); } - public Publisher close() - { - return close( false ); + public Publisher close() { + return close(false); } - Publisher close( boolean commit ) - { - return createEmptyPublisher( () -> tx.closeAsync( commit ) ); + Publisher close(boolean commit) { + return createEmptyPublisher(() -> tx.closeAsync(commit)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/reactive/RxUtils.java b/driver/src/main/java/org/neo4j/driver/internal/reactive/RxUtils.java index 392365e1da..d0048bc198 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/reactive/RxUtils.java +++ b/driver/src/main/java/org/neo4j/driver/internal/reactive/RxUtils.java @@ -18,35 +18,28 @@ */ package org.neo4j.driver.internal.reactive; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Mono; - import java.util.Optional; import java.util.concurrent.CompletionStage; import java.util.function.Supplier; - import org.neo4j.driver.internal.util.Futures; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Mono; -public class RxUtils -{ +public class RxUtils { /** * The publisher created by this method will either succeed without publishing anything or fail with an error. * @param supplier supplies a {@link CompletionStage}. * @return A publisher that publishes nothing on completion or fails with an error. */ - public static Publisher createEmptyPublisher( Supplier> supplier ) - { - return Mono.create( sink -> supplier.get().whenComplete( ( ignore, completionError ) -> { - Throwable error = Futures.completionExceptionCause( completionError ); - if ( error != null ) - { - sink.error( error ); - } - else - { + public static Publisher createEmptyPublisher(Supplier> supplier) { + return Mono.create(sink -> supplier.get().whenComplete((ignore, completionError) -> { + Throwable error = Futures.completionExceptionCause(completionError); + if (error != null) { + sink.error(error); + } else { sink.success(); } - } ) ); + })); } /** @@ -58,27 +51,20 @@ public static Publisher createEmptyPublisher( Supplier the type of the item to publish. * @return A publisher that succeeds exactly one item or fails with an error. */ - public static Publisher createSingleItemPublisher( Supplier> supplier, Supplier nullResultThrowableSupplier ) - { - return Mono.create( sink -> supplier.get().whenComplete( - ( item, completionError ) -> - { - if ( completionError == null ) - { - if ( item != null ) - { - sink.success( item ); - } - else - { - sink.error( nullResultThrowableSupplier.get() ); - } - } - else - { - Throwable error = Optional.ofNullable( Futures.completionExceptionCause( completionError ) ).orElse( completionError ); - sink.error( error ); - } - } ) ); + public static Publisher createSingleItemPublisher( + Supplier> supplier, Supplier nullResultThrowableSupplier) { + return Mono.create(sink -> supplier.get().whenComplete((item, completionError) -> { + if (completionError == null) { + if (item != null) { + sink.success(item); + } else { + sink.error(nullResultThrowableSupplier.get()); + } + } else { + Throwable error = Optional.ofNullable(Futures.completionExceptionCause(completionError)) + .orElse(completionError); + sink.error(error); + } + })); } } 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 cb9d7a7e26..664253205d 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 @@ -18,15 +18,10 @@ */ package org.neo4j.driver.internal.retry; +import static java.util.concurrent.TimeUnit.SECONDS; + import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutorGroup; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; -import reactor.util.context.Context; -import reactor.util.retry.Retry; - import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -35,7 +30,6 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.exceptions.AuthorizationExpiredException; @@ -47,14 +41,17 @@ import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.util.Experimental; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; +import reactor.util.context.Context; +import reactor.util.retry.Retry; -import static java.util.concurrent.TimeUnit.SECONDS; - -public class ExponentialBackoffRetryLogic implements RetryLogic -{ - static final long DEFAULT_MAX_RETRY_TIME_MS = SECONDS.toMillis( 30 ); +public class ExponentialBackoffRetryLogic implements RetryLogic { + static final long DEFAULT_MAX_RETRY_TIME_MS = SECONDS.toMillis(30); - private static final long INITIAL_RETRY_DELAY_MS = SECONDS.toMillis( 1 ); + private static final long INITIAL_RETRY_DELAY_MS = SECONDS.toMillis(1); private static final double RETRY_DELAY_MULTIPLIER = 2.0; private static final double RETRY_DELAY_JITTER_FACTOR = 0.2; private static final long MAX_RETRY_DELAY = Long.MAX_VALUE / 2; @@ -67,95 +64,95 @@ public class ExponentialBackoffRetryLogic implements RetryLogic private final Clock clock; private final Logger log; - public ExponentialBackoffRetryLogic( RetrySettings settings, EventExecutorGroup eventExecutorGroup, Clock clock, - Logging logging ) - { - this( settings.maxRetryTimeMs(), INITIAL_RETRY_DELAY_MS, RETRY_DELAY_MULTIPLIER, RETRY_DELAY_JITTER_FACTOR, - eventExecutorGroup, clock, logging ); + public ExponentialBackoffRetryLogic( + RetrySettings settings, EventExecutorGroup eventExecutorGroup, Clock clock, Logging logging) { + this( + settings.maxRetryTimeMs(), + INITIAL_RETRY_DELAY_MS, + RETRY_DELAY_MULTIPLIER, + RETRY_DELAY_JITTER_FACTOR, + eventExecutorGroup, + clock, + logging); } - ExponentialBackoffRetryLogic( long maxRetryTimeMs, long initialRetryDelayMs, double multiplier, - double jitterFactor, EventExecutorGroup eventExecutorGroup, Clock clock, Logging logging ) - { + ExponentialBackoffRetryLogic( + long maxRetryTimeMs, + long initialRetryDelayMs, + double multiplier, + double jitterFactor, + EventExecutorGroup eventExecutorGroup, + Clock clock, + Logging logging) { this.maxRetryTimeMs = maxRetryTimeMs; this.initialRetryDelayMs = initialRetryDelayMs; this.multiplier = multiplier; this.jitterFactor = jitterFactor; this.eventExecutorGroup = eventExecutorGroup; this.clock = clock; - this.log = logging.getLog( getClass() ); + this.log = logging.getLog(getClass()); verifyAfterConstruction(); } @Override - public T retry( Supplier work ) - { + public T retry(Supplier work) { List errors = null; long startTime = -1; long nextDelayMs = initialRetryDelayMs; - while ( true ) - { - try - { + while (true) { + try { return work.get(); - } - catch ( Throwable throwable ) - { - Throwable error = extractPossibleTerminationCause( throwable ); - if ( canRetryOn( error ) ) - { + } catch (Throwable throwable) { + Throwable error = extractPossibleTerminationCause(throwable); + if (canRetryOn(error)) { long currentTime = clock.millis(); - if ( startTime == -1 ) - { + if (startTime == -1) { startTime = currentTime; } long elapsedTime = currentTime - startTime; - if ( elapsedTime < maxRetryTimeMs ) - { - long delayWithJitterMs = computeDelayWithJitter( nextDelayMs ); - log.warn( "Transaction failed and will be retried in " + delayWithJitterMs + "ms", error ); + if (elapsedTime < maxRetryTimeMs) { + long delayWithJitterMs = computeDelayWithJitter(nextDelayMs); + log.warn("Transaction failed and will be retried in " + delayWithJitterMs + "ms", error); - sleep( delayWithJitterMs ); + sleep(delayWithJitterMs); nextDelayMs = (long) (nextDelayMs * multiplier); - errors = recordError( error, errors ); + errors = recordError(error, errors); continue; } } // Add the original error in case we didn't continue the loop from within the if above. - addSuppressed( throwable, errors ); + addSuppressed(throwable, errors); throw throwable; } } } @Override - public CompletionStage retryAsync( Supplier> work ) - { + public CompletionStage retryAsync(Supplier> work) { CompletableFuture resultFuture = new CompletableFuture<>(); - executeWorkInEventLoop( resultFuture, work ); + executeWorkInEventLoop(resultFuture, work); return resultFuture; } @Override - public Publisher retryRx( Publisher work ) - { - return Flux.from( work ).retryWhen( exponentialBackoffRetryRx() ); + public Publisher retryRx(Publisher work) { + return Flux.from(work).retryWhen(exponentialBackoffRetryRx()); } - protected boolean canRetryOn( Throwable error ) - { - return isRetryable( error ); + protected boolean canRetryOn(Throwable error) { + return isRetryable(error); } @Experimental - public static boolean isRetryable( Throwable error ) - { - return error instanceof SessionExpiredException || error instanceof ServiceUnavailableException || error instanceof AuthorizationExpiredException || - isTransientError( error ); + public static boolean isRetryable(Throwable error) { + return error instanceof SessionExpiredException + || error instanceof ServiceUnavailableException + || error instanceof AuthorizationExpiredException + || isTransientError(error); } /** @@ -164,205 +161,191 @@ public static boolean isRetryable( Throwable error ) * @param error * @return */ - private static Throwable extractPossibleTerminationCause( Throwable error ) - { + private static Throwable extractPossibleTerminationCause(Throwable error) { // Having a dedicated "TerminatedException" inheriting from ClientException might be a good idea. - if ( error instanceof ClientException && error.getCause() != null ) - { + if (error instanceof ClientException && error.getCause() != null) { return error.getCause(); } return error; } - private Retry exponentialBackoffRetryRx() - { - return Retry.from( retrySignals -> retrySignals.flatMap( retrySignal -> Mono.deferContextual( - contextView -> - { - Throwable throwable = retrySignal.failure(); - // Extract nested Neo4jException from not Neo4jException. Reactor usingWhen returns RuntimeException on async resource cleanup failure. - if ( throwable != null && !(throwable instanceof Neo4jException) && throwable.getCause() instanceof Neo4jException ) - { - throwable = throwable.getCause(); - } - Throwable error = extractPossibleTerminationCause( throwable ); - - List errors = contextView.getOrDefault( "errors", null ); - - if ( canRetryOn( error ) ) - { - long currentTime = clock.millis(); - - long startTime = contextView.getOrDefault( "startTime", currentTime ); - long nextDelayMs = contextView.getOrDefault( "nextDelayMs", initialRetryDelayMs ); - - long elapsedTime = currentTime - startTime; - if ( elapsedTime < maxRetryTimeMs ) - { - long delayWithJitterMs = computeDelayWithJitter( nextDelayMs ); - log.warn( "Reactive transaction failed and is scheduled to retry in " + delayWithJitterMs + "ms", error ); - - nextDelayMs = (long) (nextDelayMs * multiplier); - errors = recordError( error, errors ); - - // retry on netty event loop thread - EventExecutor eventExecutor = eventExecutorGroup.next(); - Context context = Context.of( - "errors", errors, - "startTime", startTime, - "nextDelayMs", nextDelayMs - ); - return Mono.just( context ).delayElement( Duration.ofMillis( delayWithJitterMs ), Schedulers.fromExecutorService( eventExecutor ) ); - } - } - addSuppressed( throwable, errors ); + private Retry exponentialBackoffRetryRx() { + return Retry.from(retrySignals -> retrySignals.flatMap(retrySignal -> Mono.deferContextual(contextView -> { + Throwable throwable = retrySignal.failure(); + // Extract nested Neo4jException from not Neo4jException. Reactor usingWhen returns RuntimeException on + // async resource cleanup failure. + if (throwable != null + && !(throwable instanceof Neo4jException) + && throwable.getCause() instanceof Neo4jException) { + throwable = throwable.getCause(); + } + Throwable error = extractPossibleTerminationCause(throwable); + + List errors = contextView.getOrDefault("errors", null); + + if (canRetryOn(error)) { + long currentTime = clock.millis(); + + long startTime = contextView.getOrDefault("startTime", currentTime); + long nextDelayMs = contextView.getOrDefault("nextDelayMs", initialRetryDelayMs); + + long elapsedTime = currentTime - startTime; + if (elapsedTime < maxRetryTimeMs) { + long delayWithJitterMs = computeDelayWithJitter(nextDelayMs); + log.warn( + "Reactive transaction failed and is scheduled to retry in " + delayWithJitterMs + "ms", + error); + + nextDelayMs = (long) (nextDelayMs * multiplier); + errors = recordError(error, errors); + + // retry on netty event loop thread + EventExecutor eventExecutor = eventExecutorGroup.next(); + Context context = Context.of( + "errors", errors, + "startTime", startTime, + "nextDelayMs", nextDelayMs); + return Mono.just(context) + .delayElement( + Duration.ofMillis(delayWithJitterMs), + Schedulers.fromExecutorService(eventExecutor)); + } + } + addSuppressed(throwable, errors); - return Mono.error( throwable ); - } ) ) ); + return Mono.error(throwable); + }))); } - private void executeWorkInEventLoop( CompletableFuture resultFuture, Supplier> work ) - { + private void executeWorkInEventLoop(CompletableFuture resultFuture, Supplier> work) { // this is the very first time we execute given work EventExecutor eventExecutor = eventExecutorGroup.next(); - eventExecutor.execute( () -> executeWork( resultFuture, work, -1, initialRetryDelayMs, null ) ); + eventExecutor.execute(() -> executeWork(resultFuture, work, -1, initialRetryDelayMs, null)); } - private void retryWorkInEventLoop( CompletableFuture resultFuture, Supplier> work, - Throwable error, long startTime, long delayMs, List errors ) - { + private void retryWorkInEventLoop( + CompletableFuture resultFuture, + Supplier> work, + Throwable error, + long startTime, + long delayMs, + List errors) { // work has failed before, we need to schedule retry with the given delay EventExecutor eventExecutor = eventExecutorGroup.next(); - long delayWithJitterMs = computeDelayWithJitter( delayMs ); - log.warn( "Async transaction failed and is scheduled to retry in " + delayWithJitterMs + "ms", error ); + long delayWithJitterMs = computeDelayWithJitter(delayMs); + log.warn("Async transaction failed and is scheduled to retry in " + delayWithJitterMs + "ms", error); - eventExecutor.schedule( () -> - { - long newRetryDelayMs = (long) (delayMs * multiplier); - executeWork( resultFuture, work, startTime, newRetryDelayMs, errors ); - }, delayWithJitterMs, TimeUnit.MILLISECONDS ); + eventExecutor.schedule( + () -> { + long newRetryDelayMs = (long) (delayMs * multiplier); + executeWork(resultFuture, work, startTime, newRetryDelayMs, errors); + }, + delayWithJitterMs, + TimeUnit.MILLISECONDS); } - private void executeWork( CompletableFuture resultFuture, Supplier> work, - long startTime, long retryDelayMs, List errors ) - { + private void executeWork( + CompletableFuture resultFuture, + Supplier> work, + long startTime, + long retryDelayMs, + List errors) { CompletionStage workStage; - try - { + try { workStage = work.get(); - } - catch ( Throwable error ) - { + } catch (Throwable error) { // work failed in a sync way, attempt to schedule a retry - retryOnError( resultFuture, work, startTime, retryDelayMs, error, errors ); + retryOnError(resultFuture, work, startTime, retryDelayMs, error, errors); return; } - workStage.whenComplete( ( result, completionError ) -> - { - Throwable error = Futures.completionExceptionCause( completionError ); - if ( error != null ) - { + workStage.whenComplete((result, completionError) -> { + Throwable error = Futures.completionExceptionCause(completionError); + if (error != null) { // work failed in async way, attempt to schedule a retry - retryOnError( resultFuture, work, startTime, retryDelayMs, error, errors ); - } - else - { - resultFuture.complete( result ); + retryOnError(resultFuture, work, startTime, retryDelayMs, error, errors); + } else { + resultFuture.complete(result); } - } ); + }); } - private void retryOnError( CompletableFuture resultFuture, Supplier> work, long startTime, long retryDelayMs, Throwable throwable, - List errors ) - { - Throwable error = extractPossibleTerminationCause( throwable ); - if ( canRetryOn( error ) ) - { + private void retryOnError( + CompletableFuture resultFuture, + Supplier> work, + long startTime, + long retryDelayMs, + Throwable throwable, + List errors) { + Throwable error = extractPossibleTerminationCause(throwable); + if (canRetryOn(error)) { long currentTime = clock.millis(); - if ( startTime == -1 ) - { + if (startTime == -1) { startTime = currentTime; } long elapsedTime = currentTime - startTime; - if ( elapsedTime < maxRetryTimeMs ) - { - errors = recordError( error, errors ); - retryWorkInEventLoop( resultFuture, work, error, startTime, retryDelayMs, errors ); + if (elapsedTime < maxRetryTimeMs) { + errors = recordError(error, errors); + retryWorkInEventLoop(resultFuture, work, error, startTime, retryDelayMs, errors); return; } } - addSuppressed( throwable, errors ); - resultFuture.completeExceptionally( throwable ); + addSuppressed(throwable, errors); + resultFuture.completeExceptionally(throwable); } - private long computeDelayWithJitter( long delayMs ) - { - if ( delayMs > MAX_RETRY_DELAY ) - { + private long computeDelayWithJitter(long delayMs) { + if (delayMs > MAX_RETRY_DELAY) { delayMs = MAX_RETRY_DELAY; } long jitter = (long) (delayMs * jitterFactor); long min = delayMs - jitter; long max = delayMs + jitter; - return ThreadLocalRandom.current().nextLong( min, max + 1 ); + return ThreadLocalRandom.current().nextLong(min, max + 1); } - private void sleep( long delayMs ) - { - try - { - clock.sleep( delayMs ); - } - catch ( InterruptedException e ) - { + private void sleep(long delayMs) { + try { + clock.sleep(delayMs); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new IllegalStateException( "Retries interrupted", e ); + throw new IllegalStateException("Retries interrupted", e); } } - private void verifyAfterConstruction() - { - if ( maxRetryTimeMs < 0 ) - { - throw new IllegalArgumentException( "Max retry time should be >= 0: " + maxRetryTimeMs ); + private void verifyAfterConstruction() { + if (maxRetryTimeMs < 0) { + throw new IllegalArgumentException("Max retry time should be >= 0: " + maxRetryTimeMs); } - if ( initialRetryDelayMs < 0 ) - { - throw new IllegalArgumentException( "Initial retry delay should >= 0: " + initialRetryDelayMs ); + if (initialRetryDelayMs < 0) { + throw new IllegalArgumentException("Initial retry delay should >= 0: " + initialRetryDelayMs); } - if ( multiplier < 1.0 ) - { - throw new IllegalArgumentException( "Multiplier should be >= 1.0: " + multiplier ); + if (multiplier < 1.0) { + throw new IllegalArgumentException("Multiplier should be >= 1.0: " + multiplier); } - if ( jitterFactor < 0 || jitterFactor > 1 ) - { - throw new IllegalArgumentException( "Jitter factor should be in [0.0, 1.0]: " + jitterFactor ); + if (jitterFactor < 0 || jitterFactor > 1) { + throw new IllegalArgumentException("Jitter factor should be in [0.0, 1.0]: " + jitterFactor); } - if ( clock == null ) - { - throw new IllegalArgumentException( "Clock should not be null" ); + if (clock == null) { + throw new IllegalArgumentException("Clock should not be null"); } } - private static boolean isTransientError( Throwable error ) - { - if ( error instanceof TransientException ) - { + private static boolean isTransientError(Throwable error) { + if (error instanceof TransientException) { String code = ((TransientException) error).code(); // Retries should not happen when transaction was explicitly terminated by the user. // Termination of transaction might result in two different error codes depending on where it was // terminated. These are really client errors but classification on the server is not entirely correct and // they are classified as transient. - if ( "Neo.TransientError.Transaction.Terminated".equals( code ) || - "Neo.TransientError.Transaction.LockClientStopped".equals( code ) ) - { + if ("Neo.TransientError.Transaction.Terminated".equals(code) + || "Neo.TransientError.Transaction.LockClientStopped".equals(code)) { return false; } return true; @@ -370,25 +353,19 @@ private static boolean isTransientError( Throwable error ) return false; } - private static List recordError( Throwable error, List errors ) - { - if ( errors == null ) - { + private static List recordError(Throwable error, List errors) { + if (errors == null) { errors = new ArrayList<>(); } - errors.add( error ); + errors.add(error); return errors; } - private static void addSuppressed( Throwable error, List suppressedErrors ) - { - if ( suppressedErrors != null ) - { - for ( Throwable suppressedError : suppressedErrors ) - { - if ( error != suppressedError ) - { - error.addSuppressed( suppressedError ); + private static void addSuppressed(Throwable error, List suppressedErrors) { + if (suppressedErrors != null) { + for (Throwable suppressedError : suppressedErrors) { + if (error != suppressedError) { + error.addSuppressed(suppressedError); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/retry/RetryLogic.java b/driver/src/main/java/org/neo4j/driver/internal/retry/RetryLogic.java index 80821c111b..a88ffbff52 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/retry/RetryLogic.java +++ b/driver/src/main/java/org/neo4j/driver/internal/retry/RetryLogic.java @@ -18,16 +18,14 @@ */ package org.neo4j.driver.internal.retry; -import org.reactivestreams.Publisher; - import java.util.concurrent.CompletionStage; import java.util.function.Supplier; +import org.reactivestreams.Publisher; -public interface RetryLogic -{ - T retry( Supplier work ); +public interface RetryLogic { + T retry(Supplier work); - CompletionStage retryAsync( Supplier> work ); + CompletionStage retryAsync(Supplier> work); - Publisher retryRx( Publisher work ); + Publisher retryRx(Publisher work); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/retry/RetrySettings.java b/driver/src/main/java/org/neo4j/driver/internal/retry/RetrySettings.java index b9f650e9b2..99cbc56f37 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/retry/RetrySettings.java +++ b/driver/src/main/java/org/neo4j/driver/internal/retry/RetrySettings.java @@ -20,22 +20,19 @@ import java.io.Serializable; -public final class RetrySettings implements Serializable -{ +public final class RetrySettings implements Serializable { private static final long serialVersionUID = -2895062473220745239L; public static final RetrySettings DEFAULT = - new RetrySettings( ExponentialBackoffRetryLogic.DEFAULT_MAX_RETRY_TIME_MS ); + new RetrySettings(ExponentialBackoffRetryLogic.DEFAULT_MAX_RETRY_TIME_MS); private final long maxRetryTimeMs; - public RetrySettings( long maxRetryTimeMs ) - { + public RetrySettings(long maxRetryTimeMs) { this.maxRetryTimeMs = maxRetryTimeMs; } - public long maxRetryTimeMs() - { + public long maxRetryTimeMs() { return maxRetryTimeMs; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/security/InternalAuthToken.java b/driver/src/main/java/org/neo4j/driver/internal/security/InternalAuthToken.java index 2d6d721896..6b12dc08ab 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/security/InternalAuthToken.java +++ b/driver/src/main/java/org/neo4j/driver/internal/security/InternalAuthToken.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.security; import java.util.Map; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.Value; @@ -27,43 +26,39 @@ * A simple common token for authentication schemes that easily convert to * an auth token map */ -public class InternalAuthToken implements AuthToken -{ +public class InternalAuthToken implements AuthToken { public static final String SCHEME_KEY = "scheme"; public static final String PRINCIPAL_KEY = "principal"; public static final String CREDENTIALS_KEY = "credentials"; public static final String REALM_KEY = "realm"; public static final String PARAMETERS_KEY = "parameters"; - private final Map content; + private final Map content; - public InternalAuthToken( Map content ) - { + public InternalAuthToken(Map content) { this.content = content; } - public Map toMap() - { + public Map toMap() { return content; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { return true; } - if ( o == null || getClass() != o.getClass() ) - { return false; } + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } InternalAuthToken that = (InternalAuthToken) o; - return content != null ? content.equals( that.content ) : that.content == null; - + return content != null ? content.equals(that.content) : that.content == null; } @Override - public int hashCode() - { + public int hashCode() { return content != null ? content.hashCode() : 0; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/security/SecurityPlan.java b/driver/src/main/java/org/neo4j/driver/internal/security/SecurityPlan.java index eec9f17381..0bef2dbd82 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/security/SecurityPlan.java +++ b/driver/src/main/java/org/neo4j/driver/internal/security/SecurityPlan.java @@ -19,14 +19,12 @@ package org.neo4j.driver.internal.security; import javax.net.ssl.SSLContext; - import org.neo4j.driver.internal.RevocationStrategy; /** * A SecurityPlan consists of encryption and trust details. */ -public interface SecurityPlan -{ +public interface SecurityPlan { boolean requiresEncryption(); SSLContext sslContext(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/security/SecurityPlanImpl.java b/driver/src/main/java/org/neo4j/driver/internal/security/SecurityPlanImpl.java index 622b3f472a..ab95babf67 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/security/SecurityPlanImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/security/SecurityPlanImpl.java @@ -18,6 +18,10 @@ */ package org.neo4j.driver.internal.security; +import static org.neo4j.driver.internal.RevocationStrategy.VERIFY_IF_PRESENT; +import static org.neo4j.driver.internal.RevocationStrategy.requiresRevocationChecking; +import static org.neo4j.driver.internal.util.CertificateTool.loadX509Cert; + import java.io.File; import java.io.IOException; import java.security.GeneralSecurityException; @@ -37,132 +41,112 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; - import org.neo4j.driver.internal.RevocationStrategy; -import static org.neo4j.driver.internal.RevocationStrategy.VERIFY_IF_PRESENT; -import static org.neo4j.driver.internal.RevocationStrategy.requiresRevocationChecking; -import static org.neo4j.driver.internal.util.CertificateTool.loadX509Cert; - /** * A SecurityPlan consists of encryption and trust details. */ -public class SecurityPlanImpl implements SecurityPlan -{ - public static SecurityPlan forAllCertificates( boolean requiresHostnameVerification, RevocationStrategy revocationStrategy ) throws GeneralSecurityException - { - SSLContext sslContext = SSLContext.getInstance( "TLS" ); - sslContext.init( new KeyManager[0], new TrustManager[]{new TrustAllTrustManager()}, null ); - - return new SecurityPlanImpl( true, sslContext, requiresHostnameVerification, revocationStrategy ); +public class SecurityPlanImpl implements SecurityPlan { + public static SecurityPlan forAllCertificates( + boolean requiresHostnameVerification, RevocationStrategy revocationStrategy) + throws GeneralSecurityException { + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(new KeyManager[0], new TrustManager[] {new TrustAllTrustManager()}, null); + + return new SecurityPlanImpl(true, sslContext, requiresHostnameVerification, revocationStrategy); } - public static SecurityPlan forCustomCASignedCertificates( List certFiles, boolean requiresHostnameVerification, - RevocationStrategy revocationStrategy ) - throws GeneralSecurityException, IOException - { - SSLContext sslContext = configureSSLContext( certFiles, revocationStrategy ); - return new SecurityPlanImpl( true, sslContext, requiresHostnameVerification, revocationStrategy ); + public static SecurityPlan forCustomCASignedCertificates( + List certFiles, boolean requiresHostnameVerification, RevocationStrategy revocationStrategy) + throws GeneralSecurityException, IOException { + SSLContext sslContext = configureSSLContext(certFiles, revocationStrategy); + return new SecurityPlanImpl(true, sslContext, requiresHostnameVerification, revocationStrategy); } - public static SecurityPlan forSystemCASignedCertificates( boolean requiresHostnameVerification, RevocationStrategy revocationStrategy ) - throws GeneralSecurityException, IOException - { - SSLContext sslContext = configureSSLContext( Collections.emptyList(), revocationStrategy ); - return new SecurityPlanImpl( true, sslContext, requiresHostnameVerification, revocationStrategy ); + public static SecurityPlan forSystemCASignedCertificates( + boolean requiresHostnameVerification, RevocationStrategy revocationStrategy) + throws GeneralSecurityException, IOException { + SSLContext sslContext = configureSSLContext(Collections.emptyList(), revocationStrategy); + return new SecurityPlanImpl(true, sslContext, requiresHostnameVerification, revocationStrategy); } - private static SSLContext configureSSLContext( List customCertFiles, RevocationStrategy revocationStrategy ) - throws GeneralSecurityException, IOException - { - KeyStore trustedKeyStore = KeyStore.getInstance( KeyStore.getDefaultType() ); - trustedKeyStore.load( null, null ); + private static SSLContext configureSSLContext(List customCertFiles, RevocationStrategy revocationStrategy) + throws GeneralSecurityException, IOException { + KeyStore trustedKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + trustedKeyStore.load(null, null); - if ( !customCertFiles.isEmpty() ) - { + if (!customCertFiles.isEmpty()) { // Certificate files are specified, so we will load the certificates in the file - loadX509Cert( customCertFiles, trustedKeyStore ); - } - else - { - loadSystemCertificates( trustedKeyStore ); + loadX509Cert(customCertFiles, trustedKeyStore); + } else { + loadSystemCertificates(trustedKeyStore); } - PKIXBuilderParameters pkixBuilderParameters = configurePKIXBuilderParameters( trustedKeyStore, revocationStrategy ); + PKIXBuilderParameters pkixBuilderParameters = + configurePKIXBuilderParameters(trustedKeyStore, revocationStrategy); - SSLContext sslContext = SSLContext.getInstance( "TLS" ); - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); + SSLContext sslContext = SSLContext.getInstance("TLS"); + TrustManagerFactory trustManagerFactory = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - if ( pkixBuilderParameters == null ) - { - trustManagerFactory.init( trustedKeyStore ); - } - else - { - trustManagerFactory.init( new CertPathTrustManagerParameters( pkixBuilderParameters ) ); + if (pkixBuilderParameters == null) { + trustManagerFactory.init(trustedKeyStore); + } else { + trustManagerFactory.init(new CertPathTrustManagerParameters(pkixBuilderParameters)); } - sslContext.init( new KeyManager[0], trustManagerFactory.getTrustManagers(), null ); + sslContext.init(new KeyManager[0], trustManagerFactory.getTrustManagers(), null); return sslContext; } - private static PKIXBuilderParameters configurePKIXBuilderParameters( KeyStore trustedKeyStore, RevocationStrategy revocationStrategy ) throws InvalidAlgorithmParameterException, KeyStoreException - { + private static PKIXBuilderParameters configurePKIXBuilderParameters( + KeyStore trustedKeyStore, RevocationStrategy revocationStrategy) + throws InvalidAlgorithmParameterException, KeyStoreException { PKIXBuilderParameters pkixBuilderParameters = null; - if ( requiresRevocationChecking( revocationStrategy ) ) - { + if (requiresRevocationChecking(revocationStrategy)) { // Configure certificate revocation checking (X509CertSelector() selects all certificates) - pkixBuilderParameters = new PKIXBuilderParameters( trustedKeyStore, new X509CertSelector() ); + pkixBuilderParameters = new PKIXBuilderParameters(trustedKeyStore, new X509CertSelector()); // sets checking of stapled ocsp response - pkixBuilderParameters.setRevocationEnabled( true ); + pkixBuilderParameters.setRevocationEnabled(true); // enables status_request extension in client hello - System.setProperty( "jdk.tls.client.enableStatusRequestExtension", "true" ); + System.setProperty("jdk.tls.client.enableStatusRequestExtension", "true"); - if ( revocationStrategy.equals( VERIFY_IF_PRESENT ) ) - { + if (revocationStrategy.equals(VERIFY_IF_PRESENT)) { // enables soft-fail behaviour if no stapled response found. - Security.setProperty( "ocsp.enable", "true" ); + Security.setProperty("ocsp.enable", "true"); } } return pkixBuilderParameters; } - private static void loadSystemCertificates( KeyStore trustedKeyStore ) throws GeneralSecurityException, IOException - { + private static void loadSystemCertificates(KeyStore trustedKeyStore) throws GeneralSecurityException, IOException { // To customize the PKIXParameters we need to get hold of the default KeyStore, no other elegant way available - TrustManagerFactory tempFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); - tempFactory.init( (KeyStore) null ); + TrustManagerFactory tempFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tempFactory.init((KeyStore) null); // Get hold of the default trust manager X509TrustManager x509TrustManager = null; - for ( TrustManager trustManager : tempFactory.getTrustManagers() ) - { - if ( trustManager instanceof X509TrustManager ) - { + for (TrustManager trustManager : tempFactory.getTrustManagers()) { + if (trustManager instanceof X509TrustManager) { x509TrustManager = (X509TrustManager) trustManager; break; } } - if ( x509TrustManager == null ) - { - throw new CertificateException( "No system certificates found" ); - } - else - { + if (x509TrustManager == null) { + throw new CertificateException("No system certificates found"); + } else { // load system default certificates into KeyStore - loadX509Cert( x509TrustManager.getAcceptedIssuers(), trustedKeyStore ); + loadX509Cert(x509TrustManager.getAcceptedIssuers(), trustedKeyStore); } } - public static SecurityPlan insecure() - { - return new SecurityPlanImpl( false, null, false, - RevocationStrategy.NO_CHECKS ); + public static SecurityPlan insecure() { + return new SecurityPlanImpl(false, null, false, RevocationStrategy.NO_CHECKS); } private final boolean requiresEncryption; @@ -170,8 +154,11 @@ public static SecurityPlan insecure() private final boolean requiresHostnameVerification; private final RevocationStrategy revocationStrategy; - private SecurityPlanImpl( boolean requiresEncryption, SSLContext sslContext, boolean requiresHostnameVerification, RevocationStrategy revocationStrategy ) - { + private SecurityPlanImpl( + boolean requiresEncryption, + SSLContext sslContext, + boolean requiresHostnameVerification, + RevocationStrategy revocationStrategy) { this.requiresEncryption = requiresEncryption; this.sslContext = sslContext; this.requiresHostnameVerification = requiresHostnameVerification; @@ -179,43 +166,35 @@ private SecurityPlanImpl( boolean requiresEncryption, SSLContext sslContext, boo } @Override - public boolean requiresEncryption() - { + public boolean requiresEncryption() { return requiresEncryption; } @Override - public SSLContext sslContext() - { + public SSLContext sslContext() { return sslContext; } @Override - public boolean requiresHostnameVerification() - { + public boolean requiresHostnameVerification() { return requiresHostnameVerification; } @Override - public RevocationStrategy revocationStrategy() - { + public RevocationStrategy revocationStrategy() { return revocationStrategy; } - private static class TrustAllTrustManager implements X509TrustManager - { - public void checkClientTrusted( X509Certificate[] chain, String authType ) throws CertificateException - { - throw new CertificateException( "All client connections to this client are forbidden." ); + private static class TrustAllTrustManager implements X509TrustManager { + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + throw new CertificateException("All client connections to this client are forbidden."); } - public void checkServerTrusted( X509Certificate[] chain, String authType ) throws CertificateException - { + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // all fine, pass through } - public X509Certificate[] getAcceptedIssuers() - { + public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/spi/Connection.java b/driver/src/main/java/org/neo4j/driver/internal/spi/Connection.java index f6d676c0e7..da8b1f5f84 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/spi/Connection.java +++ b/driver/src/main/java/org/neo4j/driver/internal/spi/Connection.java @@ -18,8 +18,9 @@ */ package org.neo4j.driver.internal.spi; -import java.util.concurrent.CompletionStage; +import static java.lang.String.format; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DatabaseName; @@ -27,29 +28,26 @@ import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.util.ServerVersion; -import static java.lang.String.format; - -public interface Connection -{ +public interface Connection { boolean isOpen(); void enableAutoRead(); void disableAutoRead(); - void write( Message message, ResponseHandler handler ); + void write(Message message, ResponseHandler handler); - void write( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ); + void write(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2); - void writeAndFlush( Message message, ResponseHandler handler ); + void writeAndFlush(Message message, ResponseHandler handler); - void writeAndFlush( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ); + void writeAndFlush(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2); CompletionStage reset(); CompletionStage release(); - void terminateAndRelease( String reason ); + void terminateAndRelease(String reason); String serverAgent(); @@ -59,19 +57,16 @@ public interface Connection BoltProtocol protocol(); - default AccessMode mode() - { - throw new UnsupportedOperationException( format( "%s does not support access mode.", getClass() ) ); + default AccessMode mode() { + throw new UnsupportedOperationException(format("%s does not support access mode.", getClass())); } - default DatabaseName databaseName() - { - throw new UnsupportedOperationException( format( "%s does not support database name.", getClass() ) ); + default DatabaseName databaseName() { + throw new UnsupportedOperationException(format("%s does not support database name.", getClass())); } - default String impersonatedUser() - { - throw new UnsupportedOperationException( format( "%s does not support impersonated user.", getClass() ) ); + default String impersonatedUser() { + throw new UnsupportedOperationException(format("%s does not support impersonated user.", getClass())); } void flush(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionPool.java b/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionPool.java index f86242b9ee..dd8eef4c41 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionPool.java +++ b/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionPool.java @@ -20,23 +20,21 @@ import java.util.Set; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.net.ServerAddress; -public interface ConnectionPool -{ +public interface ConnectionPool { String CONNECTION_POOL_CLOSED_ERROR_MESSAGE = "Pool closed"; - CompletionStage acquire( BoltServerAddress address ); + CompletionStage acquire(BoltServerAddress address); - void retainAll( Set addressesToRetain ); + void retainAll(Set addressesToRetain); - int inUseConnections( ServerAddress address ); + int inUseConnections(ServerAddress address); - int idleConnections( ServerAddress address ); + int idleConnections(ServerAddress address); CompletionStage close(); - boolean isOpen( BoltServerAddress address ); + boolean isOpen(BoltServerAddress address); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionProvider.java b/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionProvider.java index 09b3b3e07c..bc95b94126 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/spi/ConnectionProvider.java @@ -19,16 +19,14 @@ package org.neo4j.driver.internal.spi; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.internal.async.ConnectionContext; /** * Interface defines a layer used by the driver to obtain connections. It is meant to be the only component that * differs between "direct" and "routing" driver. */ -public interface ConnectionProvider -{ - CompletionStage acquireConnection( ConnectionContext context ); +public interface ConnectionProvider { + CompletionStage acquireConnection(ConnectionContext context); /** * The validation of connectivity will happen with the default database. diff --git a/driver/src/main/java/org/neo4j/driver/internal/spi/ResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/spi/ResponseHandler.java index 3946edf121..dca6c3fc30 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/spi/ResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/spi/ResponseHandler.java @@ -19,17 +19,15 @@ package org.neo4j.driver.internal.spi; import java.util.Map; - -import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.Value; +import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; -public interface ResponseHandler -{ - void onSuccess( Map metadata ); +public interface ResponseHandler { + void onSuccess(Map metadata); - void onFailure( Throwable error ); + void onFailure(Throwable error); - void onRecord( Value[] fields ); + void onRecord(Value[] fields); /** * Tells whether this response handler is able to manage auto-read of the underlying connection using {@link Connection#enableAutoRead()} and @@ -40,8 +38,7 @@ public interface ResponseHandler * racing with each other. {@link InboundMessageDispatcher} is responsible for tracking these handlers and disabling auto-read management to maintain just * a single auto-read managing handler per connection. */ - default boolean canManageAutoRead() - { + default boolean canManageAutoRead() { return false; } @@ -49,8 +46,5 @@ default boolean canManageAutoRead() * If this response handler is able to manage auto-read of the underlying connection, then this method signals it to * stop changing auto-read setting for the connection. */ - default void disableAutoReadManagement() - { - - } + default void disableAutoReadManagement() {} } diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalDatabaseInfo.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalDatabaseInfo.java index 6741af1856..8c83c9e4eb 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalDatabaseInfo.java +++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalDatabaseInfo.java @@ -19,50 +19,41 @@ package org.neo4j.driver.internal.summary; import java.util.Objects; - import org.neo4j.driver.summary.DatabaseInfo; -public class InternalDatabaseInfo implements DatabaseInfo -{ - public static DatabaseInfo DEFAULT_DATABASE_INFO = new InternalDatabaseInfo( null ); +public class InternalDatabaseInfo implements DatabaseInfo { + public static DatabaseInfo DEFAULT_DATABASE_INFO = new InternalDatabaseInfo(null); private final String name; - public InternalDatabaseInfo( String name ) - { + public InternalDatabaseInfo(String name) { this.name = name; } @Override - public String name() - { + public String name() { return this.name; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalDatabaseInfo that = (InternalDatabaseInfo) o; - return Objects.equals( name, that.name ); + return Objects.equals(name, that.name); } @Override - public int hashCode() - { - return Objects.hash( name ); + public int hashCode() { + return Objects.hash(name); } @Override - public String toString() - { + public String toString() { return "InternalDatabaseInfo{" + "name='" + name + '\'' + '}'; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalInputPosition.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalInputPosition.java index 5124a4192e..24aff9b8ad 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalInputPosition.java +++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalInputPosition.java @@ -19,14 +19,12 @@ package org.neo4j.driver.internal.summary; import java.util.Objects; - import org.neo4j.driver.summary.InputPosition; /** * An input position refers to a specific point in a query string. */ -public class InternalInputPosition implements InputPosition -{ +public class InternalInputPosition implements InputPosition { private final int offset; private final int line; private final int column; @@ -38,57 +36,46 @@ public class InternalInputPosition implements InputPosition * @param line the line number, starting from 1. * @param column the column number, starting from 1. */ - public InternalInputPosition( int offset, int line, int column ) - { + public InternalInputPosition(int offset, int line, int column) { this.offset = offset; this.line = line; this.column = column; } @Override - public int offset() - { + public int offset() { return offset; } @Override - public int line() - { + public int line() { return line; } @Override - public int column() - { + public int column() { return column; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalInputPosition that = (InternalInputPosition) o; - return offset == that.offset && - line == that.line && - column == that.column; + return offset == that.offset && line == that.line && column == that.column; } @Override - public int hashCode() - { - return Objects.hash( offset, line, column ); + public int hashCode() { + return Objects.hash(offset, line, column); } @Override - public String toString() - { + public String toString() { return "offset=" + offset + ", line=" + line + ", column=" + column; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java index 364d0ab0ed..a1f9082eef 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java +++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java @@ -18,37 +18,33 @@ */ package org.neo4j.driver.internal.summary; +import static org.neo4j.driver.internal.value.NullValue.NULL; + import java.util.function.Function; +import org.neo4j.driver.Value; import org.neo4j.driver.summary.InputPosition; import org.neo4j.driver.summary.Notification; -import org.neo4j.driver.Value; - -import static org.neo4j.driver.internal.value.NullValue.NULL; -public class InternalNotification implements Notification -{ - public static final Function VALUE_TO_NOTIFICATION = new Function() - { +public class InternalNotification implements Notification { + public static final Function VALUE_TO_NOTIFICATION = new Function() { @Override - public Notification apply( Value value ) - { - String code = value.get( "code" ).asString(); - String title = value.get( "title" ).asString(); - String description = value.get( "description" ).asString(); - String severity = value.containsKey( "severity" ) ? - value.get( "severity" ).asString() - : "N/A"; + public Notification apply(Value value) { + String code = value.get("code").asString(); + String title = value.get("title").asString(); + String description = value.get("description").asString(); + String severity = + value.containsKey("severity") ? value.get("severity").asString() : "N/A"; - Value posValue = value.get( "position" ); + Value posValue = value.get("position"); InputPosition position = null; - if( posValue != NULL ) - { - position = new InternalInputPosition( posValue.get( "offset" ).asInt(), - posValue.get( "line" ).asInt(), - posValue.get( "column" ).asInt() ); + if (posValue != NULL) { + position = new InternalInputPosition( + posValue.get("offset").asInt(), + posValue.get("line").asInt(), + posValue.get("column").asInt()); } - return new InternalNotification( code, title, description, severity, position ); + return new InternalNotification(code, title, description, severity, position); } }; @@ -58,8 +54,8 @@ public Notification apply( Value value ) private final String severity; private final InputPosition position; - public InternalNotification( String code, String title, String description, String severity, InputPosition position ) - { + public InternalNotification( + String code, String title, String description, String severity, InputPosition position) { this.code = code; this.title = title; this.description = description; @@ -68,38 +64,32 @@ public InternalNotification( String code, String title, String description, Stri } @Override - public String code() - { + public String code() { return code; } @Override - public String title() - { + public String title() { return title; } @Override - public String description() - { + public String description() { return description; } @Override - public InputPosition position() - { + public InputPosition position() { return position; } @Override - public String severity() - { + public String severity() { return severity; } @Override - public String toString() - { + public String toString() { String info = "code=" + code + ", title=" + title + ", description=" + description + ", severity=" + severity; return position == null ? info : info + ", position={" + position + "}"; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalPlan.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalPlan.java index ec675c0369..d494b67750 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalPlan.java +++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalPlan.java @@ -18,20 +18,18 @@ */ package org.neo4j.driver.internal.summary; +import static java.lang.String.format; +import static org.neo4j.driver.Values.ofString; + import java.util.Collections; import java.util.List; import java.util.Map; - +import java.util.function.Function; import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.summary.Plan; -import java.util.function.Function; -import static java.lang.String.format; -import static org.neo4j.driver.Values.ofString; - -public class InternalPlan implements Plan -{ +public class InternalPlan implements Plan { private final String operatorType; private final List identifiers; private final Map arguments; @@ -39,11 +37,7 @@ public class InternalPlan implements Plan // Only call when sub-classing, for constructing plans, use .plan instead protected InternalPlan( - String operatorType, - Map arguments, - List identifiers, - List children ) - { + String operatorType, Map arguments, List identifiers, List children) { this.operatorType = operatorType; this.identifiers = identifiers; this.arguments = arguments; @@ -51,61 +45,51 @@ protected InternalPlan( } @Override - public String operatorType() - { + public String operatorType() { return operatorType; } @Override - public List identifiers() - { + public List identifiers() { return identifiers; } @Override - public Map arguments() - { + public Map arguments() { return arguments; } @Override - public List children() - { + public List children() { return children; } @Override - public String toString() - { + public String toString() { return format( - "SimplePlanTreeNode{operatorType='%s', arguments=%s, identifiers=%s, children=%s}", - operatorType, arguments, identifiers, children - ); + "SimplePlanTreeNode{operatorType='%s', arguments=%s, identifiers=%s, children=%s}", + operatorType, arguments, identifiers, children); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalPlan that = (InternalPlan) o; - return operatorType.equals( that.operatorType ) - && arguments.equals( that.arguments ) - && identifiers.equals( that.identifiers ) - && children.equals( that.children ); + return operatorType.equals(that.operatorType) + && arguments.equals(that.arguments) + && identifiers.equals(that.identifiers) + && children.equals(that.children); } @Override - public int hashCode() - { + public int hashCode() { int result = operatorType.hashCode(); result = 31 * result + identifiers.hashCode(); result = 31 * result + arguments.hashCode(); @@ -114,20 +98,19 @@ public int hashCode() } public static Plan plan( - String operatorType, - Map arguments, - List identifiers, - List children ) - { - return EXPLAIN_PLAN.create( operatorType, arguments, identifiers, children, null ); + String operatorType, Map arguments, List identifiers, List children) { + return EXPLAIN_PLAN.create(operatorType, arguments, identifiers, children, null); } - public static final PlanCreator EXPLAIN_PLAN = new PlanCreator() - { + public static final PlanCreator EXPLAIN_PLAN = new PlanCreator() { @Override - public Plan create( String operatorType, Map arguments, List identifiers, List children, Value originalPlanValue ) - { - return new InternalPlan<>( operatorType, arguments, identifiers, children ); + public Plan create( + String operatorType, + Map arguments, + List identifiers, + List children, + Value originalPlanValue) { + return new InternalPlan<>(operatorType, arguments, identifiers, children); } }; @@ -139,46 +122,39 @@ public Plan create( String operatorType, Map arguments, List */ - interface PlanCreator - { - T create( String operatorType, - Map arguments, - List identifiers, - List children, - Value originalPlanValue ); + interface PlanCreator { + T create( + String operatorType, + Map arguments, + List identifiers, + List children, + Value originalPlanValue); } - static class Converter implements Function - { + static class Converter implements Function { private final PlanCreator planCreator; - public Converter( PlanCreator planCreator ) - { + public Converter(PlanCreator planCreator) { this.planCreator = planCreator; } @Override - public T apply( Value plan ) - { - final String operatorType = plan.get( "operatorType" ).asString(); + public T apply(Value plan) { + final String operatorType = plan.get("operatorType").asString(); - final Value argumentsValue = plan.get( "args" ); + final Value argumentsValue = plan.get("args"); final Map arguments = argumentsValue.isNull() ? Collections.emptyMap() - : argumentsValue.asMap( Values.ofValue() ); + : argumentsValue.asMap(Values.ofValue()); - final Value identifiersValue = plan.get( "identifiers" ); - final List identifiers = identifiersValue.isNull() - ? Collections.emptyList() - : identifiersValue.asList( ofString() ); + final Value identifiersValue = plan.get("identifiers"); + final List identifiers = + identifiersValue.isNull() ? Collections.emptyList() : identifiersValue.asList(ofString()); - final Value childrenValue = plan.get( "children" ); - final List children = childrenValue.isNull() - ? Collections.emptyList() - : childrenValue.asList( this ); + final Value childrenValue = plan.get("children"); + final List children = childrenValue.isNull() ? Collections.emptyList() : childrenValue.asList(this); - return planCreator.create( operatorType, arguments, identifiers, children, plan ); + return planCreator.create(operatorType, arguments, identifiers, children, plan); } } } - diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalProfiledPlan.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalProfiledPlan.java index b73335eaf1..c9d0949ffe 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalProfiledPlan.java +++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalProfiledPlan.java @@ -21,12 +21,10 @@ import java.util.List; import java.util.Map; import java.util.function.Function; - import org.neo4j.driver.Value; import org.neo4j.driver.summary.ProfiledPlan; -public class InternalProfiledPlan extends InternalPlan implements ProfiledPlan -{ +public class InternalProfiledPlan extends InternalPlan implements ProfiledPlan { private final long dbHits; private final long records; private final long pageCacheHits; @@ -34,10 +32,18 @@ public class InternalProfiledPlan extends InternalPlan implements private final double pageCacheHitRatio; private final long time; - protected InternalProfiledPlan( String operatorType, Map arguments, List identifiers, List children, long dbHits, - long records, long pageCacheHits, long pageCacheMisses, double pageCacheHitRatio, long time ) - { - super( operatorType, arguments, identifiers, children ); + protected InternalProfiledPlan( + String operatorType, + Map arguments, + List identifiers, + List children, + long dbHits, + long records, + long pageCacheHits, + long pageCacheMisses, + double pageCacheHitRatio, + long time) { + super(operatorType, arguments, identifiers, children); this.dbHits = dbHits; this.records = records; this.pageCacheHits = pageCacheHits; @@ -47,62 +53,64 @@ protected InternalProfiledPlan( String operatorType, Map arguments } @Override - public long dbHits() - { + public long dbHits() { return dbHits; } @Override - public long records() - { + public long records() { return records; } @Override - public boolean hasPageCacheStats() - { + public boolean hasPageCacheStats() { return pageCacheHits > 0 || pageCacheMisses > 0 || pageCacheHitRatio > 0; } @Override - public long pageCacheHits() - { + public long pageCacheHits() { return pageCacheHits; } @Override - public long pageCacheMisses() - { + public long pageCacheMisses() { return pageCacheMisses; } @Override - public double pageCacheHitRatio() - { + public double pageCacheHitRatio() { return pageCacheHitRatio; } @Override - public long time() - { + public long time() { return time; } - public static final PlanCreator PROFILED_PLAN = new PlanCreator() - { + public static final PlanCreator PROFILED_PLAN = new PlanCreator() { @Override - public ProfiledPlan create( String operatorType, Map arguments, List identifiers, List children, - Value originalPlanValue ) - { - return new InternalProfiledPlan( operatorType, arguments, identifiers, children, originalPlanValue.get( "dbHits" ).asLong( 0 ), - originalPlanValue.get( "rows" ).asLong( 0 ), originalPlanValue.get( "pageCacheHits" ).asLong( 0 ), - originalPlanValue.get( "pageCacheMisses" ).asLong( 0 ), originalPlanValue.get( "pageCacheHitRatio" ).asDouble( 0 ), - originalPlanValue.get( "time" ).asLong( 0 ) ); + public ProfiledPlan create( + String operatorType, + Map arguments, + List identifiers, + List children, + Value originalPlanValue) { + return new InternalProfiledPlan( + operatorType, + arguments, + identifiers, + children, + originalPlanValue.get("dbHits").asLong(0), + originalPlanValue.get("rows").asLong(0), + originalPlanValue.get("pageCacheHits").asLong(0), + originalPlanValue.get("pageCacheMisses").asLong(0), + originalPlanValue.get("pageCacheHitRatio").asDouble(0), + originalPlanValue.get("time").asLong(0)); } }; /** * Builds a regular plan without profiling information - eg. a plan that came as a result of an `EXPLAIN` query */ - public static final Function PROFILED_PLAN_FROM_VALUE = new Converter<>( PROFILED_PLAN ); + public static final Function PROFILED_PLAN_FROM_VALUE = new Converter<>(PROFILED_PLAN); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalResultSummary.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalResultSummary.java index 04c21cb6b5..4b786f80e4 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalResultSummary.java +++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalResultSummary.java @@ -22,19 +22,17 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; - import org.neo4j.driver.Query; import org.neo4j.driver.summary.DatabaseInfo; import org.neo4j.driver.summary.Notification; import org.neo4j.driver.summary.Plan; import org.neo4j.driver.summary.ProfiledPlan; +import org.neo4j.driver.summary.QueryType; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.summary.ServerInfo; -import org.neo4j.driver.summary.QueryType; import org.neo4j.driver.summary.SummaryCounters; -public class InternalResultSummary implements ResultSummary -{ +public class InternalResultSummary implements ResultSummary { private final Query query; private final ServerInfo serverInfo; private final QueryType queryType; @@ -46,15 +44,23 @@ public class InternalResultSummary implements ResultSummary private final long resultConsumedAfter; private final DatabaseInfo databaseInfo; - public InternalResultSummary(Query query, ServerInfo serverInfo, DatabaseInfo databaseInfo, QueryType queryType, - SummaryCounters counters, Plan plan, ProfiledPlan profile, List notifications, long resultAvailableAfter, long resultConsumedAfter ) - { + public InternalResultSummary( + Query query, + ServerInfo serverInfo, + DatabaseInfo databaseInfo, + QueryType queryType, + SummaryCounters counters, + Plan plan, + ProfiledPlan profile, + List notifications, + long resultAvailableAfter, + long resultConsumedAfter) { this.query = query; this.serverInfo = serverInfo; this.databaseInfo = databaseInfo; this.queryType = queryType; this.counters = counters; - this.plan = resolvePlan( plan, profile ); + this.plan = resolvePlan(plan, profile); this.profile = profile; this.notifications = notifications; this.resultAvailableAfter = resultAvailableAfter; @@ -62,124 +68,116 @@ public InternalResultSummary(Query query, ServerInfo serverInfo, DatabaseInfo da } @Override - public Query query() - { + public Query query() { return query; } @Override - public SummaryCounters counters() - { + public SummaryCounters counters() { return counters == null ? InternalSummaryCounters.EMPTY_STATS : counters; } @Override - public QueryType queryType() - { + public QueryType queryType() { return queryType; } @Override - public boolean hasPlan() - { + public boolean hasPlan() { return plan != null; } @Override - public boolean hasProfile() - { + public boolean hasProfile() { return profile != null; } @Override - public Plan plan() - { + public Plan plan() { return plan; } @Override - public ProfiledPlan profile() - { + public ProfiledPlan profile() { return profile; } @Override - public List notifications() - { + public List notifications() { return notifications == null ? Collections.emptyList() : notifications; } @Override - public long resultAvailableAfter( TimeUnit unit ) - { - return resultAvailableAfter == -1 ? resultAvailableAfter - : unit.convert( resultAvailableAfter, TimeUnit.MILLISECONDS ); + public long resultAvailableAfter(TimeUnit unit) { + return resultAvailableAfter == -1 + ? resultAvailableAfter + : unit.convert(resultAvailableAfter, TimeUnit.MILLISECONDS); } @Override - public long resultConsumedAfter( TimeUnit unit ) - { - return resultConsumedAfter == -1 ? resultConsumedAfter - : unit.convert( resultConsumedAfter, TimeUnit.MILLISECONDS ); + public long resultConsumedAfter(TimeUnit unit) { + return resultConsumedAfter == -1 + ? resultConsumedAfter + : unit.convert(resultConsumedAfter, TimeUnit.MILLISECONDS); } @Override - public ServerInfo server() - { + public ServerInfo server() { return serverInfo; } @Override - public DatabaseInfo database() - { + public DatabaseInfo database() { return databaseInfo; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalResultSummary that = (InternalResultSummary) o; - return resultAvailableAfter == that.resultAvailableAfter && - resultConsumedAfter == that.resultConsumedAfter && - Objects.equals(query, that.query) && - Objects.equals( serverInfo, that.serverInfo ) && - queryType == that.queryType && - Objects.equals( counters, that.counters ) && - Objects.equals( plan, that.plan ) && - Objects.equals( profile, that.profile ) && - Objects.equals( notifications, that.notifications ); + return resultAvailableAfter == that.resultAvailableAfter + && resultConsumedAfter == that.resultConsumedAfter + && Objects.equals(query, that.query) + && Objects.equals(serverInfo, that.serverInfo) + && queryType == that.queryType + && Objects.equals(counters, that.counters) + && Objects.equals(plan, that.plan) + && Objects.equals(profile, that.profile) + && Objects.equals(notifications, that.notifications); } @Override - public int hashCode() - { - return Objects.hash(query, serverInfo, queryType, counters, plan, profile, notifications, - resultAvailableAfter, resultConsumedAfter ); + public int hashCode() { + return Objects.hash( + query, + serverInfo, + queryType, + counters, + plan, + profile, + notifications, + resultAvailableAfter, + resultConsumedAfter); } @Override - public String toString() - { - return "InternalResultSummary{" + - "query=" + query + - ", serverInfo=" + serverInfo + - ", databaseInfo=" + databaseInfo + - ", queryType=" + queryType + - ", counters=" + counters + - ", plan=" + plan + - ", profile=" + profile + - ", notifications=" + notifications + - ", resultAvailableAfter=" + resultAvailableAfter + - ", resultConsumedAfter=" + resultConsumedAfter + - '}'; + public String toString() { + return "InternalResultSummary{" + "query=" + + query + ", serverInfo=" + + serverInfo + ", databaseInfo=" + + databaseInfo + ", queryType=" + + queryType + ", counters=" + + counters + ", plan=" + + plan + ", profile=" + + profile + ", notifications=" + + notifications + ", resultAvailableAfter=" + + resultAvailableAfter + ", resultConsumedAfter=" + + resultConsumedAfter + '}'; } /** @@ -189,8 +187,7 @@ public String toString() * @param profiledPlan the given profiled plan, possibly {@code null}. * @return available plan. */ - private static Plan resolvePlan( Plan plan, ProfiledPlan profiledPlan ) - { + private static Plan resolvePlan(Plan plan, ProfiledPlan profiledPlan) { return plan == null ? profiledPlan : plan; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalServerInfo.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalServerInfo.java index 71ab8983b0..17919a8448 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalServerInfo.java +++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalServerInfo.java @@ -19,21 +19,19 @@ package org.neo4j.driver.internal.summary; import java.util.Objects; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.messaging.BoltProtocolVersion; import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.summary.ServerInfo; -public class InternalServerInfo implements ServerInfo -{ +public class InternalServerInfo implements ServerInfo { private final String agent; private final String address; private final String version; private final String protocolVersion; - public InternalServerInfo( String agent, BoltServerAddress address, ServerVersion version, BoltProtocolVersion protocolVersion ) - { + public InternalServerInfo( + String agent, BoltServerAddress address, ServerVersion version, BoltProtocolVersion protocolVersion) { this.agent = agent; this.address = address.toString(); this.version = version.toString(); @@ -41,53 +39,44 @@ public InternalServerInfo( String agent, BoltServerAddress address, ServerVersio } @Override - public String agent() - { + public String agent() { return agent; } @Override - public String address() - { + public String address() { return address; } @Override - public String version() - { + public String version() { return version; } @Override - public String protocolVersion() - { + public String protocolVersion() { return protocolVersion; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalServerInfo that = (InternalServerInfo) o; - return Objects.equals( address, that.address ) && Objects.equals( version, that.version ); + return Objects.equals(address, that.address) && Objects.equals(version, that.version); } @Override - public int hashCode() - { - return Objects.hash( address, version ); + public int hashCode() { + return Objects.hash(address, version); } @Override - public String toString() - { + public String toString() { return "InternalServerInfo{" + "address='" + address + '\'' + ", version='" + version + '\'' + '}'; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalSummaryCounters.java b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalSummaryCounters.java index fb90ea1cb1..2976a36af5 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/summary/InternalSummaryCounters.java +++ b/driver/src/main/java/org/neo4j/driver/internal/summary/InternalSummaryCounters.java @@ -20,10 +20,9 @@ import org.neo4j.driver.summary.SummaryCounters; -public class InternalSummaryCounters implements SummaryCounters -{ +public class InternalSummaryCounters implements SummaryCounters { public static final InternalSummaryCounters EMPTY_STATS = - new InternalSummaryCounters( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + new InternalSummaryCounters(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); private final int nodesCreated; private final int nodesDeleted; private final int relationshipsCreated; @@ -38,13 +37,18 @@ public class InternalSummaryCounters implements SummaryCounters private final int systemUpdates; public InternalSummaryCounters( - int nodesCreated, int nodesDeleted, - int relationshipsCreated, int relationshipsDeleted, + int nodesCreated, + int nodesDeleted, + int relationshipsCreated, + int relationshipsDeleted, int propertiesSet, - int labelsAdded, int labelsRemoved, - int indexesAdded, int indexesRemoved, - int constraintsAdded, int constraintsRemoved, int systemUpdates ) - { + int labelsAdded, + int labelsRemoved, + int indexesAdded, + int indexesRemoved, + int constraintsAdded, + int constraintsRemoved, + int systemUpdates) { this.nodesCreated = nodesCreated; this.nodesDeleted = nodesDeleted; this.relationshipsCreated = relationshipsCreated; @@ -60,131 +64,112 @@ public InternalSummaryCounters( } @Override - public boolean containsUpdates() - { - return - isPositive( nodesCreated ) - || isPositive( nodesDeleted ) - || isPositive( relationshipsCreated ) - || isPositive( relationshipsDeleted ) - || isPositive( propertiesSet ) - || isPositive( labelsAdded ) - || isPositive( labelsRemoved ) - || isPositive( indexesAdded ) - || isPositive( indexesRemoved ) - || isPositive( constraintsAdded ) - || isPositive( constraintsRemoved ); + public boolean containsUpdates() { + return isPositive(nodesCreated) + || isPositive(nodesDeleted) + || isPositive(relationshipsCreated) + || isPositive(relationshipsDeleted) + || isPositive(propertiesSet) + || isPositive(labelsAdded) + || isPositive(labelsRemoved) + || isPositive(indexesAdded) + || isPositive(indexesRemoved) + || isPositive(constraintsAdded) + || isPositive(constraintsRemoved); } @Override - public int nodesCreated() - { + public int nodesCreated() { return nodesCreated; } @Override - public int nodesDeleted() - { + public int nodesDeleted() { return nodesDeleted; } @Override - public int relationshipsCreated() - { + public int relationshipsCreated() { return relationshipsCreated; } @Override - public int relationshipsDeleted() - { + public int relationshipsDeleted() { return relationshipsDeleted; } @Override - public int propertiesSet() - { + public int propertiesSet() { return propertiesSet; } @Override - public int labelsAdded() - { + public int labelsAdded() { return labelsAdded; } @Override - public int labelsRemoved() - { + public int labelsRemoved() { return labelsRemoved; } @Override - public int indexesAdded() - { + public int indexesAdded() { return indexesAdded; } @Override - public int indexesRemoved() - { + public int indexesRemoved() { return indexesRemoved; } @Override - public int constraintsAdded() - { + public int constraintsAdded() { return constraintsAdded; } @Override - public int constraintsRemoved() - { + public int constraintsRemoved() { return constraintsRemoved; } @Override - public boolean containsSystemUpdates() - { - return isPositive( systemUpdates ); + public boolean containsSystemUpdates() { + return isPositive(systemUpdates); } @Override - public int systemUpdates() - { + public int systemUpdates() { return systemUpdates; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } InternalSummaryCounters that = (InternalSummaryCounters) o; return nodesCreated == that.nodesCreated - && nodesDeleted == that.nodesDeleted - && relationshipsCreated == that.relationshipsCreated - && relationshipsDeleted == that.relationshipsDeleted - && propertiesSet == that.propertiesSet - && labelsAdded == that.labelsAdded - && labelsRemoved == that.labelsRemoved - && indexesAdded == that.indexesAdded - && indexesRemoved == that.indexesRemoved - && constraintsAdded == that.constraintsAdded - && constraintsRemoved == that.constraintsRemoved - && systemUpdates == that.systemUpdates; - } - - @Override - public int hashCode() - { + && nodesDeleted == that.nodesDeleted + && relationshipsCreated == that.relationshipsCreated + && relationshipsDeleted == that.relationshipsDeleted + && propertiesSet == that.propertiesSet + && labelsAdded == that.labelsAdded + && labelsRemoved == that.labelsRemoved + && indexesAdded == that.indexesAdded + && indexesRemoved == that.indexesRemoved + && constraintsAdded == that.constraintsAdded + && constraintsRemoved == that.constraintsRemoved + && systemUpdates == that.systemUpdates; + } + + @Override + public int hashCode() { int result = nodesCreated; result = 31 * result + nodesDeleted; result = 31 * result + relationshipsCreated; @@ -200,27 +185,24 @@ public int hashCode() return result; } - private boolean isPositive( int value ) - { + private boolean isPositive(int value) { return value > 0; } @Override - public String toString() - { - return "InternalSummaryCounters{" + - "nodesCreated=" + nodesCreated + - ", nodesDeleted=" + nodesDeleted + - ", relationshipsCreated=" + relationshipsCreated + - ", relationshipsDeleted=" + relationshipsDeleted + - ", propertiesSet=" + propertiesSet + - ", labelsAdded=" + labelsAdded + - ", labelsRemoved=" + labelsRemoved + - ", indexesAdded=" + indexesAdded + - ", indexesRemoved=" + indexesRemoved + - ", constraintsAdded=" + constraintsAdded + - ", constraintsRemoved=" + constraintsRemoved + - ", systemUpdates=" + systemUpdates + - '}'; + public String toString() { + return "InternalSummaryCounters{" + "nodesCreated=" + + nodesCreated + ", nodesDeleted=" + + nodesDeleted + ", relationshipsCreated=" + + relationshipsCreated + ", relationshipsDeleted=" + + relationshipsDeleted + ", propertiesSet=" + + propertiesSet + ", labelsAdded=" + + labelsAdded + ", labelsRemoved=" + + labelsRemoved + ", indexesAdded=" + + indexesAdded + ", indexesRemoved=" + + indexesRemoved + ", constraintsAdded=" + + constraintsAdded + ", constraintsRemoved=" + + constraintsRemoved + ", systemUpdates=" + + systemUpdates + '}'; } } 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 5eeb59058b..f871c114f1 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,7 +20,6 @@ import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; - import org.neo4j.driver.Config; import org.neo4j.driver.MetricsAdapter; import org.neo4j.driver.internal.DriverFactory; @@ -30,9 +29,8 @@ 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 -{ +@TargetClass(DriverFactory.class) +final class Target_org_neo4j_driver_internal_DriverFactory { /** * Substitutes metrics adatper in such a way that it falls back to off when Micrometer is not available. @@ -42,34 +40,27 @@ final class Target_org_neo4j_driver_internal_DriverFactory * @return A metrics provider, never null */ @Substitute - protected static MetricsProvider getOrCreateMetricsProvider( Config config, Clock clock ) - { + protected static MetricsProvider getOrCreateMetricsProvider(Config config, Clock clock) { MetricsAdapter metricsAdapter = config.metricsAdapter(); - if ( metricsAdapter == null ) - { + if (metricsAdapter == null) { metricsAdapter = config.isMetricsEnabled() ? MetricsAdapter.DEFAULT : MetricsAdapter.DEV_NULL; } - switch ( metricsAdapter ) - { - case DEV_NULL: - return DevNullMetricsProvider.INSTANCE; - case DEFAULT: - return new InternalMetricsProvider( clock, config.logging() ); - case MICROMETER: - try - { - @SuppressWarnings( "unused" ) Class metricsClass = Class.forName( "io.micrometer.core.instrument.Metrics" ); - return MicrometerMetricsProvider.forGlobalRegistry(); - } - catch ( ClassNotFoundException e ) - { + switch (metricsAdapter) { + case DEV_NULL: return DevNullMetricsProvider.INSTANCE; - } + case DEFAULT: + return new InternalMetricsProvider(clock, config.logging()); + case MICROMETER: + try { + @SuppressWarnings("unused") + Class metricsClass = Class.forName("io.micrometer.core.instrument.Metrics"); + return MicrometerMetricsProvider.forGlobalRegistry(); + } catch (ClassNotFoundException e) { + return DevNullMetricsProvider.INSTANCE; + } } - throw new IllegalStateException( "Unknown or unsupported MetricsAdapter: " + metricsAdapter ); + throw new IllegalStateException("Unknown or unsupported MetricsAdapter: " + metricsAdapter); } } -class MicrometerSubstitutions -{ -} +class MicrometerSubstitutions {} diff --git a/driver/src/main/java/org/neo4j/driver/internal/svm/NettySubstitutions.java b/driver/src/main/java/org/neo4j/driver/internal/svm/NettySubstitutions.java index d8f92fc02f..8e4e535d32 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/svm/NettySubstitutions.java +++ b/driver/src/main/java/org/neo4j/driver/internal/svm/NettySubstitutions.java @@ -23,16 +23,6 @@ import com.oracle.svm.core.annotate.TargetClass; import com.oracle.svm.core.jdk.JDK11OrLater; import com.oracle.svm.core.jdk.JDK8OrEarlier; - -import java.security.PrivateKey; -import java.security.Provider; -import java.security.cert.X509Certificate; -import java.util.Map; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLException; -import javax.net.ssl.TrustManagerFactory; - import io.netty.bootstrap.AbstractBootstrapConfig; import io.netty.bootstrap.ChannelFactory; import io.netty.buffer.ByteBufAllocator; @@ -51,6 +41,14 @@ import io.netty.util.concurrent.GlobalEventExecutor; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.JdkLoggerFactory; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.cert.X509Certificate; +import java.util.Map; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; /** * This substitution avoid having loggers added to the build @@ -59,7 +57,7 @@ final class Target_io_netty_util_internal_logging_InternalLoggerFactory { @Substitute - private static InternalLoggerFactory newDefaultFactory( String name) { + private static InternalLoggerFactory newDefaultFactory(String name) { return JdkLoggerFactory.INSTANCE; } } @@ -71,32 +69,46 @@ private static InternalLoggerFactory newDefaultFactory( String name) { final class Target_io_netty_handler_ssl_JdkSslServerContext { @Alias - Target_io_netty_handler_ssl_JdkSslServerContext( Provider provider, - X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, - X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, - KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, - ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, - ClientAuth clientAuth, String[] protocols, boolean startTls, + Target_io_netty_handler_ssl_JdkSslServerContext( + Provider provider, + X509Certificate[] trustCertCollection, + TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, + PrivateKey key, + String keyPassword, + KeyManagerFactory keyManagerFactory, + Iterable ciphers, + CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, + long sessionCacheSize, + long sessionTimeout, + ClientAuth clientAuth, + String[] protocols, + boolean startTls, String keyStore) - throws SSLException - { - } + throws SSLException {} } @TargetClass(className = "io.netty.handler.ssl.JdkSslClientContext") final class Target_io_netty_handler_ssl_JdkSslClientContext { @Alias - Target_io_netty_handler_ssl_JdkSslClientContext( Provider sslContextProvider, + Target_io_netty_handler_ssl_JdkSslClientContext( + Provider sslContextProvider, X509Certificate[] trustCertCollection, - TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, - String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, - CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, - long sessionCacheSize, long sessionTimeout, String keyStoreType) - throws SSLException - { - - } + TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, + PrivateKey key, + String keyPassword, + KeyManagerFactory keyManagerFactory, + Iterable ciphers, + CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, + String[] protocols, + long sessionCacheSize, + long sessionTimeout, + String keyStoreType) + throws SSLException {} } @TargetClass(className = "io.netty.handler.ssl.SslHandler$SslEngineType") @@ -106,36 +118,46 @@ final class Target_io_netty_handler_ssl_SslHandler$SslEngineType { public static Target_io_netty_handler_ssl_SslHandler$SslEngineType JDK; @Substitute - static Target_io_netty_handler_ssl_SslHandler$SslEngineType forEngine( SSLEngine engine) { + static Target_io_netty_handler_ssl_SslHandler$SslEngineType forEngine(SSLEngine engine) { return JDK; } } -@TargetClass(className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper", onlyWith = JDK11OrLater.class) +@TargetClass( + className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper", + onlyWith = JDK11OrLater.class) final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapper { @Substitute - public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, - JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { - return (SSLEngine) (Object) new Target_io_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator, isServer); + public SSLEngine wrapSslEngine( + SSLEngine engine, + ByteBufAllocator alloc, + JdkApplicationProtocolNegotiator applicationNegotiator, + boolean isServer) { + return (SSLEngine) + (Object) new Target_io_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator, isServer); } - } -@TargetClass(className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper", onlyWith = JDK8OrEarlier.class) +@TargetClass( + className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper", + onlyWith = JDK8OrEarlier.class) final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapperJava8 { @Substitute - public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, - JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { + public SSLEngine wrapSslEngine( + SSLEngine engine, + ByteBufAllocator alloc, + JdkApplicationProtocolNegotiator applicationNegotiator, + boolean isServer) { if (Target_io_netty_handler_ssl_JettyAlpnSslEngine.isAvailable()) { return isServer - ? (SSLEngine) (Object) Target_io_netty_handler_ssl_JettyAlpnSslEngine.newServerEngine(engine, - applicationNegotiator) - : (SSLEngine) (Object) Target_io_netty_handler_ssl_JettyAlpnSslEngine.newClientEngine(engine, - applicationNegotiator); + ? (SSLEngine) (Object) Target_io_netty_handler_ssl_JettyAlpnSslEngine.newServerEngine( + engine, applicationNegotiator) + : (SSLEngine) (Object) Target_io_netty_handler_ssl_JettyAlpnSslEngine.newClientEngine( + engine, applicationNegotiator); } - throw new RuntimeException("Unable to wrap SSLEngine of type " + engine.getClass().getName()); + throw new RuntimeException( + "Unable to wrap SSLEngine of type " + engine.getClass().getName()); } - } @TargetClass(className = "io.netty.handler.ssl.JettyAlpnSslEngine", onlyWith = JDK8OrEarlier.class) @@ -146,16 +168,16 @@ static boolean isAvailable() { } @Substitute - @SuppressWarnings( "deprecation" ) - static Target_io_netty_handler_ssl_JettyAlpnSslEngine newClientEngine(SSLEngine engine, - JdkApplicationProtocolNegotiator applicationNegotiator) { + @SuppressWarnings("deprecation") + static Target_io_netty_handler_ssl_JettyAlpnSslEngine newClientEngine( + SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator) { return null; } @Substitute - @SuppressWarnings( "deprecation" ) - static Target_io_netty_handler_ssl_JettyAlpnSslEngine newServerEngine(SSLEngine engine, - JdkApplicationProtocolNegotiator applicationNegotiator) { + @SuppressWarnings("deprecation") + static Target_io_netty_handler_ssl_JettyAlpnSslEngine newServerEngine( + SSLEngine engine, JdkApplicationProtocolNegotiator applicationNegotiator) { return null; } } @@ -164,56 +186,100 @@ static Target_io_netty_handler_ssl_JettyAlpnSslEngine newServerEngine(SSLEngine final class Target_io_netty_handler_ssl_JdkAlpnSslEngine { @Alias - @SuppressWarnings( "deprecation" ) - Target_io_netty_handler_ssl_JdkAlpnSslEngine(final SSLEngine engine, - final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) { - - } + @SuppressWarnings("deprecation") + Target_io_netty_handler_ssl_JdkAlpnSslEngine( + final SSLEngine engine, + final JdkApplicationProtocolNegotiator applicationNegotiator, + final boolean isServer) {} } @TargetClass(className = "io.netty.handler.ssl.SslContext") final class Target_io_netty_handler_ssl_SslContext { @Substitute - static SslContext newServerContextInternal(SslProvider provider, + static SslContext newServerContextInternal( + SslProvider provider, Provider sslContextProvider, - X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, - X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, - Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, - long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls, - boolean enableOcsp, String keyStoreType, Map.Entry, Object>... ctxOptions) - throws SSLException - { + X509Certificate[] trustCertCollection, + TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, + PrivateKey key, + String keyPassword, + KeyManagerFactory keyManagerFactory, + Iterable ciphers, + CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, + long sessionCacheSize, + long sessionTimeout, + ClientAuth clientAuth, + String[] protocols, + boolean startTls, + boolean enableOcsp, + String keyStoreType, + Map.Entry, Object>... ctxOptions) + throws SSLException { if (enableOcsp) { throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); } return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslServerContext( sslContextProvider, - trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, - keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, - clientAuth, protocols, startTls, keyStoreType); + trustCertCollection, + trustManagerFactory, + keyCertChain, + key, + keyPassword, + keyManagerFactory, + ciphers, + cipherFilter, + apn, + sessionCacheSize, + sessionTimeout, + clientAuth, + protocols, + startTls, + keyStoreType); } @Substitute static SslContext newClientContextInternal( SslProvider provider, Provider sslContextProvider, - X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory, - X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, - Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, - long sessionCacheSize, long sessionTimeout, boolean enableOcsp, String keyStoreType, Map.Entry, Object>... options) throws SSLException - { + X509Certificate[] trustCert, + TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, + PrivateKey key, + String keyPassword, + KeyManagerFactory keyManagerFactory, + Iterable ciphers, + CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, + String[] protocols, + long sessionCacheSize, + long sessionTimeout, + boolean enableOcsp, + String keyStoreType, + Map.Entry, Object>... options) + throws SSLException { if (enableOcsp) { throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); } return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslClientContext( sslContextProvider, - trustCert, trustManagerFactory, keyCertChain, key, keyPassword, - keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, - sessionTimeout, keyStoreType); + trustCert, + trustManagerFactory, + keyCertChain, + key, + keyPassword, + keyManagerFactory, + ciphers, + cipherFilter, + apn, + protocols, + sessionCacheSize, + sessionTimeout, + keyStoreType); } - } @TargetClass(className = "io.netty.handler.ssl.JdkDefaultApplicationProtocolNegotiator") @@ -229,23 +295,29 @@ final class Target_io_netty_handler_ssl_JdkSslContext { @Substitute static JdkApplicationProtocolNegotiator toNegotiator(ApplicationProtocolConfig config, boolean isServer) { if (config == null) { - return (JdkApplicationProtocolNegotiator) (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; + return (JdkApplicationProtocolNegotiator) + (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; } switch (config.protocol()) { case NONE: - return (JdkApplicationProtocolNegotiator) (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; + return (JdkApplicationProtocolNegotiator) + (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; case ALPN: if (isServer) { // GRAAL RC9 bug: https://github.com/oracle/graal/issues/813 // switch(config.selectorFailureBehavior()) { // case FATAL_ALERT: - // return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); + // return new JdkAlpnApplicationProtocolNegotiator(true, + // config.supportedProtocols()); // case NO_ADVERTISE: - // return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); + // return new JdkAlpnApplicationProtocolNegotiator(false, + // config.supportedProtocols()); // default: - // throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") - // .append(config.selectorFailureBehavior()).append(" failure behavior").toString()); + // throw new UnsupportedOperationException(new StringBuilder("JDK provider does + // not support ") + // .append(config.selectorFailureBehavior()).append(" failure + // behavior").toString()); // } SelectorFailureBehavior behavior = config.selectorFailureBehavior(); if (behavior == SelectorFailureBehavior.FATAL_ALERT) @@ -254,7 +326,9 @@ else if (behavior == SelectorFailureBehavior.NO_ADVERTISE) return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); else { throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") - .append(config.selectorFailureBehavior()).append(" failure behavior").toString()); + .append(config.selectorFailureBehavior()) + .append(" failure behavior") + .toString()); } } else { switch (config.selectedListenerFailureBehavior()) { @@ -264,17 +338,18 @@ else if (behavior == SelectorFailureBehavior.NO_ADVERTISE) return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); default: throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") - .append(config.selectedListenerFailureBehavior()).append(" failure behavior") + .append(config.selectedListenerFailureBehavior()) + .append(" failure behavior") .toString()); } } default: - throw new UnsupportedOperationException( - new StringBuilder("JDK provider does not support ").append(config.protocol()).append(" protocol") - .toString()); + throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") + .append(config.protocol()) + .append(" protocol") + .toString()); } } - } /* @@ -288,9 +363,7 @@ final class Target_io_netty_bootstrap_AbstractBootstrap { private ChannelFactory channelFactory; @Alias - void init(Channel channel) throws Exception - { - } + void init(Channel channel) throws Exception {} @Alias public AbstractBootstrapConfig config() { @@ -303,7 +376,7 @@ final ChannelFuture initAndRegister() { try { channel = channelFactory.newChannel(); init(channel); - } catch ( Throwable t) { + } catch (Throwable t) { // THE FIX IS HERE: t.printStackTrace(); if (channel != null) { @@ -333,9 +406,7 @@ final ChannelFuture initAndRegister() { // because register(), bind(), and connect() are all bound to the same thread. return regFuture; - } } -class NettySubstitutions { -} +class NettySubstitutions {} diff --git a/driver/src/main/java/org/neo4j/driver/internal/svm/ZLibSubstitutions.java b/driver/src/main/java/org/neo4j/driver/internal/svm/ZLibSubstitutions.java index 4ac2a72281..dee3a07c03 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/svm/ZLibSubstitutions.java +++ b/driver/src/main/java/org/neo4j/driver/internal/svm/ZLibSubstitutions.java @@ -38,17 +38,17 @@ public static ZlibEncoder newZlibEncoder(int compressionLevel) { } @Substitute - public static ZlibEncoder newZlibEncoder( ZlibWrapper wrapper) { + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper) { return new JdkZlibEncoder(wrapper); } @Substitute - public static ZlibEncoder newZlibEncoder( ZlibWrapper wrapper, int compressionLevel) { + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel) { return new JdkZlibEncoder(wrapper, compressionLevel); } @Substitute - public static ZlibEncoder newZlibEncoder( ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) { + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) { return new JdkZlibEncoder(wrapper, compressionLevel); } @@ -73,7 +73,7 @@ public static ZlibDecoder newZlibDecoder() { } @Substitute - public static ZlibDecoder newZlibDecoder( ZlibWrapper wrapper) { + public static ZlibDecoder newZlibDecoder(ZlibWrapper wrapper) { return new JdkZlibDecoder(wrapper); } @@ -83,6 +83,4 @@ public static ZlibDecoder newZlibDecoder(byte[] dictionary) { } } -class ZLibSubstitutions { - -} +class ZLibSubstitutions {} diff --git a/driver/src/main/java/org/neo4j/driver/internal/types/InternalMapAccessorWithDefaultValue.java b/driver/src/main/java/org/neo4j/driver/internal/types/InternalMapAccessorWithDefaultValue.java index 94d63b0a06..1a459fbf04 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/types/InternalMapAccessorWithDefaultValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/types/InternalMapAccessorWithDefaultValue.java @@ -20,325 +20,237 @@ import java.util.List; import java.util.Map; - -import org.neo4j.driver.internal.AsValue; +import java.util.function.Function; import org.neo4j.driver.Value; import org.neo4j.driver.Values; +import org.neo4j.driver.internal.AsValue; import org.neo4j.driver.types.Entity; import org.neo4j.driver.types.MapAccessorWithDefaultValue; import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Path; import org.neo4j.driver.types.Relationship; -import java.util.function.Function; -public abstract class InternalMapAccessorWithDefaultValue implements MapAccessorWithDefaultValue -{ - public abstract Value get( String key ); +public abstract class InternalMapAccessorWithDefaultValue implements MapAccessorWithDefaultValue { + public abstract Value get(String key); @Override - public Value get( String key, Value defaultValue ) - { - return get( get( key ), defaultValue ); + public Value get(String key, Value defaultValue) { + return get(get(key), defaultValue); } - private Value get( Value value, Value defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private Value get(Value value, Value defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return ((AsValue) value).asValue(); } } @Override - public Object get( String key, Object defaultValue ) - { - return get( get( key ), defaultValue ); + public Object get(String key, Object defaultValue) { + return get(get(key), defaultValue); } - private Object get(Value value, Object defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private Object get(Value value, Object defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asObject(); } } @Override - public Number get( String key, Number defaultValue ) - { - return get( get( key ), defaultValue ); + public Number get(String key, Number defaultValue) { + return get(get(key), defaultValue); } - private Number get( Value value, Number defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private Number get(Value value, Number defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asNumber(); } } @Override - public Entity get( String key, Entity defaultValue ) - { - return get( get( key ), defaultValue ); + public Entity get(String key, Entity defaultValue) { + return get(get(key), defaultValue); } - private Entity get( Value value, Entity defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private Entity get(Value value, Entity defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asEntity(); } } @Override - public Node get( String key, Node defaultValue ) - { - return get( get( key ), defaultValue ); + public Node get(String key, Node defaultValue) { + return get(get(key), defaultValue); } - private Node get( Value value, Node defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private Node get(Value value, Node defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asNode(); } } @Override - public Path get( String key, Path defaultValue ) - { - return get( get( key ), defaultValue ); + public Path get(String key, Path defaultValue) { + return get(get(key), defaultValue); } - private Path get( Value value, Path defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private Path get(Value value, Path defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asPath(); } } @Override - public Relationship get( String key, Relationship defaultValue ) - { - return get( get( key ), defaultValue ); + public Relationship get(String key, Relationship defaultValue) { + return get(get(key), defaultValue); } - private Relationship get( Value value, Relationship defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private Relationship get(Value value, Relationship defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asRelationship(); } } @Override - public List get( String key, List defaultValue ) - { - return get( get( key ), defaultValue ); + public List get(String key, List defaultValue) { + return get(get(key), defaultValue); } - private List get( Value value, List defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private List get(Value value, List defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { - return value.asList(); + } else { + return value.asList(); } } @Override - public List get( String key, List defaultValue, Function mapFunc ) - { - return get( get( key ), defaultValue, mapFunc ); + public List get(String key, List defaultValue, Function mapFunc) { + return get(get(key), defaultValue, mapFunc); } - private List get( Value value, List defaultValue, Function mapFunc ) - { - if( value.equals( Values.NULL ) ) - { + private List get(Value value, List defaultValue, Function mapFunc) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { - return value.asList( mapFunc ); + } else { + return value.asList(mapFunc); } } @Override - public Map get( String key, Map defaultValue ) - { - return get( get( key ), defaultValue ); + public Map get(String key, Map defaultValue) { + return get(get(key), defaultValue); } - private Map get( Value value, Map defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private Map get(Value value, Map defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asMap(); } } @Override - public Map get( String key, Map defaultValue, Function mapFunc ) - { - return get( get( key ), defaultValue, mapFunc ); + public Map get(String key, Map defaultValue, Function mapFunc) { + return get(get(key), defaultValue, mapFunc); } - private Map get( Value value, Map defaultValue, Function mapFunc ) - { - if( value.equals( Values.NULL ) ) - { + private Map get(Value value, Map defaultValue, Function mapFunc) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { - return value.asMap( mapFunc ); + } else { + return value.asMap(mapFunc); } } @Override - public int get( String key, int defaultValue ) - { - return get( get( key ), defaultValue ); + public int get(String key, int defaultValue) { + return get(get(key), defaultValue); } - private int get( Value value, int defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private int get(Value value, int defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asInt(); } } @Override - public long get( String key, long defaultValue ) - { - return get( get( key ), defaultValue ); + public long get(String key, long defaultValue) { + return get(get(key), defaultValue); } - private long get( Value value, long defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private long get(Value value, long defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asLong(); } } @Override - public boolean get( String key, boolean defaultValue ) - { - return get( get( key ), defaultValue ); + public boolean get(String key, boolean defaultValue) { + return get(get(key), defaultValue); } - private boolean get( Value value, boolean defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private boolean get(Value value, boolean defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asBoolean(); } } @Override - public String get( String key, String defaultValue ) - { - return get( get( key ), defaultValue ); + public String get(String key, String defaultValue) { + return get(get(key), defaultValue); } - private String get( Value value, String defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private String get(Value value, String defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asString(); } } @Override - public float get( String key, float defaultValue ) - { - return get( get( key ), defaultValue ); + public float get(String key, float defaultValue) { + return get(get(key), defaultValue); } - private float get( Value value, float defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private float get(Value value, float defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asFloat(); } } @Override - public double get( String key, double defaultValue ) - { - return get( get( key ), defaultValue ); + public double get(String key, double defaultValue) { + return get(get(key), defaultValue); } - private double get( Value value, double defaultValue ) - { - if( value.equals( Values.NULL ) ) - { + private double get(Value value, double defaultValue) { + if (value.equals(Values.NULL)) { return defaultValue; - } - else - { + } else { return value.asDouble(); } } - } diff --git a/driver/src/main/java/org/neo4j/driver/internal/types/InternalTypeSystem.java b/driver/src/main/java/org/neo4j/driver/internal/types/InternalTypeSystem.java index 7f3d19d25d..4e459bbc10 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/types/InternalTypeSystem.java +++ b/driver/src/main/java/org/neo4j/driver/internal/types/InternalTypeSystem.java @@ -18,10 +18,6 @@ */ package org.neo4j.driver.internal.types; -import org.neo4j.driver.Value; -import org.neo4j.driver.types.Type; -import org.neo4j.driver.types.TypeSystem; - import static org.neo4j.driver.internal.types.TypeConstructor.ANY; import static org.neo4j.driver.internal.types.TypeConstructor.BOOLEAN; import static org.neo4j.driver.internal.types.TypeConstructor.BYTES; @@ -43,163 +39,143 @@ import static org.neo4j.driver.internal.types.TypeConstructor.STRING; import static org.neo4j.driver.internal.types.TypeConstructor.TIME; +import org.neo4j.driver.Value; +import org.neo4j.driver.types.Type; +import org.neo4j.driver.types.TypeSystem; + /** * Utility class for determining and working with the Cypher types of values * * @see Value * @see Type */ -public class InternalTypeSystem implements TypeSystem -{ +public class InternalTypeSystem implements TypeSystem { public static InternalTypeSystem TYPE_SYSTEM = new InternalTypeSystem(); - private final TypeRepresentation anyType = constructType( ANY ); - private final TypeRepresentation booleanType = constructType( BOOLEAN ); - private final TypeRepresentation bytesType = constructType( BYTES ); - private final TypeRepresentation stringType = constructType( STRING ); - private final TypeRepresentation numberType = constructType( NUMBER ); - private final TypeRepresentation integerType = constructType( INTEGER ); - private final TypeRepresentation floatType = constructType( FLOAT ); - private final TypeRepresentation listType = constructType( LIST ); - private final TypeRepresentation mapType = constructType( MAP ); - private final TypeRepresentation nodeType = constructType( NODE ); - private final TypeRepresentation relationshipType = constructType( RELATIONSHIP ); - private final TypeRepresentation pathType = constructType( PATH ); - private final TypeRepresentation pointType = constructType( POINT ); - private final TypeRepresentation dateType = constructType( DATE ); - private final TypeRepresentation timeType = constructType( TIME ); - private final TypeRepresentation localTimeType = constructType( LOCAL_TIME ); - private final TypeRepresentation localDateTimeType = constructType( LOCAL_DATE_TIME ); - private final TypeRepresentation dateTimeType = constructType( DATE_TIME ); - private final TypeRepresentation durationType = constructType( DURATION ); - private final TypeRepresentation nullType = constructType( NULL ); - - private InternalTypeSystem() - { - } - - @Override - public Type ANY() - { + private final TypeRepresentation anyType = constructType(ANY); + private final TypeRepresentation booleanType = constructType(BOOLEAN); + private final TypeRepresentation bytesType = constructType(BYTES); + private final TypeRepresentation stringType = constructType(STRING); + private final TypeRepresentation numberType = constructType(NUMBER); + private final TypeRepresentation integerType = constructType(INTEGER); + private final TypeRepresentation floatType = constructType(FLOAT); + private final TypeRepresentation listType = constructType(LIST); + private final TypeRepresentation mapType = constructType(MAP); + private final TypeRepresentation nodeType = constructType(NODE); + private final TypeRepresentation relationshipType = constructType(RELATIONSHIP); + private final TypeRepresentation pathType = constructType(PATH); + private final TypeRepresentation pointType = constructType(POINT); + private final TypeRepresentation dateType = constructType(DATE); + private final TypeRepresentation timeType = constructType(TIME); + private final TypeRepresentation localTimeType = constructType(LOCAL_TIME); + private final TypeRepresentation localDateTimeType = constructType(LOCAL_DATE_TIME); + private final TypeRepresentation dateTimeType = constructType(DATE_TIME); + private final TypeRepresentation durationType = constructType(DURATION); + private final TypeRepresentation nullType = constructType(NULL); + + private InternalTypeSystem() {} + + @Override + public Type ANY() { return anyType; } @Override - public Type BOOLEAN() - { + public Type BOOLEAN() { return booleanType; } @Override - public Type BYTES() - { + public Type BYTES() { return bytesType; } @Override - public Type STRING() - { + public Type STRING() { return stringType; } @Override - public Type NUMBER() - { + public Type NUMBER() { return numberType; } @Override - public Type INTEGER() - { + public Type INTEGER() { return integerType; } @Override - public Type FLOAT() - { + public Type FLOAT() { return floatType; } @Override - public Type LIST() - { + public Type LIST() { return listType; } @Override - public Type MAP() - { + public Type MAP() { return mapType; } @Override - public Type NODE() - { + public Type NODE() { return nodeType; } @Override - public Type RELATIONSHIP() - { + public Type RELATIONSHIP() { return relationshipType; } @Override - public Type PATH() - { + public Type PATH() { return pathType; } @Override - public Type POINT() - { + public Type POINT() { return pointType; } @Override - public Type DATE() - { + public Type DATE() { return dateType; } @Override - public Type TIME() - { + public Type TIME() { return timeType; } @Override - public Type LOCAL_TIME() - { + public Type LOCAL_TIME() { return localTimeType; } @Override - public Type LOCAL_DATE_TIME() - { + public Type LOCAL_DATE_TIME() { return localDateTimeType; } @Override - public Type DATE_TIME() - { + public Type DATE_TIME() { return dateTimeType; } @Override - public Type DURATION() - { + public Type DURATION() { return durationType; } @Override - public Type NULL() - { + public Type NULL() { return nullType; } - private TypeRepresentation constructType( TypeConstructor tyCon ) - { - return new TypeRepresentation( tyCon ); + private TypeRepresentation constructType(TypeConstructor tyCon) { + return new TypeRepresentation(tyCon); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/types/TypeConstructor.java b/driver/src/main/java/org/neo4j/driver/internal/types/TypeConstructor.java index c6d32276ac..4bfae5df5a 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/types/TypeConstructor.java +++ b/driver/src/main/java/org/neo4j/driver/internal/types/TypeConstructor.java @@ -18,43 +18,36 @@ */ package org.neo4j.driver.internal.types; -import org.neo4j.driver.internal.value.InternalValue; import org.neo4j.driver.Value; +import org.neo4j.driver.internal.value.InternalValue; -public enum TypeConstructor -{ - ANY - { - @Override - public boolean covers( Value value ) - { - return !value.isNull(); - } - }, +public enum TypeConstructor { + ANY { + @Override + public boolean covers(Value value) { + return !value.isNull(); + } + }, BOOLEAN, BYTES, STRING, - NUMBER - { - @Override - public boolean covers( Value value ) - { - TypeConstructor valueType = typeConstructorOf( value ); - return valueType == this || valueType == INTEGER || valueType == FLOAT; - } - }, + NUMBER { + @Override + public boolean covers(Value value) { + TypeConstructor valueType = typeConstructorOf(value); + return valueType == this || valueType == INTEGER || valueType == FLOAT; + } + }, INTEGER, FLOAT, LIST, - MAP - { - @Override - public boolean covers( Value value ) - { - TypeConstructor valueType = typeConstructorOf( value ); - return valueType == MAP || valueType == NODE || valueType == RELATIONSHIP; - } - }, + MAP { + @Override + public boolean covers(Value value) { + TypeConstructor valueType = typeConstructorOf(value); + return valueType == MAP || valueType == NODE || valueType == RELATIONSHIP; + } + }, NODE, RELATIONSHIP, PATH, @@ -67,13 +60,11 @@ public boolean covers( Value value ) DURATION, NULL; - private static TypeConstructor typeConstructorOf( Value value ) - { + private static TypeConstructor typeConstructorOf(Value value) { return ((InternalValue) value).typeConstructor(); } - public boolean covers( Value value ) - { - return this == typeConstructorOf( value ); + public boolean covers(Value value) { + return this == typeConstructorOf(value); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/types/TypeRepresentation.java b/driver/src/main/java/org/neo4j/driver/internal/types/TypeRepresentation.java index 9eaa84d396..68a0f7688c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/types/TypeRepresentation.java +++ b/driver/src/main/java/org/neo4j/driver/internal/types/TypeRepresentation.java @@ -18,49 +18,44 @@ */ package org.neo4j.driver.internal.types; +import static org.neo4j.driver.internal.types.TypeConstructor.LIST; + import org.neo4j.driver.Value; import org.neo4j.driver.types.Type; -import static org.neo4j.driver.internal.types.TypeConstructor.LIST; - -public class TypeRepresentation implements Type -{ +public class TypeRepresentation implements Type { private final TypeConstructor tyCon; - public TypeRepresentation( TypeConstructor tyCon ) - { + public TypeRepresentation(TypeConstructor tyCon) { this.tyCon = tyCon; } @Override - public boolean isTypeOf( Value value ) - { - return tyCon.covers( value ); + public boolean isTypeOf(Value value) { + return tyCon.covers(value); } @Override - public String name() - { - if ( tyCon == LIST ) - { + public String name() { + if (tyCon == LIST) { return "LIST OF ANY?"; } return tyCon.toString(); } - public TypeConstructor constructor() - { + public TypeConstructor constructor() { return tyCon; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { return true; } - if ( o == null || getClass() != o.getClass() ) - { return false; } + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } TypeRepresentation that = (TypeRepresentation) o; @@ -68,8 +63,7 @@ public boolean equals( Object o ) } @Override - public int hashCode() - { + public int hashCode() { return tyCon.hashCode(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/CertificateTool.java b/driver/src/main/java/org/neo4j/driver/internal/util/CertificateTool.java index 9077dc8b78..685b6fb54f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/CertificateTool.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/CertificateTool.java @@ -37,8 +37,7 @@ /** * A tool used to save, load certs, etc. */ -public final class CertificateTool -{ +public final class CertificateTool { private static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----"; private static final String END_CERT = "-----END CERTIFICATE-----"; @@ -48,17 +47,15 @@ public final class CertificateTool * @param certFile * @throws IOException */ - public static void saveX509Cert( String certStr, File certFile ) throws IOException - { - try ( BufferedWriter writer = new BufferedWriter( new FileWriter( certFile ) ) ) - { - writer.write( BEGIN_CERT ); + public static void saveX509Cert(String certStr, File certFile) throws IOException { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(certFile))) { + writer.write(BEGIN_CERT); writer.newLine(); - writer.write( certStr ); + writer.write(certStr); writer.newLine(); - writer.write( END_CERT ); + writer.write(END_CERT); writer.newLine(); } } @@ -71,9 +68,8 @@ public static void saveX509Cert( String certStr, File certFile ) throws IOExcept * @throws GeneralSecurityException * @throws IOException */ - public static void saveX509Cert( Certificate cert, File certFile ) throws GeneralSecurityException, IOException - { - saveX509Cert( new Certificate[]{cert}, certFile ); + public static void saveX509Cert(Certificate cert, File certFile) throws GeneralSecurityException, IOException { + saveX509Cert(new Certificate[] {cert}, certFile); } /** @@ -84,21 +80,19 @@ public static void saveX509Cert( Certificate cert, File certFile ) throws Genera * @throws GeneralSecurityException * @throws IOException */ - public static void saveX509Cert( Certificate[] certs, File certFile ) throws GeneralSecurityException, IOException - { - try ( BufferedWriter writer = new BufferedWriter( new FileWriter( certFile ) ) ) - { - for ( Certificate cert : certs ) - { - String certStr = Base64.getEncoder().encodeToString( cert.getEncoded() ).replaceAll( "(.{64})", "$1\n" ); - - writer.write( BEGIN_CERT ); + public static void saveX509Cert(Certificate[] certs, File certFile) throws GeneralSecurityException, IOException { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(certFile))) { + for (Certificate cert : certs) { + String certStr = + Base64.getEncoder().encodeToString(cert.getEncoded()).replaceAll("(.{64})", "$1\n"); + + writer.write(BEGIN_CERT); writer.newLine(); - writer.write( certStr ); + writer.write(certStr); writer.newLine(); - writer.write( END_CERT ); + writer.write(END_CERT); writer.newLine(); } } @@ -112,44 +106,39 @@ public static void saveX509Cert( Certificate[] certs, File certFile ) throws Gen * @throws GeneralSecurityException * @throws IOException */ - public static void loadX509Cert( List certFiles, KeyStore keyStore ) throws GeneralSecurityException, IOException - { + public static void loadX509Cert(List certFiles, KeyStore keyStore) + throws GeneralSecurityException, IOException { int certCount = 0; // The files might contain multiple certs - for ( File certFile : certFiles ) - { - try ( BufferedInputStream inputStream = new BufferedInputStream( new FileInputStream( certFile ) ) ) - { - CertificateFactory certFactory = CertificateFactory.getInstance( "X.509" ); - - while ( inputStream.available() > 0 ) - { - try - { - Certificate cert = certFactory.generateCertificate( inputStream ); + for (File certFile : certFiles) { + try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(certFile))) { + CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + + while (inputStream.available() > 0) { + try { + Certificate cert = certFactory.generateCertificate(inputStream); certCount++; - loadX509Cert( cert, "neo4j.javadriver.trustedcert." + certCount, keyStore ); - } - catch ( CertificateException e ) - { - if ( e.getCause() != null && e.getCause().getMessage().equals( "Empty input" ) ) - { - // This happens if there is whitespace at the end of the certificate - we load one cert, and then try and load a + loadX509Cert(cert, "neo4j.javadriver.trustedcert." + certCount, keyStore); + } catch (CertificateException e) { + if (e.getCause() != null && e.getCause().getMessage().equals("Empty input")) { + // This happens if there is whitespace at the end of the certificate - we load one cert, and + // then try and load a // second cert, at which point we fail return; } - throw new IOException( "Failed to load certificate from `" + certFile.getAbsolutePath() + "`: " + certCount + " : " + e.getMessage(), - e ); + throw new IOException( + "Failed to load certificate from `" + certFile.getAbsolutePath() + "`: " + certCount + + " : " + e.getMessage(), + e); } } } } } - public static void loadX509Cert( X509Certificate[] certificates, KeyStore keyStore ) throws GeneralSecurityException, IOException - { - for ( int i = 0; i < certificates.length; i++ ) - { - loadX509Cert( certificates[i], "neo4j.javadriver.trustedcert." + i, keyStore ); + public static void loadX509Cert(X509Certificate[] certificates, KeyStore keyStore) + throws GeneralSecurityException, IOException { + for (int i = 0; i < certificates.length; i++) { + loadX509Cert(certificates[i], "neo4j.javadriver.trustedcert." + i, keyStore); } } @@ -160,9 +149,8 @@ public static void loadX509Cert( X509Certificate[] certificates, KeyStore keySto * @param cert * @param keyStore */ - public static void loadX509Cert( Certificate cert, String certAlias, KeyStore keyStore ) throws KeyStoreException - { - keyStore.setCertificateEntry( certAlias, cert ); + public static void loadX509Cert(Certificate cert, String certAlias, KeyStore keyStore) throws KeyStoreException { + keyStore.setCertificateEntry(certAlias, cert); } /** @@ -170,16 +158,10 @@ public static void loadX509Cert( Certificate cert, String certAlias, KeyStore ke * @param cert encoded cert string * @return */ - public static String X509CertToString( String cert ) - { - String cert64CharPerLine = cert.replaceAll( "(.{64})", "$1\n" ); - return BEGIN_CERT + "\n" + cert64CharPerLine + "\n"+ END_CERT + "\n"; + public static String X509CertToString(String cert) { + String cert64CharPerLine = cert.replaceAll("(.{64})", "$1\n"); + return BEGIN_CERT + "\n" + cert64CharPerLine + "\n" + END_CERT + "\n"; } - private CertificateTool() - { - } + private CertificateTool() {} } - - - 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 index 4ce8a2b36f..0e2b7b0cef 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/Clock.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/Clock.java @@ -21,25 +21,21 @@ /** * Since {@link java.time.Clock} is only available in Java 8, use our own until we drop java 7 support. */ -public interface Clock -{ +public interface Clock { /** Current time, in milliseconds. */ long millis(); - void sleep( long millis ) throws InterruptedException; + void sleep(long millis) throws InterruptedException; - Clock SYSTEM = new Clock() - { + Clock SYSTEM = new Clock() { @Override - public long millis() - { + public long millis() { return System.currentTimeMillis(); } @Override - public void sleep( long millis ) throws InterruptedException - { - Thread.sleep( millis ); + public void sleep(long millis) throws InterruptedException { + Thread.sleep(millis); } }; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java b/driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java index 2abfa62fe6..e1a2175291 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java @@ -19,11 +19,9 @@ package org.neo4j.driver.internal.util; import io.netty.util.internal.PlatformDependent; - import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.stream.Stream; - import org.neo4j.driver.exceptions.AuthenticationException; import org.neo4j.driver.exceptions.AuthorizationExpiredException; import org.neo4j.driver.exceptions.ClientException; @@ -36,159 +34,122 @@ import org.neo4j.driver.exceptions.TokenExpiredException; import org.neo4j.driver.exceptions.TransientException; -public final class ErrorUtil -{ - private ErrorUtil() - { - } +public final class ErrorUtil { + private ErrorUtil() {} - public static ServiceUnavailableException newConnectionTerminatedError( String reason ) - { - if ( reason == null ) - { + public static ServiceUnavailableException newConnectionTerminatedError(String reason) { + if (reason == null) { return newConnectionTerminatedError(); } - return new ServiceUnavailableException( "Connection to the database terminated. " + reason ); + return new ServiceUnavailableException("Connection to the database terminated. " + reason); } - public static ServiceUnavailableException newConnectionTerminatedError() - { - return new ServiceUnavailableException( "Connection to the database terminated. " + - "Please ensure that your database is listening on the correct host and port and that you have compatible encryption settings both on Neo4j server and driver. " + - "Note that the default encryption setting has changed in Neo4j 4.0." ); + public static ServiceUnavailableException newConnectionTerminatedError() { + return new ServiceUnavailableException("Connection to the database terminated. " + + "Please ensure that your database is listening on the correct host and port and that you have compatible encryption settings both on Neo4j server and driver. " + + "Note that the default encryption setting has changed in Neo4j 4.0."); } - public static ResultConsumedException newResultConsumedError() - { - return new ResultConsumedException( "Cannot access records on this result any more as the result has already been consumed " + - "or the query runner where the result is created has already been closed." ); + public static ResultConsumedException newResultConsumedError() { + return new ResultConsumedException( + "Cannot access records on this result any more as the result has already been consumed " + + "or the query runner where the result is created has already been closed."); } - public static Neo4jException newNeo4jError( String code, String message ) - { - switch ( extractErrorClass( code ) ) - { - case "ClientError": - if ( "Security".equals( extractErrorSubClass( code ) ) ) - { - if ( code.equalsIgnoreCase( "Neo.ClientError.Security.Unauthorized" ) ) - { - return new AuthenticationException( code, message ); - } - else if ( code.equalsIgnoreCase( "Neo.ClientError.Security.AuthorizationExpired" ) ) - { - return new AuthorizationExpiredException( code, message ); - } - else if ( code.equalsIgnoreCase( "Neo.ClientError.Security.TokenExpired" ) ) - { - return new TokenExpiredException( code, message ); + public static Neo4jException newNeo4jError(String code, String message) { + switch (extractErrorClass(code)) { + case "ClientError": + if ("Security".equals(extractErrorSubClass(code))) { + if (code.equalsIgnoreCase("Neo.ClientError.Security.Unauthorized")) { + return new AuthenticationException(code, message); + } else if (code.equalsIgnoreCase("Neo.ClientError.Security.AuthorizationExpired")) { + return new AuthorizationExpiredException(code, message); + } else if (code.equalsIgnoreCase("Neo.ClientError.Security.TokenExpired")) { + return new TokenExpiredException(code, message); + } else { + return new SecurityException(code, message); + } + } else { + if (code.equalsIgnoreCase("Neo.ClientError.Database.DatabaseNotFound")) { + return new FatalDiscoveryException(code, message); + } else { + return new ClientException(code, message); + } } - else - { - return new SecurityException( code, message ); - } - } - else - { - if ( code.equalsIgnoreCase( "Neo.ClientError.Database.DatabaseNotFound" ) ) - { - return new FatalDiscoveryException( code, message ); - } - else - { - return new ClientException( code, message ); - } - } - case "TransientError": - return new TransientException( code, message ); - default: - return new DatabaseException( code, message ); + case "TransientError": + return new TransientException(code, message); + default: + return new DatabaseException(code, message); } } - public static boolean isFatal( Throwable error ) - { - if ( error instanceof Neo4jException ) - { - if ( isProtocolViolationError( ((Neo4jException) error) ) ) - { + public static boolean isFatal(Throwable error) { + if (error instanceof Neo4jException) { + if (isProtocolViolationError(((Neo4jException) error))) { return true; } - if ( isClientOrTransientError( ((Neo4jException) error) ) ) - { + if (isClientOrTransientError(((Neo4jException) error))) { return false; } } return true; } - public static void rethrowAsyncException( ExecutionException e ) - { + public static void rethrowAsyncException(ExecutionException e) { Throwable error = e.getCause(); - InternalExceptionCause internalCause = new InternalExceptionCause( error.getStackTrace() ); - error.addSuppressed( internalCause ); + InternalExceptionCause internalCause = new InternalExceptionCause(error.getStackTrace()); + error.addSuppressed(internalCause); - StackTraceElement[] currentStackTrace = Stream.of( Thread.currentThread().getStackTrace() ) - .skip( 2 ) // do not include Thread.currentThread() and this method in the stacktrace - .toArray( StackTraceElement[]::new ); - error.setStackTrace( currentStackTrace ); + StackTraceElement[] currentStackTrace = Stream.of(Thread.currentThread().getStackTrace()) + .skip(2) // do not include Thread.currentThread() and this method in the stacktrace + .toArray(StackTraceElement[]::new); + error.setStackTrace(currentStackTrace); - PlatformDependent.throwException( error ); + PlatformDependent.throwException(error); } - private static boolean isProtocolViolationError( Neo4jException error ) - { + private static boolean isProtocolViolationError(Neo4jException error) { String errorCode = error.code(); - return errorCode != null && errorCode.startsWith( "Neo.ClientError.Request" ); + return errorCode != null && errorCode.startsWith("Neo.ClientError.Request"); } - private static boolean isClientOrTransientError( Neo4jException error ) - { + private static boolean isClientOrTransientError(Neo4jException error) { String errorCode = error.code(); - return errorCode != null && (errorCode.contains( "ClientError" ) || errorCode.contains( "TransientError" )); + return errorCode != null && (errorCode.contains("ClientError") || errorCode.contains("TransientError")); } - private static String extractErrorClass( String code ) - { - String[] parts = code.split( "\\." ); - if ( parts.length < 2 ) - { + private static String extractErrorClass(String code) { + String[] parts = code.split("\\."); + if (parts.length < 2) { return ""; } return parts[1]; } - private static String extractErrorSubClass( String code ) - { - String[] parts = code.split( "\\." ); - if ( parts.length < 3 ) - { + private static String extractErrorSubClass(String code) { + String[] parts = code.split("\\."); + if (parts.length < 3) { return ""; } return parts[2]; } - public static void addSuppressed( Throwable mainError, Throwable error ) - { - if ( mainError != error ) - { - mainError.addSuppressed( error ); + public static void addSuppressed(Throwable mainError, Throwable error) { + if (mainError != error) { + mainError.addSuppressed(error); } } - public static Throwable getRootCause( Throwable error ) - { - Objects.requireNonNull( error ); + public static Throwable getRootCause(Throwable error) { + Objects.requireNonNull(error); Throwable cause = error.getCause(); - if ( cause == null ) - { + if (cause == null) { // Nothing causes this error, returns the error itself return error; } - while ( cause.getCause() != null ) - { + while (cause.getCause() != null) { cause = cause.getCause(); } return cause; @@ -198,16 +159,13 @@ public static Throwable getRootCause( Throwable error ) * Exception which is merely a holder of an async stacktrace, which is not the primary stacktrace users are interested in. * Used for blocking API calls that block on async API calls. */ - private static class InternalExceptionCause extends RuntimeException - { - InternalExceptionCause( StackTraceElement[] stackTrace ) - { - setStackTrace( stackTrace ); + private static class InternalExceptionCause extends RuntimeException { + InternalExceptionCause(StackTraceElement[] stackTrace) { + setStackTrace(stackTrace); } @Override - public synchronized Throwable fillInStackTrace() - { + public synchronized Throwable fillInStackTrace() { // no need to fill in the stack trace // this exception just uses the given stack trace return this; diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/Extract.java b/driver/src/main/java/org/neo4j/driver/internal/util/Extract.java index 3c188cd009..4996fb1a2c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/Extract.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/Extract.java @@ -18,206 +18,177 @@ */ package org.neo4j.driver.internal.util; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static java.util.Collections.unmodifiableList; +import static java.util.Collections.unmodifiableMap; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.Iterables.newHashMapWithSize; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; - +import java.util.function.Function; +import org.neo4j.driver.Record; +import org.neo4j.driver.Value; +import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.InternalPair; import org.neo4j.driver.internal.value.NodeValue; import org.neo4j.driver.internal.value.PathValue; import org.neo4j.driver.internal.value.RelationshipValue; -import org.neo4j.driver.Record; -import org.neo4j.driver.Value; -import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.types.MapAccessor; import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Path; import org.neo4j.driver.types.Relationship; -import java.util.function.Function; import org.neo4j.driver.util.Pair; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static java.util.Collections.unmodifiableList; -import static java.util.Collections.unmodifiableMap; -import static org.neo4j.driver.internal.util.Iterables.newHashMapWithSize; -import static org.neo4j.driver.Values.value; - /** * Utility class for extracting data. */ -public final class Extract -{ - private Extract() - { +public final class Extract { + private Extract() { throw new UnsupportedOperationException(); } - public static List list( Value[] values ) - { - switch ( values.length ) - { + public static List list(Value[] values) { + switch (values.length) { case 0: return emptyList(); case 1: - return singletonList( values[0] ); + return singletonList(values[0]); default: - return unmodifiableList( Arrays.asList( values ) ); + return unmodifiableList(Arrays.asList(values)); } } - public static List list( Value[] data, Function mapFunction ) - { + public static List list(Value[] data, Function mapFunction) { int size = data.length; - switch ( size ) - { + switch (size) { case 0: return emptyList(); case 1: - return singletonList( mapFunction.apply( data[0] ) ); + return singletonList(mapFunction.apply(data[0])); default: - List result = new ArrayList<>( size ); - for ( Value value : data ) - { - result.add( mapFunction.apply( value ) ); + List result = new ArrayList<>(size); + for (Value value : data) { + result.add(mapFunction.apply(value)); } - return unmodifiableList( result ); + return unmodifiableList(result); } } - public static Map map( Map data, Function mapFunction ) - { - if ( data.isEmpty() ) { + public static Map map(Map data, Function mapFunction) { + if (data.isEmpty()) { return emptyMap(); } else { int size = data.size(); - if ( size == 1 ) { + if (size == 1) { Map.Entry head = data.entrySet().iterator().next(); - return singletonMap( head.getKey(), mapFunction.apply( head.getValue() ) ); + return singletonMap(head.getKey(), mapFunction.apply(head.getValue())); } else { - Map map = Iterables.newLinkedHashMapWithSize( size ); - for ( Map.Entry entry : data.entrySet() ) - { - map.put( entry.getKey(), mapFunction.apply( entry.getValue() ) ); + Map map = Iterables.newLinkedHashMapWithSize(size); + for (Map.Entry entry : data.entrySet()) { + map.put(entry.getKey(), mapFunction.apply(entry.getValue())); } - return unmodifiableMap( map ); + return unmodifiableMap(map); } } } - public static Map map( Record record, Function mapFunction ) - { + public static Map map(Record record, Function mapFunction) { int size = record.size(); - switch ( size ) - { + switch (size) { case 0: return emptyMap(); case 1: - return singletonMap( record.keys().get( 0 ), mapFunction.apply( record.get( 0 ) ) ); + return singletonMap(record.keys().get(0), mapFunction.apply(record.get(0))); default: - Map map = Iterables.newLinkedHashMapWithSize( size ); + Map map = Iterables.newLinkedHashMapWithSize(size); List keys = record.keys(); - for ( int i = 0; i < size; i++ ) - { - map.put( keys.get( i ), mapFunction.apply( record.get( i ) ) ); + for (int i = 0; i < size; i++) { + map.put(keys.get(i), mapFunction.apply(record.get(i))); } - return unmodifiableMap( map ); + return unmodifiableMap(map); } } - public static Iterable> properties( final MapAccessor map, final Function mapFunction ) - { + public static Iterable> properties( + final MapAccessor map, final Function mapFunction) { int size = map.size(); - switch ( size ) - { + switch (size) { case 0: return emptyList(); - case 1: - { + case 1: { String key = map.keys().iterator().next(); - Value value = map.get( key ); - return singletonList( InternalPair.of( key, mapFunction.apply( value ) ) ); + Value value = map.get(key); + return singletonList(InternalPair.of(key, mapFunction.apply(value))); } - default: - { - List> list = new ArrayList<>( size ); - for ( String key : map.keys() ) - { - Value value = map.get( key ); - list.add( InternalPair.of( key, mapFunction.apply( value ) ) ); + default: { + List> list = new ArrayList<>(size); + for (String key : map.keys()) { + Value value = map.get(key); + list.add(InternalPair.of(key, mapFunction.apply(value))); } - return unmodifiableList( list ); + return unmodifiableList(list); } } } - public static List> fields( final Record map, final Function mapFunction ) - { + public static List> fields(final Record map, final Function mapFunction) { int size = map.keys().size(); - switch ( size ) - { + switch (size) { case 0: return emptyList(); - case 1: - { + case 1: { String key = map.keys().iterator().next(); - Value value = map.get( key ); - return singletonList( InternalPair.of( key, mapFunction.apply( value ) ) ); + Value value = map.get(key); + return singletonList(InternalPair.of(key, mapFunction.apply(value))); } - default: - { - List> list = new ArrayList<>( size ); + default: { + List> list = new ArrayList<>(size); List keys = map.keys(); - for ( int i = 0; i < size; i++ ) - { - String key = keys.get( i ); - Value value = map.get( i ); - list.add( InternalPair.of( key, mapFunction.apply( value ) ) ); + for (int i = 0; i < size; i++) { + String key = keys.get(i); + Value value = map.get(i); + list.add(InternalPair.of(key, mapFunction.apply(value))); } - return unmodifiableList( list ); + return unmodifiableList(list); } } } - public static Map mapOfValues( Map map ) - { - if ( map == null || map.isEmpty() ) - { + public static Map mapOfValues(Map map) { + if (map == null || map.isEmpty()) { return emptyMap(); } - Map result = newHashMapWithSize( map.size() ); - for ( Map.Entry entry : map.entrySet() ) - { + Map result = newHashMapWithSize(map.size()); + for (Map.Entry entry : map.entrySet()) { Object value = entry.getValue(); - assertParameter( value ); - result.put( entry.getKey(), value( value ) ); + assertParameter(value); + result.put(entry.getKey(), value(value)); } return result; } - public static void assertParameter( Object value ) - { - if ( value instanceof Node || value instanceof NodeValue ) - { - throw new ClientException( "Nodes can't be used as parameters." ); + public static void assertParameter(Object value) { + if (value instanceof Node || value instanceof NodeValue) { + throw new ClientException("Nodes can't be used as parameters."); } - if ( value instanceof Relationship || value instanceof RelationshipValue ) - { - throw new ClientException( "Relationships can't be used as parameters." ); + if (value instanceof Relationship || value instanceof RelationshipValue) { + throw new ClientException("Relationships can't be used as parameters."); } - if ( value instanceof Path || value instanceof PathValue ) - { - throw new ClientException( "Paths can't be used as parameters." ); + if (value instanceof Path || value instanceof PathValue) { + throw new ClientException("Paths can't be used as parameters."); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/Format.java b/driver/src/main/java/org/neo4j/driver/internal/util/Format.java index e8395779f1..4778a5958f 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/Format.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/Format.java @@ -22,53 +22,45 @@ import java.util.Map; import java.util.Map.Entry; -public abstract class Format -{ - private Format() - { +public abstract class Format { + private Format() { throw new UnsupportedOperationException(); } // formats map using ':' as key-value separator instead of default '=' - public static String formatPairs( Map entries ) - { - Iterator> iterator = entries.entrySet().iterator(); - switch ( entries.size() ) { + public static String formatPairs(Map entries) { + Iterator> iterator = entries.entrySet().iterator(); + switch (entries.size()) { case 0: return "{}"; - case 1: - { - return String.format( "{%s}", keyValueString( iterator.next() ) ); + case 1: { + return String.format("{%s}", keyValueString(iterator.next())); } - default: - { + default: { StringBuilder builder = new StringBuilder(); - builder.append( "{" ); - builder.append( keyValueString( iterator.next() ) ); - while ( iterator.hasNext() ) - { - builder.append( ',' ); - builder.append( ' ' ); - builder.append( keyValueString( iterator.next() ) ); + builder.append("{"); + builder.append(keyValueString(iterator.next())); + while (iterator.hasNext()) { + builder.append(','); + builder.append(' '); + builder.append(keyValueString(iterator.next())); } - builder.append( "}" ); + builder.append("}"); return builder.toString(); } } } - private static String keyValueString( Entry entry ) - { - return String.format( "%s: %s", entry.getKey(), String.valueOf( entry.getValue() ) ); + private static String keyValueString(Entry entry) { + return String.format("%s: %s", entry.getKey(), String.valueOf(entry.getValue())); } /** * Returns the submitted value if it is not null or an empty string if it is. */ - public static String valueOrEmpty( String value ) - { + public static String valueOrEmpty(String value) { return value != null ? value : ""; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/Futures.java b/driver/src/main/java/org/neo4j/driver/internal/util/Futures.java index ca845ade28..4d69e4cf7e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/Futures.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/Futures.java @@ -18,6 +18,9 @@ */ package org.neo4j.driver.internal.util; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.neo4j.driver.internal.util.ErrorUtil.addSuppressed; + import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; @@ -28,108 +31,74 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; - import org.neo4j.driver.internal.async.connection.EventLoopGroupFactory; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.neo4j.driver.internal.util.ErrorUtil.addSuppressed; +public final class Futures { + private static final CompletableFuture COMPLETED_WITH_NULL = completedFuture(null); -public final class Futures -{ - private static final CompletableFuture COMPLETED_WITH_NULL = completedFuture( null ); - - private Futures() - { - } + private Futures() {} - @SuppressWarnings( "unchecked" ) - public static CompletableFuture completedWithNull() - { + @SuppressWarnings("unchecked") + public static CompletableFuture completedWithNull() { return (CompletableFuture) COMPLETED_WITH_NULL; } - public static CompletableFuture completeWithNullIfNoError( CompletableFuture future, Throwable error ) - { - if ( error != null ) - { - future.completeExceptionally( error ); - } - else - { - future.complete( null ); + public static CompletableFuture completeWithNullIfNoError(CompletableFuture future, Throwable error) { + if (error != null) { + future.completeExceptionally(error); + } else { + future.complete(null); } return future; } - public static CompletionStage asCompletionStage( io.netty.util.concurrent.Future future ) - { + public static CompletionStage asCompletionStage(io.netty.util.concurrent.Future future) { CompletableFuture result = new CompletableFuture<>(); - return asCompletionStage( future, result ); - } - - public static CompletionStage asCompletionStage( io.netty.util.concurrent.Future future, CompletableFuture result ) - { - if ( future.isCancelled() ) - { - result.cancel( true ); - } - else if ( future.isSuccess() ) - { - result.complete( future.getNow() ); - } - else if ( future.cause() != null ) - { - result.completeExceptionally( future.cause() ); - } - else - { - future.addListener( ignore -> - { - if ( future.isCancelled() ) - { - result.cancel( true ); - } - else if ( future.isSuccess() ) - { - result.complete( future.getNow() ); - } - else - { - result.completeExceptionally( future.cause() ); + return asCompletionStage(future, result); + } + + public static CompletionStage asCompletionStage( + io.netty.util.concurrent.Future future, CompletableFuture result) { + if (future.isCancelled()) { + result.cancel(true); + } else if (future.isSuccess()) { + result.complete(future.getNow()); + } else if (future.cause() != null) { + result.completeExceptionally(future.cause()); + } else { + future.addListener(ignore -> { + if (future.isCancelled()) { + result.cancel(true); + } else if (future.isSuccess()) { + result.complete(future.getNow()); + } else { + result.completeExceptionally(future.cause()); } - } ); + }); } return result; } - public static CompletableFuture failedFuture( Throwable error ) - { + public static CompletableFuture failedFuture(Throwable error) { CompletableFuture result = new CompletableFuture<>(); - result.completeExceptionally( error ); + result.completeExceptionally(error); return result; } - public static V blockingGet( CompletionStage stage ) - { - return blockingGet( stage, Futures::noOpInterruptHandler ); + public static V blockingGet(CompletionStage stage) { + return blockingGet(stage, Futures::noOpInterruptHandler); } - public static V blockingGet( CompletionStage stage, Runnable interruptHandler ) - { + public static V blockingGet(CompletionStage stage, Runnable interruptHandler) { EventLoopGroupFactory.assertNotInEventLoopThread(); Future future = stage.toCompletableFuture(); boolean interrupted = false; - try - { - while ( true ) - { - try - { + try { + while (true) { + try { return future.get(); - } - catch ( InterruptedException e ) - { + } catch (InterruptedException e) { // this thread was interrupted while waiting // computation denoted by the future might still be running @@ -137,36 +106,27 @@ public static V blockingGet( CompletionStage stage, Runnable interruptHan // run the interrupt handler and ignore if it throws // need to wait for IO thread to actually finish, can't simply re-rethrow - safeRun( interruptHandler ); - } - catch ( ExecutionException e ) - { - ErrorUtil.rethrowAsyncException( e ); + safeRun(interruptHandler); + } catch (ExecutionException e) { + ErrorUtil.rethrowAsyncException(e); } } - } - finally - { - if ( interrupted ) - { + } finally { + if (interrupted) { Thread.currentThread().interrupt(); } } } - public static T getNow( CompletionStage stage ) - { - return stage.toCompletableFuture().getNow( null ); + public static T getNow(CompletionStage stage) { + return stage.toCompletableFuture().getNow(null); } - public static T joinNowOrElseThrow( CompletableFuture future, Supplier exceptionSupplier ) - { - if ( future.isDone() ) - { + public static T joinNowOrElseThrow( + CompletableFuture future, Supplier exceptionSupplier) { + if (future.isDone()) { return future.join(); - } - else - { + } else { throw exceptionSupplier.get(); } } @@ -180,10 +140,8 @@ public static T joinNowOrElseThrow( CompletableFuture future, Supplier type * @return a new completed future with the same completed value if the given future completes successfully, otherwise continues with the onErrorAction. */ - @SuppressWarnings( "ThrowableNotThrown" ) - public static CompletableFuture onErrorContinue( CompletableFuture future, Throwable errorRecorder, - Function> onErrorAction ) - { - Objects.requireNonNull( future ); - return future.handle( ( value, error ) -> { - if ( error != null ) - { - // record error - Futures.combineErrors( errorRecorder, error ); - return new CompletionResult( null, error ); - } - return new CompletionResult<>( value, null ); - } ).thenCompose( result -> { - if ( result.value != null ) - { - return completedFuture( result.value ); - } - else - { - return onErrorAction.apply( result.error ); - } - } ); - } - - public static BiConsumer futureCompletingConsumer( CompletableFuture future ) - { - return ( value, throwable ) -> - { - if ( throwable != null ) - { - future.completeExceptionally( throwable ); - } - else - { - future.complete( value ); + @SuppressWarnings("ThrowableNotThrown") + public static CompletableFuture onErrorContinue( + CompletableFuture future, + Throwable errorRecorder, + Function> onErrorAction) { + Objects.requireNonNull(future); + return future.handle((value, error) -> { + if (error != null) { + // record error + Futures.combineErrors(errorRecorder, error); + return new CompletionResult(null, error); + } + return new CompletionResult<>(value, null); + }) + .thenCompose(result -> { + if (result.value != null) { + return completedFuture(result.value); + } else { + return onErrorAction.apply(result.error); + } + }); + } + + public static BiConsumer futureCompletingConsumer(CompletableFuture future) { + return (value, throwable) -> { + if (throwable != null) { + future.completeExceptionally(throwable); + } else { + future.complete(value); } }; } - private static class CompletionResult - { + private static class CompletionResult { T value; Throwable error; - CompletionResult( T value, Throwable error ) - { + CompletionResult(T value, Throwable error) { this.value = value; this.error = error; } } - private static void safeRun( Runnable runnable ) - { - try - { + private static void safeRun(Runnable runnable) { + try { runnable.run(); - } - catch ( Throwable ignore ) - { + } catch (Throwable ignore) { } } - private static void noOpInterruptHandler() - { - } + private static void noOpInterruptHandler() {} } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/Iterables.java b/driver/src/main/java/org/neo4j/driver/internal/util/Iterables.java index daa2f1e35a..9e845559f6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/Iterables.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/Iterables.java @@ -28,87 +28,74 @@ import java.util.List; import java.util.Map; import java.util.Queue; - import java.util.function.Function; -public class Iterables -{ - @SuppressWarnings( "rawtypes" ) +public class Iterables { + @SuppressWarnings("rawtypes") private static final Queue EMPTY_QUEUE = new EmptyQueue(); + private static final float DEFAULT_HASH_MAP_LOAD_FACTOR = 0.75F; - public static int count( Iterable it ) - { - if ( it instanceof Collection ) { return ((Collection) it).size(); } + public static int count(Iterable it) { + if (it instanceof Collection) { + return ((Collection) it).size(); + } int size = 0; - for ( Object o : it ) - { + for (Object o : it) { size++; } return size; } - public static List asList( Iterable it ) - { - if ( it instanceof List ) { return (List) it; } + public static List asList(Iterable it) { + if (it instanceof List) { + return (List) it; + } List list = new ArrayList<>(); - for ( T t : it ) - { - list.add( t ); + for (T t : it) { + list.add(t); } return list; } - public static T single( Iterable it ) - { + public static T single(Iterable it) { Iterator iterator = it.iterator(); - if ( !iterator.hasNext() ) - { - throw new IllegalArgumentException( "Given iterable is empty" ); + if (!iterator.hasNext()) { + throw new IllegalArgumentException("Given iterable is empty"); } T result = iterator.next(); - if ( iterator.hasNext() ) - { - throw new IllegalArgumentException( "Given iterable contains more than one element: " + it ); + if (iterator.hasNext()) { + throw new IllegalArgumentException("Given iterable contains more than one element: " + it); } return result; } - public static Map map( String ... alternatingKeyValue ) - { - Map out = newHashMapWithSize( alternatingKeyValue.length / 2 ); - for ( int i = 0; i < alternatingKeyValue.length; i+=2 ) - { - out.put( alternatingKeyValue[i], alternatingKeyValue[i+1] ); + public static Map map(String... alternatingKeyValue) { + Map out = newHashMapWithSize(alternatingKeyValue.length / 2); + for (int i = 0; i < alternatingKeyValue.length; i += 2) { + out.put(alternatingKeyValue[i], alternatingKeyValue[i + 1]); } return out; } - public static Iterable map(final Iterable it, final Function f) - { - return new Iterable() - { + public static Iterable map(final Iterable it, final Function f) { + return new Iterable() { @Override - public Iterator iterator() - { + public Iterator iterator() { final Iterator aIterator = it.iterator(); - return new Iterator() - { + return new Iterator() { @Override - public boolean hasNext() - { + public boolean hasNext() { return aIterator.hasNext(); } @Override - public B next() - { - return f.apply( aIterator.next() ); + public B next() { + return f.apply(aIterator.next()); } @Override - public void remove() - { + public void remove() { aIterator.remove(); } }; @@ -116,64 +103,52 @@ public void remove() }; } - @SuppressWarnings( "unchecked" ) - public static Queue emptyQueue() - { + @SuppressWarnings("unchecked") + public static Queue emptyQueue() { return (Queue) EMPTY_QUEUE; } - public static HashMap newHashMapWithSize( int expectedSize ) - { - return new HashMap<>( hashMapCapacity( expectedSize ) ); + public static HashMap newHashMapWithSize(int expectedSize) { + return new HashMap<>(hashMapCapacity(expectedSize)); } - public static LinkedHashMap newLinkedHashMapWithSize( int expectedSize ) - { - return new LinkedHashMap<>( hashMapCapacity( expectedSize ) ); + public static LinkedHashMap newLinkedHashMapWithSize(int expectedSize) { + return new LinkedHashMap<>(hashMapCapacity(expectedSize)); } - private static int hashMapCapacity( int expectedSize ) - { - if ( expectedSize < 3 ) - { - if ( expectedSize < 0 ) - { - throw new IllegalArgumentException( "Illegal map size: " + expectedSize ); + private static int hashMapCapacity(int expectedSize) { + if (expectedSize < 3) { + if (expectedSize < 0) { + throw new IllegalArgumentException("Illegal map size: " + expectedSize); } return expectedSize + 1; } return (int) ((float) expectedSize / DEFAULT_HASH_MAP_LOAD_FACTOR + 1.0F); } - private static class EmptyQueue extends AbstractQueue - { + private static class EmptyQueue extends AbstractQueue { @Override - public Iterator iterator() - { + public Iterator iterator() { return Collections.emptyIterator(); } @Override - public int size() - { + public int size() { return 0; } @Override - public boolean offer( T t ) - { + public boolean offer(T t) { throw new UnsupportedOperationException(); } @Override - public T poll() - { + public T poll() { return null; } @Override - public T peek() - { + public T peek() { return null; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/LockUtil.java b/driver/src/main/java/org/neo4j/driver/internal/util/LockUtil.java index f308921ef3..9d31f0ab63 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/LockUtil.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/LockUtil.java @@ -23,39 +23,29 @@ import java.util.concurrent.locks.Lock; import java.util.function.Supplier; -public class LockUtil -{ - public static void executeWithLock( Lock lock, Runnable runnable ) - { +public class LockUtil { + public static void executeWithLock(Lock lock, Runnable runnable) { lock.lock(); - try - { + try { runnable.run(); - } - finally - { + } finally { lock.unlock(); } } - public static T executeWithLock( Lock lock, Supplier supplier ) - { + public static T executeWithLock(Lock lock, Supplier supplier) { lock.lock(); - try - { + try { return supplier.get(); - } - finally - { + } finally { lock.unlock(); } } - public static void executeWithLockAsync( Lock lock, Supplier> stageSupplier ) - { + public static void executeWithLockAsync(Lock lock, Supplier> stageSupplier) { lock.lock(); - CompletableFuture.completedFuture( lock ) - .thenCompose( ignored -> stageSupplier.get() ) - .whenComplete( ( ignored, throwable ) -> lock.unlock() ); + CompletableFuture.completedFuture(lock) + .thenCompose(ignored -> stageSupplier.get()) + .whenComplete((ignored, throwable) -> lock.unlock()); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/MetadataExtractor.java b/driver/src/main/java/org/neo4j/driver/internal/util/MetadataExtractor.java index 7d9f8606fb..3886458102 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/MetadataExtractor.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/MetadataExtractor.java @@ -18,11 +18,13 @@ */ package org.neo4j.driver.internal.util; +import static org.neo4j.driver.internal.summary.InternalDatabaseInfo.DEFAULT_DATABASE_INFO; +import static org.neo4j.driver.internal.types.InternalTypeSystem.TYPE_SYSTEM; + import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; import org.neo4j.driver.Value; @@ -45,35 +47,26 @@ import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.summary.ServerInfo; -import static org.neo4j.driver.internal.summary.InternalDatabaseInfo.DEFAULT_DATABASE_INFO; -import static org.neo4j.driver.internal.types.InternalTypeSystem.TYPE_SYSTEM; - -public class MetadataExtractor -{ +public class MetadataExtractor { public static final int ABSENT_QUERY_ID = -1; private static final String UNEXPECTED_TYPE_MSG_FMT = "Unexpected query type '%s', consider updating the driver"; - private static final Function UNEXPECTED_TYPE_EXCEPTION_SUPPLIER = - ( type ) -> new ProtocolException( String.format( UNEXPECTED_TYPE_MSG_FMT, type ) ); + private static final Function UNEXPECTED_TYPE_EXCEPTION_SUPPLIER = + (type) -> new ProtocolException(String.format(UNEXPECTED_TYPE_MSG_FMT, type)); private final String resultAvailableAfterMetadataKey; private final String resultConsumedAfterMetadataKey; - public MetadataExtractor( String resultAvailableAfterMetadataKey, String resultConsumedAfterMetadataKey ) - { + public MetadataExtractor(String resultAvailableAfterMetadataKey, String resultConsumedAfterMetadataKey) { this.resultAvailableAfterMetadataKey = resultAvailableAfterMetadataKey; this.resultConsumedAfterMetadataKey = resultConsumedAfterMetadataKey; } - public QueryKeys extractQueryKeys( Map metadata ) - { - Value keysValue = metadata.get( "fields" ); - if ( keysValue != null ) - { - if ( !keysValue.isEmpty() ) - { - QueryKeys keys = new QueryKeys( keysValue.size() ); - for ( Value value : keysValue.values() ) - { - keys.add( value.asString() ); + public QueryKeys extractQueryKeys(Map metadata) { + Value keysValue = metadata.get("fields"); + if (keysValue != null) { + if (!keysValue.isEmpty()) { + QueryKeys keys = new QueryKeys(keysValue.size()); + for (Value value : keysValue.values()) { + keys.add(value.asString()); } return keys; @@ -82,158 +75,139 @@ public QueryKeys extractQueryKeys( Map metadata ) return QueryKeys.empty(); } - public long extractQueryId( Map metadata ) - { - Value queryId = metadata.get( "qid" ); - if ( queryId != null ) - { + public long extractQueryId(Map metadata) { + Value queryId = metadata.get("qid"); + if (queryId != null) { return queryId.asLong(); } return ABSENT_QUERY_ID; } - - public long extractResultAvailableAfter( Map metadata ) - { - Value resultAvailableAfterValue = metadata.get( resultAvailableAfterMetadataKey ); - if ( resultAvailableAfterValue != null ) - { + public long extractResultAvailableAfter(Map metadata) { + Value resultAvailableAfterValue = metadata.get(resultAvailableAfterMetadataKey); + if (resultAvailableAfterValue != null) { return resultAvailableAfterValue.asLong(); } return -1; } - public ResultSummary extractSummary( Query query, Connection connection, long resultAvailableAfter, Map metadata ) - { - ServerInfo serverInfo = - new InternalServerInfo( connection.serverAgent(), connection.serverAddress(), connection.serverVersion(), connection.protocol().version() ); - DatabaseInfo dbInfo = extractDatabaseInfo( metadata ); - return new InternalResultSummary( query, serverInfo, dbInfo, extractQueryType( metadata ), extractCounters( metadata ), extractPlan( metadata ), - extractProfiledPlan( metadata ), extractNotifications( metadata ), resultAvailableAfter, - extractResultConsumedAfter( metadata, resultConsumedAfterMetadataKey ) ); - } - - public static DatabaseInfo extractDatabaseInfo( Map metadata ) - { - Value dbValue = metadata.get( "db" ); - if ( dbValue == null || dbValue.isNull() ) - { + public ResultSummary extractSummary( + Query query, Connection connection, long resultAvailableAfter, Map metadata) { + ServerInfo serverInfo = new InternalServerInfo( + connection.serverAgent(), + connection.serverAddress(), + connection.serverVersion(), + connection.protocol().version()); + DatabaseInfo dbInfo = extractDatabaseInfo(metadata); + return new InternalResultSummary( + query, + serverInfo, + dbInfo, + extractQueryType(metadata), + extractCounters(metadata), + extractPlan(metadata), + extractProfiledPlan(metadata), + extractNotifications(metadata), + resultAvailableAfter, + extractResultConsumedAfter(metadata, resultConsumedAfterMetadataKey)); + } + + public static DatabaseInfo extractDatabaseInfo(Map metadata) { + Value dbValue = metadata.get("db"); + if (dbValue == null || dbValue.isNull()) { return DEFAULT_DATABASE_INFO; - } - else - { - return new InternalDatabaseInfo( dbValue.asString() ); + } else { + return new InternalDatabaseInfo(dbValue.asString()); } } - public static Bookmark extractBookmarks( Map metadata ) - { - Value bookmarkValue = metadata.get( "bookmark" ); - if ( bookmarkValue != null && !bookmarkValue.isNull() && bookmarkValue.hasType( TYPE_SYSTEM.STRING() ) ) - { - return InternalBookmark.parse( bookmarkValue.asString() ); + public static Bookmark extractBookmarks(Map metadata) { + Value bookmarkValue = metadata.get("bookmark"); + if (bookmarkValue != null && !bookmarkValue.isNull() && bookmarkValue.hasType(TYPE_SYSTEM.STRING())) { + return InternalBookmark.parse(bookmarkValue.asString()); } return InternalBookmark.empty(); } - public static ServerVersion extractNeo4jServerVersion( Map metadata ) - { - Value serverValue = extractServer( metadata ); - ServerVersion server = ServerVersion.version( serverValue.asString() ); - if ( ServerVersion.NEO4J_PRODUCT.equalsIgnoreCase( server.product() ) ) - { + public static ServerVersion extractNeo4jServerVersion(Map metadata) { + Value serverValue = extractServer(metadata); + ServerVersion server = ServerVersion.version(serverValue.asString()); + if (ServerVersion.NEO4J_PRODUCT.equalsIgnoreCase(server.product())) { return server; - } - else - { - throw new UntrustedServerException( "Server does not identify as a genuine Neo4j instance: '" + server.product() + "'" ); + } else { + throw new UntrustedServerException( + "Server does not identify as a genuine Neo4j instance: '" + server.product() + "'"); } } - public static Value extractServer( Map metadata ) - { - Value versionValue = metadata.get( "server" ); - if ( versionValue == null || versionValue.isNull() ) - { - throw new UntrustedServerException( "Server provides no product identifier" ); + public static Value extractServer(Map metadata) { + Value versionValue = metadata.get("server"); + if (versionValue == null || versionValue.isNull()) { + throw new UntrustedServerException("Server provides no product identifier"); } return versionValue; } - private static QueryType extractQueryType( Map metadata ) - { - Value typeValue = metadata.get( "type" ); - if ( typeValue != null ) - { - return QueryType.fromCode( typeValue.asString(), UNEXPECTED_TYPE_EXCEPTION_SUPPLIER ); + private static QueryType extractQueryType(Map metadata) { + Value typeValue = metadata.get("type"); + if (typeValue != null) { + return QueryType.fromCode(typeValue.asString(), UNEXPECTED_TYPE_EXCEPTION_SUPPLIER); } return null; } - private static InternalSummaryCounters extractCounters( Map metadata ) - { - Value countersValue = metadata.get( "stats" ); - if ( countersValue != null ) - { + private static InternalSummaryCounters extractCounters(Map metadata) { + Value countersValue = metadata.get("stats"); + if (countersValue != null) { return new InternalSummaryCounters( - counterValue( countersValue, "nodes-created" ), - counterValue( countersValue, "nodes-deleted" ), - counterValue( countersValue, "relationships-created" ), - counterValue( countersValue, "relationships-deleted" ), - counterValue( countersValue, "properties-set" ), - counterValue( countersValue, "labels-added" ), - counterValue( countersValue, "labels-removed" ), - counterValue( countersValue, "indexes-added" ), - counterValue( countersValue, "indexes-removed" ), - counterValue( countersValue, "constraints-added" ), - counterValue( countersValue, "constraints-removed" ), - counterValue( countersValue, "system-updates" ) - ); + counterValue(countersValue, "nodes-created"), + counterValue(countersValue, "nodes-deleted"), + counterValue(countersValue, "relationships-created"), + counterValue(countersValue, "relationships-deleted"), + counterValue(countersValue, "properties-set"), + counterValue(countersValue, "labels-added"), + counterValue(countersValue, "labels-removed"), + counterValue(countersValue, "indexes-added"), + counterValue(countersValue, "indexes-removed"), + counterValue(countersValue, "constraints-added"), + counterValue(countersValue, "constraints-removed"), + counterValue(countersValue, "system-updates")); } return null; } - private static int counterValue( Value countersValue, String name ) - { - Value value = countersValue.get( name ); + private static int counterValue(Value countersValue, String name) { + Value value = countersValue.get(name); return value.isNull() ? 0 : value.asInt(); } - private static Plan extractPlan( Map metadata ) - { - Value planValue = metadata.get( "plan" ); - if ( planValue != null ) - { - return InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply( planValue ); + private static Plan extractPlan(Map metadata) { + Value planValue = metadata.get("plan"); + if (planValue != null) { + return InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply(planValue); } return null; } - private static ProfiledPlan extractProfiledPlan( Map metadata ) - { - Value profiledPlanValue = metadata.get( "profile" ); - if ( profiledPlanValue != null ) - { - return InternalProfiledPlan.PROFILED_PLAN_FROM_VALUE.apply( profiledPlanValue ); + private static ProfiledPlan extractProfiledPlan(Map metadata) { + Value profiledPlanValue = metadata.get("profile"); + if (profiledPlanValue != null) { + return InternalProfiledPlan.PROFILED_PLAN_FROM_VALUE.apply(profiledPlanValue); } return null; } - private static List extractNotifications( Map metadata ) - { - Value notificationsValue = metadata.get( "notifications" ); - if ( notificationsValue != null ) - { - return notificationsValue.asList( InternalNotification.VALUE_TO_NOTIFICATION ); + private static List extractNotifications(Map metadata) { + Value notificationsValue = metadata.get("notifications"); + if (notificationsValue != null) { + return notificationsValue.asList(InternalNotification.VALUE_TO_NOTIFICATION); } return Collections.emptyList(); } - private static long extractResultConsumedAfter( Map metadata, String key ) - { - Value resultConsumedAfterValue = metadata.get( key ); - if ( resultConsumedAfterValue != null ) - { + private static long extractResultConsumedAfter(Map metadata, String key) { + Value resultConsumedAfterValue = metadata.get(key); + if (resultConsumedAfterValue != null) { return resultConsumedAfterValue.asLong(); } return -1; diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/Preconditions.java b/driver/src/main/java/org/neo4j/driver/internal/util/Preconditions.java index cb018aa17f..b60be661c2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/Preconditions.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/Preconditions.java @@ -18,11 +18,8 @@ */ package org.neo4j.driver.internal.util; -public final class Preconditions -{ - private Preconditions() - { - } +public final class Preconditions { + private Preconditions() {} /** * Assert that given expression is true. @@ -31,11 +28,9 @@ private Preconditions() * @param message the message. * @throws IllegalArgumentException if given value is {@code false}. */ - public static void checkArgument( boolean expression, String message ) - { - if ( !expression ) - { - throw new IllegalArgumentException( message ); + public static void checkArgument(boolean expression, String message) { + if (!expression) { + throw new IllegalArgumentException(message); } } @@ -46,11 +41,10 @@ public static void checkArgument( boolean expression, String message ) * @param expectedClass the expected type. * @throws IllegalArgumentException if argument is not of expected type. */ - public static void checkArgument( Object argument, Class expectedClass ) - { - if ( !expectedClass.isInstance( argument ) ) - { - throw new IllegalArgumentException( "Argument expected to be of type: " + expectedClass.getName() + " but was: " + argument ); + public static void checkArgument(Object argument, Class expectedClass) { + if (!expectedClass.isInstance(argument)) { + throw new IllegalArgumentException( + "Argument expected to be of type: " + expectedClass.getName() + " but was: " + argument); } } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/QueryKeys.java b/driver/src/main/java/org/neo4j/driver/internal/util/QueryKeys.java index d5f6d3ba5e..ac6bee498c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/QueryKeys.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/QueryKeys.java @@ -18,95 +18,80 @@ */ package org.neo4j.driver.internal.util; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; - -public class QueryKeys -{ - private static final QueryKeys EMPTY = new QueryKeys( emptyList(), emptyMap() ); +public class QueryKeys { + private static final QueryKeys EMPTY = new QueryKeys(emptyList(), emptyMap()); private final List keys; - private final Map keyIndex; + private final Map keyIndex; - public QueryKeys( int size ) - { - this( new ArrayList<>( size ), new HashMap<>( size ) ); + public QueryKeys(int size) { + this(new ArrayList<>(size), new HashMap<>(size)); } - public QueryKeys( List keys ) - { + public QueryKeys(List keys) { this.keys = keys; - Map keyIndex = new HashMap<>( keys.size() ); + Map keyIndex = new HashMap<>(keys.size()); int i = 0; - for ( String key : keys ) - { - keyIndex.put( key, i++ ); + for (String key : keys) { + keyIndex.put(key, i++); } this.keyIndex = keyIndex; } - public QueryKeys( List keys, Map keyIndex ) - { + public QueryKeys(List keys, Map keyIndex) { this.keys = keys; this.keyIndex = keyIndex; } - public void add( String key ) - { + public void add(String key) { int index = keys.size(); - keys.add( key ); - keyIndex.put( key, index ); + keys.add(key); + keyIndex.put(key, index); } - public List keys() - { + public List keys() { return keys; } - public Map keyIndex() - { + public Map keyIndex() { return keyIndex; } - public static QueryKeys empty() - { + public static QueryKeys empty() { return EMPTY; } - public int indexOf( String key ) - { - return keyIndex.getOrDefault( key, -1 ); + public int indexOf(String key) { + return keyIndex.getOrDefault(key, -1); } - public boolean contains( String key ) - { - return keyIndex.containsKey( key ); + public boolean contains(String key) { + return keyIndex.containsKey(key); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } QueryKeys queryKeys = (QueryKeys) o; - return keys.equals( queryKeys.keys ) && keyIndex.equals( queryKeys.keyIndex ); + return keys.equals(queryKeys.keys) && keyIndex.equals(queryKeys.keyIndex); } @Override - public int hashCode() - { - return Objects.hash( keys, keyIndex ); + public int hashCode() { + return Objects.hash(keys, keyIndex); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/ServerVersion.java b/driver/src/main/java/org/neo4j/driver/internal/util/ServerVersion.java index 5232d4e76f..9949b24b5d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/ServerVersion.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/ServerVersion.java @@ -18,10 +18,11 @@ */ package org.neo4j.driver.internal.util; +import static java.lang.Integer.compare; + import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.neo4j.driver.Driver; import org.neo4j.driver.Session; import org.neo4j.driver.internal.messaging.BoltProtocolVersion; @@ -31,24 +32,22 @@ import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43; import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44; -import static java.lang.Integer.compare; - -public class ServerVersion -{ +public class ServerVersion { public static final String NEO4J_PRODUCT = "Neo4j"; - public static final ServerVersion v4_4_0 = new ServerVersion( NEO4J_PRODUCT, 4, 4, 0 ); - public static final ServerVersion v4_3_0 = new ServerVersion( NEO4J_PRODUCT, 4, 3, 0 ); - public static final ServerVersion v4_2_0 = new ServerVersion( NEO4J_PRODUCT, 4, 2, 0 ); - public static final ServerVersion v4_1_0 = new ServerVersion( NEO4J_PRODUCT, 4, 1, 0 ); - public static final ServerVersion v4_0_0 = new ServerVersion( NEO4J_PRODUCT, 4, 0, 0 ); - public static final ServerVersion v3_5_0 = new ServerVersion( NEO4J_PRODUCT, 3, 5, 0 ); - public static final ServerVersion v3_4_0 = new ServerVersion( NEO4J_PRODUCT, 3, 4, 0 ); - public static final ServerVersion vInDev = new ServerVersion( NEO4J_PRODUCT, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE ); + public static final ServerVersion v4_4_0 = new ServerVersion(NEO4J_PRODUCT, 4, 4, 0); + public static final ServerVersion v4_3_0 = new ServerVersion(NEO4J_PRODUCT, 4, 3, 0); + public static final ServerVersion v4_2_0 = new ServerVersion(NEO4J_PRODUCT, 4, 2, 0); + public static final ServerVersion v4_1_0 = new ServerVersion(NEO4J_PRODUCT, 4, 1, 0); + public static final ServerVersion v4_0_0 = new ServerVersion(NEO4J_PRODUCT, 4, 0, 0); + public static final ServerVersion v3_5_0 = new ServerVersion(NEO4J_PRODUCT, 3, 5, 0); + public static final ServerVersion v3_4_0 = new ServerVersion(NEO4J_PRODUCT, 3, 4, 0); + public static final ServerVersion vInDev = + new ServerVersion(NEO4J_PRODUCT, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); private static final String NEO4J_IN_DEV_VERSION_STRING = NEO4J_PRODUCT + "/dev"; private static final Pattern PATTERN = - Pattern.compile( "([^/]+)/(\\d+)\\.(\\d+)(?:\\.)?(\\d*)(\\.|-|\\+)?([0-9A-Za-z-.]*)?" ); + Pattern.compile("([^/]+)/(\\d+)\\.(\\d+)(?:\\.)?(\\d*)(\\.|-|\\+)?([0-9A-Za-z-.]*)?"); private final String product; private final int major; @@ -56,113 +55,99 @@ public class ServerVersion private final int patch; private final String stringValue; - private ServerVersion( String product, int major, int minor, int patch ) - { + private ServerVersion(String product, int major, int minor, int patch) { this.product = product; this.major = major; this.minor = minor; this.patch = patch; - this.stringValue = stringValue( product, major, minor, patch ); + this.stringValue = stringValue(product, major, minor, patch); } - public String product() - { + public String product() { return product; } - public static ServerVersion version( Driver driver ) - { - try ( Session session = driver.session() ) - { - String versionString = session.readTransaction( tx -> tx.run( "RETURN 1" ).consume().server().version() ); - return version( versionString ); + public static ServerVersion version(Driver driver) { + try (Session session = driver.session()) { + String versionString = session.readTransaction( + tx -> tx.run("RETURN 1").consume().server().version()); + return version(versionString); } } - public static ServerVersion version( String server ) - { - Matcher matcher = PATTERN.matcher( server ); - if ( matcher.matches() ) - { - String product = matcher.group( 1 ); - int major = Integer.valueOf( matcher.group( 2 ) ); - int minor = Integer.valueOf( matcher.group( 3 ) ); - String patchString = matcher.group( 4 ); + public static ServerVersion version(String server) { + Matcher matcher = PATTERN.matcher(server); + if (matcher.matches()) { + String product = matcher.group(1); + int major = Integer.valueOf(matcher.group(2)); + int minor = Integer.valueOf(matcher.group(3)); + String patchString = matcher.group(4); int patch = 0; - if ( patchString != null && !patchString.isEmpty() ) - { - patch = Integer.valueOf( patchString ); + if (patchString != null && !patchString.isEmpty()) { + patch = Integer.valueOf(patchString); } - return new ServerVersion( product, major, minor, patch ); - } - else if ( server.equalsIgnoreCase( NEO4J_IN_DEV_VERSION_STRING ) ) - { + return new ServerVersion(product, major, minor, patch); + } else if (server.equalsIgnoreCase(NEO4J_IN_DEV_VERSION_STRING)) { return vInDev; - } - else - { - throw new IllegalArgumentException( "Cannot parse " + server ); + } else { + throw new IllegalArgumentException("Cannot parse " + server); } } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { return true; } - if ( o == null || getClass() != o.getClass() ) - { return false; } + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } ServerVersion that = (ServerVersion) o; - if ( !product.equals( that.product ) ) - { return false; } - if ( major != that.major ) - { return false; } - if ( minor != that.minor ) - { return false; } + if (!product.equals(that.product)) { + return false; + } + if (major != that.major) { + return false; + } + if (minor != that.minor) { + return false; + } return patch == that.patch; } @Override - public int hashCode() - { + public int hashCode() { return Objects.hash(product, major, minor, patch); } - public boolean greaterThan(ServerVersion other) - { - return compareTo( other ) > 0; + public boolean greaterThan(ServerVersion other) { + return compareTo(other) > 0; } - public boolean greaterThanOrEqual(ServerVersion other) - { - return compareTo( other ) >= 0; + public boolean greaterThanOrEqual(ServerVersion other) { + return compareTo(other) >= 0; } - public boolean lessThan(ServerVersion other) - { - return compareTo( other ) < 0; + public boolean lessThan(ServerVersion other) { + return compareTo(other) < 0; } - public boolean lessThanOrEqual(ServerVersion other) - { - return compareTo( other ) <= 0; + public boolean lessThanOrEqual(ServerVersion other) { + return compareTo(other) <= 0; } - private int compareTo( ServerVersion o ) - { - if ( !product.equals( o.product ) ) - { - throw new IllegalArgumentException( "Comparing different products '" + product + "' with '" + o.product + "'" ); + private int compareTo(ServerVersion o) { + if (!product.equals(o.product)) { + throw new IllegalArgumentException( + "Comparing different products '" + product + "' with '" + o.product + "'"); } - int c = compare( major, o.major ); - if (c == 0) - { - c = compare( minor, o.minor ); - if (c == 0) - { - c = compare( patch, o.patch ); + int c = compare(major, o.major); + if (c == 0) { + c = compare(minor, o.minor); + if (c == 0) { + c = compare(patch, o.patch); } } @@ -170,40 +155,28 @@ private int compareTo( ServerVersion o ) } @Override - public String toString() - { + public String toString() { return stringValue; } - private static String stringValue( String product, int major, int minor, int patch ) - { - if ( major == Integer.MAX_VALUE && minor == Integer.MAX_VALUE && patch == Integer.MAX_VALUE ) - { + private static String stringValue(String product, int major, int minor, int patch) { + if (major == Integer.MAX_VALUE && minor == Integer.MAX_VALUE && patch == Integer.MAX_VALUE) { return NEO4J_IN_DEV_VERSION_STRING; } - return String.format( "%s/%s.%s.%s", product, major, minor, patch ); + return String.format("%s/%s.%s.%s", product, major, minor, patch); } - public static ServerVersion fromBoltProtocolVersion( BoltProtocolVersion protocolVersion ) - { + public static ServerVersion fromBoltProtocolVersion(BoltProtocolVersion protocolVersion) { - if ( BoltProtocolV4.VERSION.equals( protocolVersion ) ) - { + if (BoltProtocolV4.VERSION.equals(protocolVersion)) { return ServerVersion.v4_0_0; - } - else if ( BoltProtocolV41.VERSION.equals( protocolVersion ) ) - { + } else if (BoltProtocolV41.VERSION.equals(protocolVersion)) { return ServerVersion.v4_1_0; - } else if ( BoltProtocolV42.VERSION.equals( protocolVersion ) ) - { + } else if (BoltProtocolV42.VERSION.equals(protocolVersion)) { return ServerVersion.v4_2_0; - } - else if ( BoltProtocolV43.VERSION.equals( protocolVersion ) ) - { + } else if (BoltProtocolV43.VERSION.equals(protocolVersion)) { return ServerVersion.v4_3_0; - } - else if ( BoltProtocolV44.VERSION.equals( protocolVersion ) ) - { + } else if (BoltProtocolV44.VERSION.equals(protocolVersion)) { return ServerVersion.v4_4_0; } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/BooleanValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/BooleanValue.java index 0eeb0481e8..6be935f437 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/BooleanValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/BooleanValue.java @@ -21,18 +21,15 @@ import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public abstract class BooleanValue extends ValueAdapter -{ - private BooleanValue() - { - //do nothing +public abstract class BooleanValue extends ValueAdapter { + private BooleanValue() { + // do nothing } public static BooleanValue TRUE = new TrueValue(); public static BooleanValue FALSE = new FalseValue(); - public static BooleanValue fromBoolean( boolean value ) - { + public static BooleanValue fromBoolean(boolean value) { return value ? TRUE : FALSE; } @@ -40,14 +37,12 @@ public static BooleanValue fromBoolean( boolean value ) public abstract Boolean asObject(); @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.BOOLEAN(); } @Override - public int hashCode() - { + public int hashCode() { Boolean value = asBoolean() ? Boolean.TRUE : Boolean.FALSE; return value.hashCode(); } @@ -55,79 +50,66 @@ public int hashCode() private static class TrueValue extends BooleanValue { @Override - public Boolean asObject() - { + public Boolean asObject() { return Boolean.TRUE; } @Override - public boolean asBoolean() - { + public boolean asBoolean() { return true; } @Override - public boolean isTrue() - { + public boolean isTrue() { return true; } @Override - public boolean isFalse() - { + public boolean isFalse() { return false; } @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals( Object obj ) - { + public boolean equals(Object obj) { return obj == TRUE; } @Override - public String toString() - { + public String toString() { return "TRUE"; } } - private static class FalseValue extends BooleanValue - { + private static class FalseValue extends BooleanValue { @Override - public Boolean asObject() - { + public Boolean asObject() { return Boolean.FALSE; } @Override - public boolean asBoolean() - { + public boolean asBoolean() { return false; } @Override - public boolean isTrue() - { + public boolean isTrue() { return false; } @Override - public boolean isFalse() - { + public boolean isFalse() { return true; } @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals( Object obj ) - { + public boolean equals(Object obj) { return obj == FALSE; } @Override - public String toString() - { + public String toString() { return "FALSE"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/BytesValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/BytesValue.java index 5649c626d2..03aeb34f8b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/BytesValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/BytesValue.java @@ -19,62 +19,50 @@ package org.neo4j.driver.internal.value; import java.util.Arrays; - import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class BytesValue extends ValueAdapter -{ +public class BytesValue extends ValueAdapter { private final byte[] val; - public BytesValue( byte[] val ) - { - if ( val == null ) - { - throw new IllegalArgumentException( "Cannot construct BytesValue from null" ); + public BytesValue(byte[] val) { + if (val == null) { + throw new IllegalArgumentException("Cannot construct BytesValue from null"); } this.val = val; } @Override - public boolean isEmpty() - { + public boolean isEmpty() { return val.length == 0; } @Override - public int size() - { + public int size() { return val.length; } @Override - public byte[] asObject() - { + public byte[] asObject() { return val; } @Override - public byte[] asByteArray() - { + public byte[] asByteArray() { return val; } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.BYTES(); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } @@ -83,19 +71,15 @@ public boolean equals( Object o ) } @Override - public int hashCode() - { + public int hashCode() { return Arrays.hashCode(val); } @Override - public String toString() - { + public String toString() { StringBuilder s = new StringBuilder("#"); - for (byte b : val) - { - if (b < 0x10) - { + for (byte b : val) { + if (b < 0x10) { s.append('0'); } s.append(Integer.toHexString(b)); diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/DateTimeValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/DateTimeValue.java index 9c4e480f63..25bbca49e6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/DateTimeValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/DateTimeValue.java @@ -20,32 +20,26 @@ import java.time.OffsetDateTime; import java.time.ZonedDateTime; - import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class DateTimeValue extends ObjectValueAdapter -{ - public DateTimeValue( ZonedDateTime zonedDateTime ) - { - super( zonedDateTime ); +public class DateTimeValue extends ObjectValueAdapter { + public DateTimeValue(ZonedDateTime zonedDateTime) { + super(zonedDateTime); } @Override - public OffsetDateTime asOffsetDateTime() - { + public OffsetDateTime asOffsetDateTime() { return asZonedDateTime().toOffsetDateTime(); } @Override - public ZonedDateTime asZonedDateTime() - { + public ZonedDateTime asZonedDateTime() { return asObject(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.DATE_TIME(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/DateValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/DateValue.java index 5628440887..f69abd2be9 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/DateValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/DateValue.java @@ -19,26 +19,21 @@ package org.neo4j.driver.internal.value; import java.time.LocalDate; - import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class DateValue extends ObjectValueAdapter -{ - public DateValue( LocalDate date ) - { - super( date ); +public class DateValue extends ObjectValueAdapter { + public DateValue(LocalDate date) { + super(date); } @Override - public LocalDate asLocalDate() - { + public LocalDate asLocalDate() { return asObject(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.DATE(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/DurationValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/DurationValue.java index 79151965f9..e509c5d850 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/DurationValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/DurationValue.java @@ -22,22 +22,18 @@ import org.neo4j.driver.types.IsoDuration; import org.neo4j.driver.types.Type; -public class DurationValue extends ObjectValueAdapter -{ - public DurationValue( IsoDuration duration ) - { - super( duration ); +public class DurationValue extends ObjectValueAdapter { + public DurationValue(IsoDuration duration) { + super(duration); } @Override - public IsoDuration asIsoDuration() - { + public IsoDuration asIsoDuration() { return asObject(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.DURATION(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/EntityValueAdapter.java b/driver/src/main/java/org/neo4j/driver/internal/value/EntityValueAdapter.java index 2b37d9def3..e754b4e572 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/EntityValueAdapter.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/EntityValueAdapter.java @@ -19,51 +19,42 @@ package org.neo4j.driver.internal.value; import java.util.Map; - +import java.util.function.Function; import org.neo4j.driver.Value; import org.neo4j.driver.types.Entity; -import java.util.function.Function; -public abstract class EntityValueAdapter extends ObjectValueAdapter -{ - protected EntityValueAdapter( V adapted ) - { - super( adapted ); +public abstract class EntityValueAdapter extends ObjectValueAdapter { + protected EntityValueAdapter(V adapted) { + super(adapted); } @Override - public V asEntity() - { + public V asEntity() { return asObject(); } @Override - public Map asMap() - { + public Map asMap() { return asEntity().asMap(); } @Override - public Map asMap( Function mapFunction ) - { - return asEntity().asMap( mapFunction ); + public Map asMap(Function mapFunction) { + return asEntity().asMap(mapFunction); } @Override - public int size() - { + public int size() { return asEntity().size(); } @Override - public Iterable keys() - { + public Iterable keys() { return asEntity().keys(); } @Override - public Value get( String key ) - { - return asEntity().get( key ); + public Value get(String key) { + return asEntity().get(key); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/FloatValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/FloatValue.java index 9ff3e45d22..7580ce0362 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/FloatValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/FloatValue.java @@ -18,99 +18,83 @@ */ package org.neo4j.driver.internal.value; -import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.exceptions.value.LossyCoercion; +import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class FloatValue extends NumberValueAdapter -{ +public class FloatValue extends NumberValueAdapter { private final double val; - public FloatValue( double val ) - { + public FloatValue(double val) { this.val = val; } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.FLOAT(); } @Override - public Double asNumber() - { + public Double asNumber() { return val; } @Override - public long asLong() - { + public long asLong() { long longVal = (long) val; - if ((double) longVal != val) - { - throw new LossyCoercion( type().name(), "Java long" ); + if ((double) longVal != val) { + throw new LossyCoercion(type().name(), "Java long"); } return longVal; } @Override - public int asInt() - { + public int asInt() { int intVal = (int) val; - if ((double) intVal != val) - { - throw new LossyCoercion( type().name(), "Java int" ); + if ((double) intVal != val) { + throw new LossyCoercion(type().name(), "Java int"); } return intVal; } @Override - public double asDouble() - { + public double asDouble() { return val; } @Override - public float asFloat() - { + public float asFloat() { float floatVal = (float) val; - if ((double) floatVal != val) - { - throw new LossyCoercion( type().name(), "Java float" ); + if ((double) floatVal != val) { + throw new LossyCoercion(type().name(), "Java float"); } return floatVal; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } FloatValue values = (FloatValue) o; - return Double.compare( values.val, val ) == 0; + return Double.compare(values.val, val) == 0; } @Override - public int hashCode() - { - long temp = Double.doubleToLongBits( val ); + public int hashCode() { + long temp = Double.doubleToLongBits(val); return (int) (temp ^ (temp >>> 32)); } @Override - public String toString() - { - return Double.toString( val ); + public String toString() { + return Double.toString(val); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/IntegerValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/IntegerValue.java index bb7415d9e5..ebdbf06d2e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/IntegerValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/IntegerValue.java @@ -18,80 +18,66 @@ */ package org.neo4j.driver.internal.value; -import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.exceptions.value.LossyCoercion; +import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class IntegerValue extends NumberValueAdapter -{ +public class IntegerValue extends NumberValueAdapter { private final long val; - public IntegerValue( long val ) - { + public IntegerValue(long val) { this.val = val; } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.INTEGER(); } @Override - public Long asNumber() - { + public Long asNumber() { return val; } @Override - public long asLong() - { + public long asLong() { return val; } @Override - public int asInt() - { - if (val > Integer.MAX_VALUE || val < Integer.MIN_VALUE) - { - throw new LossyCoercion( type().name(), "Java int" ); + public int asInt() { + if (val > Integer.MAX_VALUE || val < Integer.MIN_VALUE) { + throw new LossyCoercion(type().name(), "Java int"); } return (int) val; } @Override - public double asDouble() - { + public double asDouble() { double doubleVal = (double) val; - if ( (long) doubleVal != val) - { - throw new LossyCoercion( type().name(), "Java double" ); + if ((long) doubleVal != val) { + throw new LossyCoercion(type().name(), "Java double"); } return (double) val; } @Override - public float asFloat() - { + public float asFloat() { return (float) val; } @Override - public String toString() - { - return Long.toString( val ); + public String toString() { + return Long.toString(val); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } @@ -100,8 +86,7 @@ public boolean equals( Object o ) } @Override - public int hashCode() - { + public int hashCode() { return (int) (val ^ (val >>> 32)); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/InternalValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/InternalValue.java index 93176f240c..cc0f45c131 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/InternalValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/InternalValue.java @@ -18,11 +18,10 @@ */ package org.neo4j.driver.internal.value; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.AsValue; import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.Value; -public interface InternalValue extends Value, AsValue -{ +public interface InternalValue extends Value, AsValue { TypeConstructor typeConstructor(); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/ListValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/ListValue.java index b8ad0411c8..f72bb89503 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/ListValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/ListValue.java @@ -18,132 +18,108 @@ */ package org.neo4j.driver.internal.value; +import static org.neo4j.driver.Values.ofObject; + import java.util.Arrays; import java.util.Iterator; import java.util.List; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.internal.util.Extract; +import java.util.function.Function; import org.neo4j.driver.Value; import org.neo4j.driver.Values; +import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.neo4j.driver.internal.util.Extract; import org.neo4j.driver.types.Type; -import java.util.function.Function; -import static org.neo4j.driver.Values.ofObject; - -public class ListValue extends ValueAdapter -{ +public class ListValue extends ValueAdapter { private final Value[] values; - public ListValue( Value... values ) - { - if ( values == null ) - { - throw new IllegalArgumentException( "Cannot construct ListValue from null" ); + public ListValue(Value... values) { + if (values == null) { + throw new IllegalArgumentException("Cannot construct ListValue from null"); } this.values = values; } @Override - public boolean isEmpty() - { + public boolean isEmpty() { return values.length == 0; } @Override - public List asObject() - { - return asList( ofObject() ); + public List asObject() { + return asList(ofObject()); } @Override - public List asList() - { - return Extract.list( values, ofObject() ); + public List asList() { + return Extract.list(values, ofObject()); } @Override - public List asList( Function mapFunction ) - { - return Extract.list( values, mapFunction ); + public List asList(Function mapFunction) { + return Extract.list(values, mapFunction); } @Override - public int size() - { + public int size() { return values.length; } @Override - public Value get( int index ) - { + public Value get(int index) { return index >= 0 && index < values.length ? values[index] : Values.NULL; } @Override - public Iterable values( final Function mapFunction ) - { - return new Iterable() - { + public Iterable values(final Function mapFunction) { + return new Iterable() { @Override - public Iterator iterator() - { - return new Iterator() - { + public Iterator iterator() { + return new Iterator() { private int cursor = 0; @Override - public boolean hasNext() - { + public boolean hasNext() { return cursor < values.length; } @Override - public T next() - { - return mapFunction.apply( values[cursor++] ); + public T next() { + return mapFunction.apply(values[cursor++]); } @Override - public void remove() - { - } + public void remove() {} }; } }; } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.LIST(); } @Override - public String toString() - { - return Arrays.toString( values ); + public String toString() { + return Arrays.toString(values); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } ListValue otherValues = (ListValue) o; - return Arrays.equals( values, otherValues.values ); + return Arrays.equals(values, otherValues.values); } @Override - public int hashCode() - { - return Arrays.hashCode( values ); + public int hashCode() { + return Arrays.hashCode(values); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/LocalDateTimeValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/LocalDateTimeValue.java index 13d0b6e1c8..04fe2e9df2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/LocalDateTimeValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/LocalDateTimeValue.java @@ -19,26 +19,21 @@ package org.neo4j.driver.internal.value; import java.time.LocalDateTime; - import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class LocalDateTimeValue extends ObjectValueAdapter -{ - public LocalDateTimeValue( LocalDateTime localDateTime ) - { - super( localDateTime ); +public class LocalDateTimeValue extends ObjectValueAdapter { + public LocalDateTimeValue(LocalDateTime localDateTime) { + super(localDateTime); } @Override - public LocalDateTime asLocalDateTime() - { + public LocalDateTime asLocalDateTime() { return asObject(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.LOCAL_DATE_TIME(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/LocalTimeValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/LocalTimeValue.java index a1db0357cc..dfb5bddbab 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/LocalTimeValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/LocalTimeValue.java @@ -19,26 +19,21 @@ package org.neo4j.driver.internal.value; import java.time.LocalTime; - import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class LocalTimeValue extends ObjectValueAdapter -{ - public LocalTimeValue( LocalTime time ) - { - super( time ); +public class LocalTimeValue extends ObjectValueAdapter { + public LocalTimeValue(LocalTime time) { + super(time); } @Override - public LocalTime asLocalTime() - { + public LocalTime asLocalTime() { return asObject(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.LOCAL_TIME(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/MapValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/MapValue.java index 5bfe276a6a..15f4120ed6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/MapValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/MapValue.java @@ -18,124 +18,104 @@ */ package org.neo4j.driver.internal.value; -import java.util.Map; +import static org.neo4j.driver.Values.ofObject; +import static org.neo4j.driver.Values.ofValue; +import static org.neo4j.driver.internal.util.Format.formatPairs; -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.internal.util.Extract; +import java.util.Map; +import java.util.function.Function; import org.neo4j.driver.Value; import org.neo4j.driver.Values; +import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.neo4j.driver.internal.util.Extract; import org.neo4j.driver.types.Type; -import java.util.function.Function; - -import static org.neo4j.driver.internal.util.Format.formatPairs; -import static org.neo4j.driver.Values.ofObject; -import static org.neo4j.driver.Values.ofValue; -public class MapValue extends ValueAdapter -{ +public class MapValue extends ValueAdapter { private final Map val; - public MapValue( Map val ) - { - if ( val == null ) - { - throw new IllegalArgumentException( "Cannot construct MapValue from null" ); + public MapValue(Map val) { + if (val == null) { + throw new IllegalArgumentException("Cannot construct MapValue from null"); } this.val = val; } @Override - public boolean isEmpty() - { + public boolean isEmpty() { return val.isEmpty(); } @Override - public Map asObject() - { - return asMap( ofObject() ); + public Map asObject() { + return asMap(ofObject()); } @Override - public Map asMap() - { - return Extract.map( val, ofObject() ); + public Map asMap() { + return Extract.map(val, ofObject()); } @Override - public Map asMap( Function mapFunction ) - { - return Extract.map( val, mapFunction ); + public Map asMap(Function mapFunction) { + return Extract.map(val, mapFunction); } @Override - public int size() - { + public int size() { return val.size(); } @Override - public boolean containsKey( String key ) - { - return val.containsKey( key ); + public boolean containsKey(String key) { + return val.containsKey(key); } @Override - public Iterable keys() - { + public Iterable keys() { return val.keySet(); } @Override - public Iterable values() - { + public Iterable values() { return val.values(); } @Override - public Iterable values( Function mapFunction ) - { - return Extract.map( val, mapFunction ).values(); + public Iterable values(Function mapFunction) { + return Extract.map(val, mapFunction).values(); } @Override - public Value get( String key ) - { - Value value = val.get( key ); - return value == null ? Values.NULL: value; + public Value get(String key) { + Value value = val.get(key); + return value == null ? Values.NULL : value; } @Override - public String toString() - { - return formatPairs( asMap( ofValue() ) ); + public String toString() { + return formatPairs(asMap(ofValue())); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.MAP(); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } MapValue values = (MapValue) o; - return val.equals( values.val ); + return val.equals(values.val); } @Override - public int hashCode() - { + public int hashCode() { return val.hashCode(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/NodeValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/NodeValue.java index 89708d251e..f7c78659a4 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/NodeValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/NodeValue.java @@ -22,22 +22,18 @@ import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Type; -public class NodeValue extends EntityValueAdapter -{ - public NodeValue( Node adapted ) - { - super( adapted ); +public class NodeValue extends EntityValueAdapter { + public NodeValue(Node adapted) { + super(adapted); } @Override - public Node asNode() - { + public Node asNode() { return asEntity(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.NODE(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/NullValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/NullValue.java index 10ddb70d7e..ca3bcb7df3 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/NullValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/NullValue.java @@ -18,58 +18,48 @@ */ package org.neo4j.driver.internal.value; -import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.Value; +import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public final class NullValue extends ValueAdapter -{ +public final class NullValue extends ValueAdapter { public static final Value NULL = new NullValue(); - private NullValue() - { - } + private NullValue() {} @Override - public boolean isNull() - { + public boolean isNull() { return true; } @Override - public Object asObject() - { + public Object asObject() { return null; } @Override - public String asString() - { + public String asString() { return "null"; } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.NULL(); } @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") @Override - public boolean equals( Object obj ) - { + public boolean equals(Object obj) { return obj == NULL; } @Override - public int hashCode() - { + public int hashCode() { return 0; } @Override - public String toString() - { + public String toString() { return "NULL"; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/NumberValueAdapter.java b/driver/src/main/java/org/neo4j/driver/internal/value/NumberValueAdapter.java index e75e99bc27..dc8be2e6fd 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/NumberValueAdapter.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/NumberValueAdapter.java @@ -18,11 +18,9 @@ */ package org.neo4j.driver.internal.value; -public abstract class NumberValueAdapter extends ValueAdapter -{ +public abstract class NumberValueAdapter extends ValueAdapter { @Override - public final V asObject() - { + public final V asObject() { return asNumber(); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/ObjectValueAdapter.java b/driver/src/main/java/org/neo4j/driver/internal/value/ObjectValueAdapter.java index 2a45089d63..6738bda803 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/ObjectValueAdapter.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/ObjectValueAdapter.java @@ -18,53 +18,45 @@ */ package org.neo4j.driver.internal.value; -import java.util.Objects; - import static java.lang.String.format; -public abstract class ObjectValueAdapter extends ValueAdapter -{ +import java.util.Objects; + +public abstract class ObjectValueAdapter extends ValueAdapter { private final V adapted; - protected ObjectValueAdapter( V adapted ) - { - if ( adapted == null ) - { - throw new IllegalArgumentException( format( "Cannot construct %s from null", getClass().getSimpleName() ) ); + protected ObjectValueAdapter(V adapted) { + if (adapted == null) { + throw new IllegalArgumentException( + format("Cannot construct %s from null", getClass().getSimpleName())); } this.adapted = adapted; } @Override - public final V asObject() - { + public final V asObject() { return adapted; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } ObjectValueAdapter that = (ObjectValueAdapter) o; - return Objects.equals( adapted, that.adapted ); + return Objects.equals(adapted, that.adapted); } @Override - public int hashCode() - { + public int hashCode() { return adapted.hashCode(); } @Override - public String toString() - { + public String toString() { return adapted.toString(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/PathValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/PathValue.java index 9fff923de0..28af57b0ce 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/PathValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/PathValue.java @@ -22,29 +22,23 @@ import org.neo4j.driver.types.Path; import org.neo4j.driver.types.Type; -public class PathValue extends ObjectValueAdapter -{ - public PathValue( Path adapted ) - { - super( adapted ); +public class PathValue extends ObjectValueAdapter { + public PathValue(Path adapted) { + super(adapted); } @Override - public Path asPath() - { + public Path asPath() { return asObject(); } @Override - public int size() - { + public int size() { return asObject().length(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.PATH(); } - } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/PointValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/PointValue.java index b14606f09b..ce90d7d2ac 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/PointValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/PointValue.java @@ -22,22 +22,18 @@ import org.neo4j.driver.types.Point; import org.neo4j.driver.types.Type; -public class PointValue extends ObjectValueAdapter -{ - public PointValue( Point point ) - { - super( point ); +public class PointValue extends ObjectValueAdapter { + public PointValue(Point point) { + super(point); } @Override - public Point asPoint() - { + public Point asPoint() { return asObject(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.POINT(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/RelationshipValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/RelationshipValue.java index 607bd71dac..9fcf6e84b7 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/RelationshipValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/RelationshipValue.java @@ -22,22 +22,18 @@ import org.neo4j.driver.types.Relationship; import org.neo4j.driver.types.Type; -public class RelationshipValue extends EntityValueAdapter -{ - public RelationshipValue( Relationship adapted ) - { - super( adapted ); +public class RelationshipValue extends EntityValueAdapter { + public RelationshipValue(Relationship adapted) { + super(adapted); } @Override - public Relationship asRelationship() - { + public Relationship asRelationship() { return asEntity(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.RELATIONSHIP(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/StringValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/StringValue.java index 380f89c20c..1fcc324a7d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/StringValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/StringValue.java @@ -19,77 +19,63 @@ package org.neo4j.driver.internal.value; import java.util.Objects; - import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class StringValue extends ValueAdapter -{ +public class StringValue extends ValueAdapter { private final String val; - public StringValue( String val ) - { - if ( val == null ) - { - throw new IllegalArgumentException( "Cannot construct StringValue from null" ); + public StringValue(String val) { + if (val == null) { + throw new IllegalArgumentException("Cannot construct StringValue from null"); } this.val = val; } @Override - public boolean isEmpty() - { + public boolean isEmpty() { return val.isEmpty(); } @Override - public int size() - { + public int size() { return val.length(); } @Override - public String asObject() - { + public String asObject() { return asString(); } @Override - public String asString() - { + public String asString() { return val; } @Override - public String toString() - { - return String.format( "\"%s\"", val.replace( "\"", "\\\"" ) ); + public String toString() { + return String.format("\"%s\"", val.replace("\"", "\\\"")); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.STRING(); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } StringValue that = (StringValue) o; - return Objects.equals( val, that.val ); + return Objects.equals(val, that.val); } @Override - public int hashCode() - { + public int hashCode() { return val.hashCode(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/TimeValue.java b/driver/src/main/java/org/neo4j/driver/internal/value/TimeValue.java index 2ce71f601c..5dba60bb22 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/TimeValue.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/TimeValue.java @@ -19,26 +19,21 @@ package org.neo4j.driver.internal.value; import java.time.OffsetTime; - import org.neo4j.driver.internal.types.InternalTypeSystem; import org.neo4j.driver.types.Type; -public class TimeValue extends ObjectValueAdapter -{ - public TimeValue( OffsetTime time ) - { - super( time ); +public class TimeValue extends ObjectValueAdapter { + public TimeValue(OffsetTime time) { + super(time); } @Override - public OffsetTime asOffsetTime() - { + public OffsetTime asOffsetTime() { return asObject(); } @Override - public Type type() - { + public Type type() { return InternalTypeSystem.TYPE_SYSTEM.TIME(); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/value/ValueAdapter.java b/driver/src/main/java/org/neo4j/driver/internal/value/ValueAdapter.java index 427caddb70..9d7040e25d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/value/ValueAdapter.java +++ b/driver/src/main/java/org/neo4j/driver/internal/value/ValueAdapter.java @@ -18,6 +18,10 @@ */ package org.neo4j.driver.internal.value; +import static java.util.Collections.emptyList; +import static org.neo4j.driver.Values.ofObject; +import static org.neo4j.driver.Values.ofValue; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -26,14 +30,14 @@ import java.time.ZonedDateTime; import java.util.List; import java.util.Map; - -import org.neo4j.driver.internal.types.InternalMapAccessorWithDefaultValue; -import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.internal.types.TypeRepresentation; +import java.util.function.Function; import org.neo4j.driver.Value; import org.neo4j.driver.exceptions.value.NotMultiValued; import org.neo4j.driver.exceptions.value.Uncoercible; import org.neo4j.driver.exceptions.value.Unsizable; +import org.neo4j.driver.internal.types.InternalMapAccessorWithDefaultValue; +import org.neo4j.driver.internal.types.TypeConstructor; +import org.neo4j.driver.internal.types.TypeRepresentation; import org.neo4j.driver.types.Entity; import org.neo4j.driver.types.IsoDuration; import org.neo4j.driver.types.Node; @@ -41,375 +45,309 @@ import org.neo4j.driver.types.Point; import org.neo4j.driver.types.Relationship; import org.neo4j.driver.types.Type; -import java.util.function.Function; -import static java.util.Collections.emptyList; -import static org.neo4j.driver.Values.ofObject; -import static org.neo4j.driver.Values.ofValue; - -public abstract class ValueAdapter extends InternalMapAccessorWithDefaultValue implements InternalValue -{ +public abstract class ValueAdapter extends InternalMapAccessorWithDefaultValue implements InternalValue { @Override - public Value asValue() - { + public Value asValue() { return this; } @Override - public boolean hasType( Type type ) - { - return type.isTypeOf( this ); + public boolean hasType(Type type) { + return type.isTypeOf(this); } @Override - public boolean isTrue() - { + public boolean isTrue() { return false; } @Override - public boolean isFalse() - { + public boolean isFalse() { return false; } @Override - public boolean isNull() - { + public boolean isNull() { return false; } @Override - public boolean containsKey( String key ) - { - throw new NotMultiValued( type().name() + " is not a keyed collection" ); + public boolean containsKey(String key) { + throw new NotMultiValued(type().name() + " is not a keyed collection"); } @Override - public String asString() - { - throw new Uncoercible( type().name(), "Java String" ); + public String asString() { + throw new Uncoercible(type().name(), "Java String"); } @Override - public boolean asBoolean( boolean defaultValue ) - { - return computeOrDefault( Value:: asBoolean, defaultValue ); + public boolean asBoolean(boolean defaultValue) { + return computeOrDefault(Value::asBoolean, defaultValue); } @Override - public String asString( String defaultValue ) - { - return computeOrDefault( (Value::asString), defaultValue ); + public String asString(String defaultValue) { + return computeOrDefault((Value::asString), defaultValue); } @Override - public long asLong( long defaultValue ) - { - return computeOrDefault( Value::asLong, defaultValue ); + public long asLong(long defaultValue) { + return computeOrDefault(Value::asLong, defaultValue); } @Override - public int asInt( int defaultValue ) - { - return computeOrDefault( Value::asInt, defaultValue ); + public int asInt(int defaultValue) { + return computeOrDefault(Value::asInt, defaultValue); } @Override - public double asDouble( double defaultValue ) - { - return computeOrDefault( Value::asDouble, defaultValue ); + public double asDouble(double defaultValue) { + return computeOrDefault(Value::asDouble, defaultValue); } @Override - public float asFloat( float defaultValue ) - { - return computeOrDefault( Value::asFloat, defaultValue ); + public float asFloat(float defaultValue) { + return computeOrDefault(Value::asFloat, defaultValue); } @Override - public long asLong() - { - throw new Uncoercible( type().name(), "Java long" ); + public long asLong() { + throw new Uncoercible(type().name(), "Java long"); } @Override - public int asInt() - { - throw new Uncoercible( type().name(), "Java int" ); + public int asInt() { + throw new Uncoercible(type().name(), "Java int"); } @Override - public float asFloat() - { - throw new Uncoercible( type().name(), "Java float" ); + public float asFloat() { + throw new Uncoercible(type().name(), "Java float"); } @Override - public double asDouble() - { - throw new Uncoercible( type().name(), "Java double" ); + public double asDouble() { + throw new Uncoercible(type().name(), "Java double"); } @Override - public boolean asBoolean() - { - throw new Uncoercible( type().name(), "Java boolean" ); + public boolean asBoolean() { + throw new Uncoercible(type().name(), "Java boolean"); } @Override - public List asList() - { - return asList( ofObject() ); + public List asList() { + return asList(ofObject()); } @Override - public List asList( Function mapFunction ) - { - throw new Uncoercible( type().name(), "Java List" ); + public List asList(Function mapFunction) { + throw new Uncoercible(type().name(), "Java List"); } @Override - public Map asMap() - { - return asMap( ofObject() ); + public Map asMap() { + return asMap(ofObject()); } @Override - public Map asMap( Function mapFunction ) - { - throw new Uncoercible( type().name(), "Java Map" ); + public Map asMap(Function mapFunction) { + throw new Uncoercible(type().name(), "Java Map"); } @Override - public Object asObject() - { - throw new Uncoercible( type().name(), "Java Object" ); + public Object asObject() { + throw new Uncoercible(type().name(), "Java Object"); } @Override - public T computeOrDefault( Function mapper, T defaultValue ) - { - if ( isNull() ) - { + public T computeOrDefault(Function mapper, T defaultValue) { + if (isNull()) { return defaultValue; } - return mapper.apply( this ); + return mapper.apply(this); } @Override - public Map asMap( Map defaultValue ) - { - return computeOrDefault( Value::asMap, defaultValue ); + public Map asMap(Map defaultValue) { + return computeOrDefault(Value::asMap, defaultValue); } @Override - public Map asMap( Function mapFunction, Map defaultValue ) - { - return computeOrDefault( value -> value.asMap( mapFunction ), defaultValue ); + public Map asMap(Function mapFunction, Map defaultValue) { + return computeOrDefault(value -> value.asMap(mapFunction), defaultValue); } @Override - public byte[] asByteArray( byte[] defaultValue ) - { - return computeOrDefault( Value::asByteArray, defaultValue ); + public byte[] asByteArray(byte[] defaultValue) { + return computeOrDefault(Value::asByteArray, defaultValue); } @Override - public List asList( List defaultValue ) - { - return computeOrDefault( Value::asList, defaultValue ); + public List asList(List defaultValue) { + return computeOrDefault(Value::asList, defaultValue); } @Override - public List asList( Function mapFunction, List defaultValue ) - { - return computeOrDefault( value -> value.asList( mapFunction ), defaultValue ); + public List asList(Function mapFunction, List defaultValue) { + return computeOrDefault(value -> value.asList(mapFunction), defaultValue); } @Override - public LocalDate asLocalDate( LocalDate defaultValue ) - { - return computeOrDefault( Value::asLocalDate, defaultValue ); + public LocalDate asLocalDate(LocalDate defaultValue) { + return computeOrDefault(Value::asLocalDate, defaultValue); } @Override - public OffsetTime asOffsetTime( OffsetTime defaultValue ) - { - return computeOrDefault( Value::asOffsetTime, defaultValue ); + public OffsetTime asOffsetTime(OffsetTime defaultValue) { + return computeOrDefault(Value::asOffsetTime, defaultValue); } @Override - public LocalTime asLocalTime( LocalTime defaultValue ) - { - return computeOrDefault( Value::asLocalTime, defaultValue ); + public LocalTime asLocalTime(LocalTime defaultValue) { + return computeOrDefault(Value::asLocalTime, defaultValue); } @Override - public LocalDateTime asLocalDateTime( LocalDateTime defaultValue ) - { - return computeOrDefault( Value::asLocalDateTime, defaultValue ); + public LocalDateTime asLocalDateTime(LocalDateTime defaultValue) { + return computeOrDefault(Value::asLocalDateTime, defaultValue); } @Override - public OffsetDateTime asOffsetDateTime( OffsetDateTime defaultValue ) - { - return computeOrDefault( Value::asOffsetDateTime, defaultValue ); + public OffsetDateTime asOffsetDateTime(OffsetDateTime defaultValue) { + return computeOrDefault(Value::asOffsetDateTime, defaultValue); } @Override - public ZonedDateTime asZonedDateTime( ZonedDateTime defaultValue ) - { - return computeOrDefault( Value::asZonedDateTime, defaultValue ); + public ZonedDateTime asZonedDateTime(ZonedDateTime defaultValue) { + return computeOrDefault(Value::asZonedDateTime, defaultValue); } @Override - public IsoDuration asIsoDuration( IsoDuration defaultValue ) - { - return computeOrDefault( Value::asIsoDuration, defaultValue ); + public IsoDuration asIsoDuration(IsoDuration defaultValue) { + return computeOrDefault(Value::asIsoDuration, defaultValue); } @Override - public Point asPoint( Point defaultValue ) - { - return computeOrDefault( Value::asPoint, defaultValue ); + public Point asPoint(Point defaultValue) { + return computeOrDefault(Value::asPoint, defaultValue); } @Override - public byte[] asByteArray() - { - throw new Uncoercible( type().name(), "Byte array" ); + public byte[] asByteArray() { + throw new Uncoercible(type().name(), "Byte array"); } @Override - public Number asNumber() - { - throw new Uncoercible( type().name(), "Java Number" ); + public Number asNumber() { + throw new Uncoercible(type().name(), "Java Number"); } @Override - public Entity asEntity() - { - throw new Uncoercible( type().name(), "Entity" ); + public Entity asEntity() { + throw new Uncoercible(type().name(), "Entity"); } @Override - public Node asNode() - { - throw new Uncoercible( type().name(), "Node" ); + public Node asNode() { + throw new Uncoercible(type().name(), "Node"); } @Override - public Path asPath() - { - throw new Uncoercible( type().name(), "Path" ); + public Path asPath() { + throw new Uncoercible(type().name(), "Path"); } @Override - public Relationship asRelationship() - { - throw new Uncoercible( type().name(), "Relationship" ); + public Relationship asRelationship() { + throw new Uncoercible(type().name(), "Relationship"); } @Override - public LocalDate asLocalDate() - { - throw new Uncoercible( type().name(), "LocalDate" ); + public LocalDate asLocalDate() { + throw new Uncoercible(type().name(), "LocalDate"); } @Override - public OffsetTime asOffsetTime() - { - throw new Uncoercible( type().name(), "OffsetTime" ); + public OffsetTime asOffsetTime() { + throw new Uncoercible(type().name(), "OffsetTime"); } @Override - public LocalTime asLocalTime() - { - throw new Uncoercible( type().name(), "LocalTime" ); + public LocalTime asLocalTime() { + throw new Uncoercible(type().name(), "LocalTime"); } @Override - public LocalDateTime asLocalDateTime() - { - throw new Uncoercible( type().name(), "LocalDateTime" ); + public LocalDateTime asLocalDateTime() { + throw new Uncoercible(type().name(), "LocalDateTime"); } @Override - public OffsetDateTime asOffsetDateTime() - { - throw new Uncoercible( type().name(), "OffsetDateTime" ); + public OffsetDateTime asOffsetDateTime() { + throw new Uncoercible(type().name(), "OffsetDateTime"); } @Override - public ZonedDateTime asZonedDateTime() - { - throw new Uncoercible( type().name(), "ZonedDateTime" ); + public ZonedDateTime asZonedDateTime() { + throw new Uncoercible(type().name(), "ZonedDateTime"); } @Override - public IsoDuration asIsoDuration() - { - throw new Uncoercible( type().name(), "Duration" ); + public IsoDuration asIsoDuration() { + throw new Uncoercible(type().name(), "Duration"); } @Override - public Point asPoint() - { - throw new Uncoercible( type().name(), "Point" ); + public Point asPoint() { + throw new Uncoercible(type().name(), "Point"); } @Override - public Value get( int index ) - { - throw new NotMultiValued( type().name() + " is not an indexed collection" ); + public Value get(int index) { + throw new NotMultiValued(type().name() + " is not an indexed collection"); } @Override - public Value get( String key ) - { - throw new NotMultiValued( type().name() + " is not a keyed collection" ); + public Value get(String key) { + throw new NotMultiValued(type().name() + " is not a keyed collection"); } @Override - public int size() - { - throw new Unsizable( type().name() + " does not have size" ); + public int size() { + throw new Unsizable(type().name() + " does not have size"); } @Override - public Iterable keys() - { + public Iterable keys() { return emptyList(); } @Override - public boolean isEmpty() - { - return ! values().iterator().hasNext(); + public boolean isEmpty() { + return !values().iterator().hasNext(); } @Override - public Iterable values() - { - return values( ofValue() ); + public Iterable values() { + return values(ofValue()); } @Override - public Iterable values( Function mapFunction ) - { - throw new NotMultiValued( type().name() + " is not iterable" ); + public Iterable values(Function mapFunction) { + throw new NotMultiValued(type().name() + " is not iterable"); } @Override - public final TypeConstructor typeConstructor() - { - return ( (TypeRepresentation) type() ).constructor(); + public final TypeConstructor typeConstructor() { + return ((TypeRepresentation) type()).constructor(); } // Force implementation @Override - public abstract boolean equals( Object obj ); + public abstract boolean equals(Object obj); // Force implementation @Override @@ -419,5 +357,3 @@ public final TypeConstructor typeConstructor() @Override public abstract String toString(); } - - diff --git a/driver/src/main/java/org/neo4j/driver/net/ServerAddress.java b/driver/src/main/java/org/neo4j/driver/net/ServerAddress.java index f462885281..935b5fbea1 100644 --- a/driver/src/main/java/org/neo4j/driver/net/ServerAddress.java +++ b/driver/src/main/java/org/neo4j/driver/net/ServerAddress.java @@ -24,8 +24,7 @@ * Represents a host and port. Host can either be an IP address or a DNS name. * Both IPv4 and IPv6 hosts are supported. */ -public interface ServerAddress -{ +public interface ServerAddress { /** * Retrieve the host portion of this {@link ServerAddress}. * @@ -47,8 +46,7 @@ public interface ServerAddress * @param port the port portion. Should be in range [0, 65535]. * @return new server address with the specified host and port. */ - static ServerAddress of( String host, int port ) - { - return new BoltServerAddress( host, port ); + static ServerAddress of(String host, int port) { + return new BoltServerAddress(host, port); } } diff --git a/driver/src/main/java/org/neo4j/driver/net/ServerAddressResolver.java b/driver/src/main/java/org/neo4j/driver/net/ServerAddressResolver.java index 0cf5827c95..949d79b818 100644 --- a/driver/src/main/java/org/neo4j/driver/net/ServerAddressResolver.java +++ b/driver/src/main/java/org/neo4j/driver/net/ServerAddressResolver.java @@ -25,8 +25,7 @@ * A resolver function used by the routing driver to resolve the initial address used to create the driver. */ @FunctionalInterface -public interface ServerAddressResolver -{ +public interface ServerAddressResolver { /** * Resolve the given address to a set of other addresses. * It is highly recommended to shuffle the addresses returned to prevent the driver from @@ -37,5 +36,5 @@ public interface ServerAddressResolver * @param address the address to resolve. * @return new set of addresses. */ - Set resolve( ServerAddress address ); + Set resolve(ServerAddress address); } diff --git a/driver/src/main/java/org/neo4j/driver/reactive/RxQueryRunner.java b/driver/src/main/java/org/neo4j/driver/reactive/RxQueryRunner.java index 1da225352d..603c8f80b1 100644 --- a/driver/src/main/java/org/neo4j/driver/reactive/RxQueryRunner.java +++ b/driver/src/main/java/org/neo4j/driver/reactive/RxQueryRunner.java @@ -19,7 +19,6 @@ package org.neo4j.driver.reactive; import java.util.Map; - import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -31,8 +30,7 @@ * @see RxTransaction * @since 4.0 */ -public interface RxQueryRunner -{ +public interface RxQueryRunner { /** * Register running of a query and return a reactive result stream. * The query is not executed when the reactive result is returned. @@ -54,7 +52,7 @@ public interface RxQueryRunner * @param parameters input parameters, should be a map Value, see {@link Values#parameters(Object...)}. * @return a reactive result. */ - RxResult run(String query, Value parameters ); + RxResult run(String query, Value parameters); /** * Register running of a query and return a reactive result stream. @@ -74,7 +72,7 @@ public interface RxQueryRunner * @param parameters input data for the query * @return a reactive result. */ - RxResult run(String query, Map parameters ); + RxResult run(String query, Map parameters); /** * Register running of a query and return a reactive result stream. @@ -93,7 +91,7 @@ public interface RxQueryRunner * @param parameters input data for the query * @return a reactive result. */ - RxResult run(String query, Record parameters ); + RxResult run(String query, Record parameters); /** * Register running of a query and return a reactive result stream. @@ -103,7 +101,7 @@ public interface RxQueryRunner * @param query text of a Neo4j query * @return a reactive result. */ - RxResult run(String query ); + RxResult run(String query); /** * Register running of a query and return a reactive result stream. diff --git a/driver/src/main/java/org/neo4j/driver/reactive/RxResult.java b/driver/src/main/java/org/neo4j/driver/reactive/RxResult.java index 1797c2bf3c..7aa89c21aa 100644 --- a/driver/src/main/java/org/neo4j/driver/reactive/RxResult.java +++ b/driver/src/main/java/org/neo4j/driver/reactive/RxResult.java @@ -18,16 +18,14 @@ */ package org.neo4j.driver.reactive; -import org.neo4j.driver.Query; -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscriber; -import org.reactivestreams.Subscription; - import java.util.List; - +import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.exceptions.ResultConsumedException; import org.neo4j.driver.summary.ResultSummary; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; /** * A reactive result provides a reactive way to execute query on the server and receives records back. @@ -41,8 +39,7 @@ * @see Subscription * @since 4.0 */ -public interface RxResult -{ +public interface RxResult { /** * Returns a cold publisher of keys. * This publisher always publishes one item - a list of keys. The list could be empty which indicates no keys in the result. diff --git a/driver/src/main/java/org/neo4j/driver/reactive/RxSession.java b/driver/src/main/java/org/neo4j/driver/reactive/RxSession.java index 08cb645555..74b14650b2 100644 --- a/driver/src/main/java/org/neo4j/driver/reactive/RxSession.java +++ b/driver/src/main/java/org/neo4j/driver/reactive/RxSession.java @@ -18,17 +18,15 @@ */ package org.neo4j.driver.reactive; -import org.neo4j.driver.Query; -import org.reactivestreams.Publisher; - import java.util.Map; import java.util.concurrent.CompletableFuture; - import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Bookmark; +import org.neo4j.driver.Query; import org.neo4j.driver.Session; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.Values; -import org.neo4j.driver.Bookmark; +import org.reactivestreams.Publisher; /** * A reactive session is the same as {@link Session} except it provides a reactive API. @@ -38,8 +36,7 @@ * @see Publisher * @since 4.0 */ -public interface RxSession extends RxQueryRunner -{ +public interface RxSession extends RxQueryRunner { /** * Begin a new unmanaged {@linkplain RxTransaction transaction}. At * most one transaction may exist in a session at any point in time. To @@ -62,11 +59,11 @@ public interface RxSession extends RxQueryRunner * @param config configuration for the new transaction. * @return a new {@link RxTransaction} */ - Publisher beginTransaction( TransactionConfig config ); + Publisher beginTransaction(TransactionConfig config); /** * Execute given unit of reactive work in a {@link AccessMode#READ read} reactive transaction. -

+ *

* Transaction will automatically be committed unless given unit of work fails or * {@link RxTransaction#commit() transaction commit} fails. * It will also not be committed if explicitly rolled back via {@link RxTransaction#rollback()}. @@ -83,12 +80,12 @@ public interface RxSession extends RxQueryRunner * publisher can be completed exceptionally if given work or commit fails. * */ - Publisher readTransaction( RxTransactionWork> work ); + Publisher readTransaction(RxTransactionWork> work); /** * Execute given unit of reactive work in a {@link AccessMode#READ read} reactive transaction with * the specified {@link TransactionConfig configuration}. -

+ *

* Transaction will automatically be committed unless given unit of work fails or * {@link RxTransaction#commit() transaction commit} fails. * It will also not be committed if explicitly rolled back via {@link RxTransaction#rollback()}. @@ -106,11 +103,11 @@ public interface RxSession extends RxQueryRunner * publisher can be completed exceptionally if given work or commit fails. * */ - Publisher readTransaction( RxTransactionWork> work, TransactionConfig config ); + Publisher readTransaction(RxTransactionWork> work, TransactionConfig config); /** * Execute given unit of reactive work in a {@link AccessMode#WRITE write} reactive transaction. -

+ *

* Transaction will automatically be committed unless given unit of work fails or * {@link RxTransaction#commit() transaction commit} fails. * It will also not be committed if explicitly rolled back via {@link RxTransaction#rollback()}. @@ -127,12 +124,12 @@ public interface RxSession extends RxQueryRunner * publisher can be completed exceptionally if given work or commit fails. * */ - Publisher writeTransaction( RxTransactionWork> work ); + Publisher writeTransaction(RxTransactionWork> work); /** * Execute given unit of reactive work in a {@link AccessMode#WRITE write} reactive transaction with * the specified {@link TransactionConfig configuration}. -

+ *

* Transaction will automatically be committed unless given unit of work fails or * {@link RxTransaction#commit() transaction commit} fails. * It will also not be committed if explicitly rolled back via {@link RxTransaction#rollback()}. @@ -150,7 +147,7 @@ public interface RxSession extends RxQueryRunner * publisher can be completed exceptionally if given work or commit fails. * */ - Publisher writeTransaction( RxTransactionWork> work, TransactionConfig config ); + Publisher writeTransaction(RxTransactionWork> work, TransactionConfig config); /** * Run a query with parameters in an auto-commit transaction with specified {@link TransactionConfig} and return a reactive result stream. @@ -161,7 +158,7 @@ public interface RxSession extends RxQueryRunner * @param config configuration for the new transaction. * @return a reactive result. */ - RxResult run(String query, TransactionConfig config ); + RxResult run(String query, TransactionConfig config); /** * Run a query with parameters in an auto-commit transaction with specified {@link TransactionConfig} and return a reactive result stream. @@ -199,7 +196,7 @@ public interface RxSession extends RxQueryRunner * @param config configuration for the new transaction. * @return a reactive result. */ - RxResult run(String query, Map parameters, TransactionConfig config ); + RxResult run(String query, Map parameters, TransactionConfig config); /** * Run a query in an auto-commit transaction with specified {@link TransactionConfig configuration} and return a reactive result stream. @@ -225,7 +222,7 @@ public interface RxSession extends RxQueryRunner * @param config configuration for the new transaction. * @return a reactive result. */ - RxResult run(Query query, TransactionConfig config ); + RxResult run(Query query, TransactionConfig config); /** * Return the bookmark received following the last completed query within this session. diff --git a/driver/src/main/java/org/neo4j/driver/reactive/RxTransaction.java b/driver/src/main/java/org/neo4j/driver/reactive/RxTransaction.java index 1c50e17dd7..9aec0c66a3 100644 --- a/driver/src/main/java/org/neo4j/driver/reactive/RxTransaction.java +++ b/driver/src/main/java/org/neo4j/driver/reactive/RxTransaction.java @@ -18,9 +18,8 @@ */ package org.neo4j.driver.reactive; -import org.reactivestreams.Publisher; - import org.neo4j.driver.Transaction; +import org.reactivestreams.Publisher; /** * Same as {@link Transaction} except this reactive transaction exposes a reactive API. @@ -29,8 +28,7 @@ * @see Publisher * @since 4.0 */ -public interface RxTransaction extends RxQueryRunner -{ +public interface RxTransaction extends RxQueryRunner { /** * Commits the transaction. * It completes without publishing anything if transaction is committed successfully. diff --git a/driver/src/main/java/org/neo4j/driver/reactive/RxTransactionWork.java b/driver/src/main/java/org/neo4j/driver/reactive/RxTransactionWork.java index ef68a8118f..b2ce4313e2 100644 --- a/driver/src/main/java/org/neo4j/driver/reactive/RxTransactionWork.java +++ b/driver/src/main/java/org/neo4j/driver/reactive/RxTransactionWork.java @@ -26,13 +26,12 @@ * @param the return type of this work. * @since 4.0 */ -public interface RxTransactionWork -{ +public interface RxTransactionWork { /** * Executes all given operations against the same transaction. * * @param tx the transaction to use. * @return some result object or {@code null} if none. */ - T execute( RxTransaction tx ); + T execute(RxTransaction tx); } diff --git a/driver/src/main/java/org/neo4j/driver/summary/DatabaseInfo.java b/driver/src/main/java/org/neo4j/driver/summary/DatabaseInfo.java index b7b17c6424..3361ddfd82 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/DatabaseInfo.java +++ b/driver/src/main/java/org/neo4j/driver/summary/DatabaseInfo.java @@ -21,8 +21,7 @@ /** * Provides basic information about where a {@link ResultSummary} is obtained from. */ -public interface DatabaseInfo -{ +public interface DatabaseInfo { /** * The name of the database where a {@link ResultSummary} is obtained from. * Default to {@code null} if servers does not support multi-databases. diff --git a/driver/src/main/java/org/neo4j/driver/summary/InputPosition.java b/driver/src/main/java/org/neo4j/driver/summary/InputPosition.java index 11775bdf88..208ee02c3c 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/InputPosition.java +++ b/driver/src/main/java/org/neo4j/driver/summary/InputPosition.java @@ -25,8 +25,7 @@ * @since 1.0 */ @Immutable -public interface InputPosition -{ +public interface InputPosition { /** * The character offset referred to by this position; offset numbers start at 0. * diff --git a/driver/src/main/java/org/neo4j/driver/summary/Notification.java b/driver/src/main/java/org/neo4j/driver/summary/Notification.java index c02c1a228b..df12784bb5 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/Notification.java +++ b/driver/src/main/java/org/neo4j/driver/summary/Notification.java @@ -27,8 +27,7 @@ * @since 1.0 */ @Immutable -public interface Notification -{ +public interface Notification { /** * Returns a notification code for the discovered issue. * @return the notification code diff --git a/driver/src/main/java/org/neo4j/driver/summary/Plan.java b/driver/src/main/java/org/neo4j/driver/summary/Plan.java index 1d51126926..561fd2d328 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/Plan.java +++ b/driver/src/main/java/org/neo4j/driver/summary/Plan.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Map; - import org.neo4j.driver.Value; import org.neo4j.driver.util.Immutable; @@ -38,8 +37,7 @@ * @since 1.0 */ @Immutable -public interface Plan -{ +public interface Plan { /** * @return the operation this plan is performing. */ @@ -51,7 +49,7 @@ public interface Plan * * @return the arguments for the {@link #operatorType() operator} used. */ - Map arguments(); + Map arguments(); /** * Identifiers used by this part of the plan. These can be both identifiers introduce by you, or automatically diff --git a/driver/src/main/java/org/neo4j/driver/summary/ProfiledPlan.java b/driver/src/main/java/org/neo4j/driver/summary/ProfiledPlan.java index de0bd7e8e2..7491e1b8c4 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/ProfiledPlan.java +++ b/driver/src/main/java/org/neo4j/driver/summary/ProfiledPlan.java @@ -25,8 +25,7 @@ * step of the plan incurred on the database. * @since 1.0 */ -public interface ProfiledPlan extends Plan -{ +public interface ProfiledPlan extends Plan { /** * @return the number of times this part of the plan touched the underlying data stores */ diff --git a/driver/src/main/java/org/neo4j/driver/summary/QueryType.java b/driver/src/main/java/org/neo4j/driver/summary/QueryType.java index 606a2de037..2d7fce6205 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/QueryType.java +++ b/driver/src/main/java/org/neo4j/driver/summary/QueryType.java @@ -19,7 +19,6 @@ package org.neo4j.driver.summary; import java.util.function.Function; - import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.Neo4jException; @@ -28,43 +27,36 @@ * * @since 1.0 */ -public enum QueryType -{ +public enum QueryType { READ_ONLY, READ_WRITE, WRITE_ONLY, SCHEMA_WRITE; private static final String UNEXPECTED_TYPE_MSG_FMT = "Unknown query type: `%s`."; - private static final Function UNEXPECTED_TYPE_EXCEPTION_SUPPLIER = - ( type ) -> new ClientException( String.format( UNEXPECTED_TYPE_MSG_FMT, type ) ); + private static final Function UNEXPECTED_TYPE_EXCEPTION_SUPPLIER = + (type) -> new ClientException(String.format(UNEXPECTED_TYPE_MSG_FMT, type)); - public static QueryType fromCode( String type ) - { - return fromCode( type, UNEXPECTED_TYPE_EXCEPTION_SUPPLIER ); + public static QueryType fromCode(String type) { + return fromCode(type, UNEXPECTED_TYPE_EXCEPTION_SUPPLIER); } - public static QueryType fromCode( String type, Function exceptionFunction ) - { - switch ( type ) - { - case "r": - return QueryType.READ_ONLY; - case "rw": - return QueryType.READ_WRITE; - case "w": - return QueryType.WRITE_ONLY; - case "s": - return QueryType.SCHEMA_WRITE; - default: - if ( exceptionFunction != null ) - { - throw exceptionFunction.apply( type ); - } - else - { - return null; - } + public static QueryType fromCode(String type, Function exceptionFunction) { + switch (type) { + case "r": + return QueryType.READ_ONLY; + case "rw": + return QueryType.READ_WRITE; + case "w": + return QueryType.WRITE_ONLY; + case "s": + return QueryType.SCHEMA_WRITE; + default: + if (exceptionFunction != null) { + throw exceptionFunction.apply(type); + } else { + return null; + } } } } diff --git a/driver/src/main/java/org/neo4j/driver/summary/ResultSummary.java b/driver/src/main/java/org/neo4j/driver/summary/ResultSummary.java index 7004d62975..025718bda5 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/ResultSummary.java +++ b/driver/src/main/java/org/neo4j/driver/summary/ResultSummary.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; - import org.neo4j.driver.Query; import org.neo4j.driver.util.Immutable; @@ -35,8 +34,7 @@ * @since 1.0 */ @Immutable -public interface ResultSummary -{ +public interface ResultSummary { /** * @return query that has been executed */ @@ -98,7 +96,7 @@ public interface ResultSummary * @param unit The unit of the duration. * @return The time it took for the server to have the result available in the provided time unit. */ - long resultAvailableAfter( TimeUnit unit ); + long resultAvailableAfter(TimeUnit unit); /** * The time it took the server to consume the result. @@ -106,7 +104,7 @@ public interface ResultSummary * @param unit The unit of the duration. * @return The time it took for the server to consume the result in the provided time unit. */ - long resultConsumedAfter( TimeUnit unit ); + long resultConsumedAfter(TimeUnit unit); /** * The basic information of the server where the result is obtained from diff --git a/driver/src/main/java/org/neo4j/driver/summary/ServerInfo.java b/driver/src/main/java/org/neo4j/driver/summary/ServerInfo.java index 5178ebc985..e783b09e79 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/ServerInfo.java +++ b/driver/src/main/java/org/neo4j/driver/summary/ServerInfo.java @@ -21,8 +21,7 @@ /** * Provides some basic information of the server where the result is obtained from. */ -public interface ServerInfo -{ +public interface ServerInfo { /** * Returns a string telling the address of the server the query was executed. diff --git a/driver/src/main/java/org/neo4j/driver/summary/SummaryCounters.java b/driver/src/main/java/org/neo4j/driver/summary/SummaryCounters.java index fc02b40691..be1f055f53 100644 --- a/driver/src/main/java/org/neo4j/driver/summary/SummaryCounters.java +++ b/driver/src/main/java/org/neo4j/driver/summary/SummaryCounters.java @@ -25,8 +25,7 @@ * @since 1.0 */ @Immutable -public interface SummaryCounters -{ +public interface SummaryCounters { /** * Whether there were any updates at all, eg. any of the counters are greater than 0. * @return true if the query made any updates diff --git a/driver/src/main/java/org/neo4j/driver/types/Entity.java b/driver/src/main/java/org/neo4j/driver/types/Entity.java index 06d7281648..4d9bc1cd34 100644 --- a/driver/src/main/java/org/neo4j/driver/types/Entity.java +++ b/driver/src/main/java/org/neo4j/driver/types/Entity.java @@ -25,8 +25,7 @@ * @since 1.0 */ @Immutable -public interface Entity extends MapAccessor -{ +public interface Entity extends MapAccessor { /** * A unique id for this Entity. Ids are guaranteed to remain stable for the duration of the session they * were found in, but may be re-used for other entities after that. As such, if you want a public identity to use diff --git a/driver/src/main/java/org/neo4j/driver/types/IsoDuration.java b/driver/src/main/java/org/neo4j/driver/types/IsoDuration.java index 51d3e3ebbd..537543ee66 100644 --- a/driver/src/main/java/org/neo4j/driver/types/IsoDuration.java +++ b/driver/src/main/java/org/neo4j/driver/types/IsoDuration.java @@ -19,7 +19,6 @@ package org.neo4j.driver.types; import java.time.temporal.TemporalAmount; - import org.neo4j.driver.Values; import org.neo4j.driver.util.Immutable; @@ -29,8 +28,7 @@ * Value that represents a duration can be created using {@link Values#isoDuration(long, long, long, int)} method. */ @Immutable -public interface IsoDuration extends TemporalAmount -{ +public interface IsoDuration extends TemporalAmount { /** * Retrieve amount of months in this duration. * diff --git a/driver/src/main/java/org/neo4j/driver/types/MapAccessor.java b/driver/src/main/java/org/neo4j/driver/types/MapAccessor.java index 97b5ec884f..a7df3b39a2 100644 --- a/driver/src/main/java/org/neo4j/driver/types/MapAccessor.java +++ b/driver/src/main/java/org/neo4j/driver/types/MapAccessor.java @@ -19,12 +19,11 @@ package org.neo4j.driver.types; import java.util.Map; - -import org.neo4j.driver.internal.value.NullValue; +import java.util.function.Function; import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.exceptions.ClientException; -import java.util.function.Function; +import org.neo4j.driver.internal.value.NullValue; /** * Access the keys, properties and values of an underlying unordered map by key @@ -33,8 +32,7 @@ * for changing the underlying map. * @since 1.0 */ -public interface MapAccessor -{ +public interface MapAccessor { /** * Retrieve the keys of the underlying map * @@ -48,7 +46,7 @@ public interface MapAccessor * @param key the key * @return {@code true} if this map keys contains the given key otherwise {@code false} */ - boolean containsKey( String key ); + boolean containsKey(String key); /** * Retrieve the value of the property with the given key @@ -57,7 +55,7 @@ public interface MapAccessor * @return the property's value or a {@link NullValue} if no such key exists * @throws ClientException if record has not been initialized */ - Value get( String key ); + Value get(String key); /** * Retrieve the number of entries in this map @@ -81,7 +79,7 @@ public interface MapAccessor * @param the target type of mapping * @return the result of mapping all values in unspecified order */ - Iterable values( Function mapFunction ); + Iterable values(Function mapFunction); /** * Return the underlying map as a map of string keys and values converted using @@ -100,5 +98,5 @@ public interface MapAccessor * @see Values for a long list of built-in conversion functions * @return the value as a map from string keys to values of type T obtained from mapping he original map values, if possible */ - Map asMap( Function mapFunction ); + Map asMap(Function mapFunction); } diff --git a/driver/src/main/java/org/neo4j/driver/types/MapAccessorWithDefaultValue.java b/driver/src/main/java/org/neo4j/driver/types/MapAccessorWithDefaultValue.java index 84df2eebec..c402bcac46 100644 --- a/driver/src/main/java/org/neo4j/driver/types/MapAccessorWithDefaultValue.java +++ b/driver/src/main/java/org/neo4j/driver/types/MapAccessorWithDefaultValue.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import java.util.function.Function; - import org.neo4j.driver.Value; /** @@ -30,8 +29,7 @@ * If the type of the value found A differs from the type of the default value B, a cast from A to B would happen automatically. Note: Error might arise if the * cast from A to B is not possible. */ -public interface MapAccessorWithDefaultValue extends MapAccessor -{ +public interface MapAccessorWithDefaultValue extends MapAccessor { /** * Retrieve the value with the given key. * If no value found by the key, then the default value provided would be returned. @@ -39,7 +37,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default value that would be returned if no value found by the key in the map * @return the value found by the key or the default value if no such key exists */ - Value get( String key, Value defaultValue ); + Value get(String key, Value defaultValue); /** * Retrieve the object with the given key. @@ -48,7 +46,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default object that would be returned if no object found by the key in the map * @return the object found by the key or the default object if no such key exists */ - Object get( String key, Object defaultValue ); + Object get(String key, Object defaultValue); /** * Retrieve the number with the given key. @@ -57,7 +55,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default number that would be returned if no number found by the key in the map * @return the number found by the key or the default number if no such key exists */ - Number get( String key, Number defaultValue ); + Number get(String key, Number defaultValue); /** * Retrieve the entity with the given key. @@ -66,7 +64,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default entity that would be returned if no entity found by the key in the map * @return the entity found by the key or the default entity if no such key exists */ - Entity get( String key, Entity defaultValue ); + Entity get(String key, Entity defaultValue); /** * Retrieve the node with the given key. @@ -75,7 +73,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default node that would be returned if no node found by the key in the map * @return the node found by the key or the default node if no such key exists */ - Node get( String key, Node defaultValue ); + Node get(String key, Node defaultValue); /** * Retrieve the path with the given key. @@ -84,7 +82,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default path that would be returned if no path found by the key in the map * @return the path found by the key or the default path if no such key exists */ - Path get( String key, Path defaultValue ); + Path get(String key, Path defaultValue); /** * Retrieve the value with the given key. @@ -93,7 +91,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default value that would be returned if no value found by the key in the map * @return the value found by the key or the default value if no such key exists */ - Relationship get( String key, Relationship defaultValue ); + Relationship get(String key, Relationship defaultValue); /** * Retrieve the list of objects with the given key. @@ -102,7 +100,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default value that would be returned if no value found by the key in the map * @return the list of objects found by the key or the default value if no such key exists */ - List get( String key, List defaultValue ); + List get(String key, List defaultValue); /** * Retrieve the list with the given key. @@ -113,7 +111,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param the type of the elements in the returned list * @return the converted list found by the key or the default list if no such key exists */ - List get( String key, List defaultValue, Function mapFunc ); + List get(String key, List defaultValue, Function mapFunc); /** * Retrieve the map with the given key. @@ -122,7 +120,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default value that would be returned if no value found by the key in the map * @return the map found by the key or the default value if no such key exists */ - Map get( String key, Map defaultValue ); + Map get(String key, Map defaultValue); /** * Retrieve the map with the given key. @@ -133,7 +131,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param the type of the values in the returned map * @return the converted map found by the key or the default map if no such key exists. */ - Map get( String key, Map defaultValue, Function mapFunc ); + Map get(String key, Map defaultValue, Function mapFunc); /** * Retrieve the java integer with the given key. @@ -142,7 +140,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default integer that would be returned if no integer found by the key in the map * @return the integer found by the key or the default integer if no such key exists */ - int get( String key, int defaultValue ); + int get(String key, int defaultValue); /** * Retrieve the java long number with the given key. @@ -151,7 +149,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default value that would be returned if no value found by the key in the map * @return the java long number found by the key or the default value if no such key exists */ - long get( String key, long defaultValue ); + long get(String key, long defaultValue); /** * Retrieve the java boolean with the given key. @@ -160,7 +158,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default value that would be returned if no value found by the key in the map * @return the java boolean found by the key or the default value if no such key exists */ - boolean get( String key, boolean defaultValue ); + boolean get(String key, boolean defaultValue); /** * Retrieve the java string with the given key. @@ -169,7 +167,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default string that would be returned if no string found by the key in the map * @return the string found by the key or the default string if no such key exists */ - String get( String key, String defaultValue ); + String get(String key, String defaultValue); /** * Retrieve the java float number with the given key. @@ -178,7 +176,7 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default value that would be returned if no value found by the key in the map * @return the java float number found by the key or the default value if no such key exists */ - float get( String key, float defaultValue ); + float get(String key, float defaultValue); /** * Retrieve the java double number with the given key. @@ -187,5 +185,5 @@ public interface MapAccessorWithDefaultValue extends MapAccessor * @param defaultValue the default value that would be returned if no value found by the key in the map * @return the java double number found by the key or the default value if no such key exists */ - double get( String key, double defaultValue ); + double get(String key, double defaultValue); } diff --git a/driver/src/main/java/org/neo4j/driver/types/Node.java b/driver/src/main/java/org/neo4j/driver/types/Node.java index f8b5bdcaaa..6562263db8 100644 --- a/driver/src/main/java/org/neo4j/driver/types/Node.java +++ b/driver/src/main/java/org/neo4j/driver/types/Node.java @@ -22,8 +22,7 @@ * The Node interface describes the characteristics of a node from a Neo4j graph. * @since 1.0 */ -public interface Node extends Entity -{ +public interface Node extends Entity { /** * Return all labels. * @@ -37,5 +36,5 @@ public interface Node extends Entity * @param label the label * @return {@code true} if this node has the label otherwise {@code false} */ - boolean hasLabel( String label ); + boolean hasLabel(String label); } diff --git a/driver/src/main/java/org/neo4j/driver/types/Path.java b/driver/src/main/java/org/neo4j/driver/types/Path.java index 98702989df..425f486023 100644 --- a/driver/src/main/java/org/neo4j/driver/types/Path.java +++ b/driver/src/main/java/org/neo4j/driver/types/Path.java @@ -40,8 +40,7 @@ * @since 1.0 */ @Immutable -public interface Path extends Iterable -{ +public interface Path extends Iterable { /** * A segment combines a relationship in a path with a start and end node that describe the traversal direction * for that relationship. This exists because the relationship has a direction between the two nodes that is @@ -52,8 +51,7 @@ public interface Path extends Iterable * Segment 2: (n2)<-[r2]-(n3) * } */ - interface Segment - { + interface Segment { /** @return the relationship underlying this path segment */ Relationship relationship(); @@ -83,13 +81,13 @@ interface Segment * @param node the node to check for * @return true if the specified node is contained in this path */ - boolean contains( Node node ); + boolean contains(Node node); /** * @param relationship the relationship to check for * @return true if the specified relationship is contained in this path */ - boolean contains( Relationship relationship ); + boolean contains(Relationship relationship); /** * Create an iterable over the nodes in this path, nodes will appear in the same order as they appear diff --git a/driver/src/main/java/org/neo4j/driver/types/Point.java b/driver/src/main/java/org/neo4j/driver/types/Point.java index 107e6ebba1..1aa6039361 100644 --- a/driver/src/main/java/org/neo4j/driver/types/Point.java +++ b/driver/src/main/java/org/neo4j/driver/types/Point.java @@ -28,8 +28,7 @@ * or {@link Values#point(int, double, double, double)} method. */ @Immutable -public interface Point -{ +public interface Point { /** * Retrieve identifier of the coordinate reference system for this point. * diff --git a/driver/src/main/java/org/neo4j/driver/types/Relationship.java b/driver/src/main/java/org/neo4j/driver/types/Relationship.java index 241c3a838c..162f5a8f9a 100644 --- a/driver/src/main/java/org/neo4j/driver/types/Relationship.java +++ b/driver/src/main/java/org/neo4j/driver/types/Relationship.java @@ -22,8 +22,7 @@ * The Relationship interface describes the characteristics of a relationship from a Neo4j graph. * @since 1.0 */ -public interface Relationship extends Entity -{ +public interface Relationship extends Entity { /** * Id of the node where this relationship starts. * @return the node id @@ -49,5 +48,5 @@ public interface Relationship extends Entity * @param relationshipType the give relationship type * @return {@code true} if this relationship has the given relationship type otherwise {@code false} */ - boolean hasType( String relationshipType ); + boolean hasType(String relationshipType); } diff --git a/driver/src/main/java/org/neo4j/driver/types/Type.java b/driver/src/main/java/org/neo4j/driver/types/Type.java index d6cd401ca6..694b8f2ff5 100644 --- a/driver/src/main/java/org/neo4j/driver/types/Type.java +++ b/driver/src/main/java/org/neo4j/driver/types/Type.java @@ -28,8 +28,7 @@ */ @Immutable @Experimental -public interface Type -{ +public interface Type { /** * @return the name of the Cypher type (as defined by Cypher) */ @@ -41,5 +40,5 @@ public interface Type * @param value the value * @return {@code true} if the value is a value of this type otherwise {@code false} */ - boolean isTypeOf( Value value ); + boolean isTypeOf(Value value); } diff --git a/driver/src/main/java/org/neo4j/driver/types/TypeSystem.java b/driver/src/main/java/org/neo4j/driver/types/TypeSystem.java index 35cb1775d3..31373c3508 100644 --- a/driver/src/main/java/org/neo4j/driver/types/TypeSystem.java +++ b/driver/src/main/java/org/neo4j/driver/types/TypeSystem.java @@ -27,8 +27,7 @@ */ @Immutable @Experimental -public interface TypeSystem -{ +public interface TypeSystem { Type ANY(); Type BOOLEAN(); diff --git a/driver/src/main/java/org/neo4j/driver/util/Experimental.java b/driver/src/main/java/org/neo4j/driver/util/Experimental.java index 5485fa738f..9d46c39138 100644 --- a/driver/src/main/java/org/neo4j/driver/util/Experimental.java +++ b/driver/src/main/java/org/neo4j/driver/util/Experimental.java @@ -32,7 +32,5 @@ @Inherited @Retention(RetentionPolicy.RUNTIME) @Documented -@Target( { ElementType.TYPE, ElementType.METHOD } ) -public @interface Experimental -{ -} +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface Experimental {} diff --git a/driver/src/main/java/org/neo4j/driver/util/Immutable.java b/driver/src/main/java/org/neo4j/driver/util/Immutable.java index c4242ffab5..aca35d3884 100644 --- a/driver/src/main/java/org/neo4j/driver/util/Immutable.java +++ b/driver/src/main/java/org/neo4j/driver/util/Immutable.java @@ -33,7 +33,5 @@ @Inherited @Retention(RetentionPolicy.RUNTIME) @Documented -@Target( { ElementType.TYPE } ) -public @interface Immutable -{ -} +@Target({ElementType.TYPE}) +public @interface Immutable {} diff --git a/driver/src/main/java/org/neo4j/driver/util/Pair.java b/driver/src/main/java/org/neo4j/driver/util/Pair.java index 0b1886008b..808f77a669 100644 --- a/driver/src/main/java/org/neo4j/driver/util/Pair.java +++ b/driver/src/main/java/org/neo4j/driver/util/Pair.java @@ -25,8 +25,7 @@ * @since 1.0 */ @Immutable -public interface Pair -{ +public interface Pair { /** * @return the property key */ diff --git a/driver/src/main/java/org/neo4j/driver/util/Resource.java b/driver/src/main/java/org/neo4j/driver/util/Resource.java index 19aae1e5f9..8815a7cbe8 100644 --- a/driver/src/main/java/org/neo4j/driver/util/Resource.java +++ b/driver/src/main/java/org/neo4j/driver/util/Resource.java @@ -24,8 +24,7 @@ * * @since 1.0 */ -public interface Resource extends AutoCloseable -{ +public interface Resource extends AutoCloseable { /** * Detect whether this resource is still open * diff --git a/driver/src/test/java/org/neo4j/driver/AuthTokensTest.java b/driver/src/test/java/org/neo4j/driver/AuthTokensTest.java index f2e0a8fa9f..bdc6c27ee8 100644 --- a/driver/src/test/java/org/neo4j/driver/AuthTokensTest.java +++ b/driver/src/test/java/org/neo4j/driver/AuthTokensTest.java @@ -18,16 +18,6 @@ */ package org.neo4j.driver; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.Map; - -import org.neo4j.driver.internal.security.InternalAuthToken; -import org.neo4j.driver.internal.value.ListValue; -import org.neo4j.driver.internal.value.MapValue; -import org.neo4j.driver.internal.value.StringValue; - import static java.util.Arrays.asList; import static org.hamcrest.core.IsEqual.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; @@ -37,167 +27,161 @@ import static org.neo4j.driver.AuthTokens.custom; import static org.neo4j.driver.Values.values; -class AuthTokensTest -{ +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.security.InternalAuthToken; +import org.neo4j.driver.internal.value.ListValue; +import org.neo4j.driver.internal.value.MapValue; +import org.neo4j.driver.internal.value.StringValue; + +class AuthTokensTest { @Test - void basicAuthWithoutRealm() - { - InternalAuthToken basic = (InternalAuthToken) basic( "foo", "bar" ); + void basicAuthWithoutRealm() { + InternalAuthToken basic = (InternalAuthToken) basic("foo", "bar"); - Map map = basic.toMap(); + Map map = basic.toMap(); - assertThat( map.size(), equalTo( 3 ) ); - assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "basic" ) ) ); - assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "foo" ) ) ); - assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "bar" ) ) ); + assertThat(map.size(), equalTo(3)); + assertThat(map.get("scheme"), equalTo((Value) new StringValue("basic"))); + assertThat(map.get("principal"), equalTo((Value) new StringValue("foo"))); + assertThat(map.get("credentials"), equalTo((Value) new StringValue("bar"))); } @Test - void basicAuthWithRealm() - { - InternalAuthToken basic = (InternalAuthToken) basic( "foo", "bar", "baz" ); + void basicAuthWithRealm() { + InternalAuthToken basic = (InternalAuthToken) basic("foo", "bar", "baz"); - Map map = basic.toMap(); + Map map = basic.toMap(); - assertThat( map.size(), equalTo( 4 ) ); - assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "basic" ) ) ); - assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "foo" ) ) ); - assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "bar" ) ) ); - assertThat( map.get( "realm" ), equalTo( (Value) new StringValue( "baz" ) ) ); + assertThat(map.size(), equalTo(4)); + assertThat(map.get("scheme"), equalTo((Value) new StringValue("basic"))); + assertThat(map.get("principal"), equalTo((Value) new StringValue("foo"))); + assertThat(map.get("credentials"), equalTo((Value) new StringValue("bar"))); + assertThat(map.get("realm"), equalTo((Value) new StringValue("baz"))); } @Test - void customAuthWithoutParameters() - { - InternalAuthToken basic = (InternalAuthToken) custom( "foo", "bar", "baz", "my_scheme" ); + void customAuthWithoutParameters() { + InternalAuthToken basic = (InternalAuthToken) custom("foo", "bar", "baz", "my_scheme"); - Map map = basic.toMap(); + Map map = basic.toMap(); - assertThat( map.size(), equalTo( 4 ) ); - assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "my_scheme" ) ) ); - assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "foo" ) ) ); - assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "bar" ) ) ); - assertThat( map.get( "realm" ), equalTo( (Value) new StringValue( "baz" ) ) ); + assertThat(map.size(), equalTo(4)); + assertThat(map.get("scheme"), equalTo((Value) new StringValue("my_scheme"))); + assertThat(map.get("principal"), equalTo((Value) new StringValue("foo"))); + assertThat(map.get("credentials"), equalTo((Value) new StringValue("bar"))); + assertThat(map.get("realm"), equalTo((Value) new StringValue("baz"))); } @Test - void customAuthParameters() - { - HashMap parameters = new HashMap<>(); - parameters.put( "list", asList( 1, 2, 3 ) ); - InternalAuthToken basic = (InternalAuthToken) custom( "foo", "bar", "baz", "my_scheme", parameters ); - - - Map expectedParameters = new HashMap<>(); - expectedParameters.put( "list", new ListValue( values( 1, 2, 3 ) ) ); - Map map = basic.toMap(); - - assertThat( map.size(), equalTo( 5 ) ); - assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "my_scheme" ) ) ); - assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "foo" ) ) ); - assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "bar" ) ) ); - assertThat( map.get( "realm" ), equalTo( (Value) new StringValue( "baz" ) ) ); - assertThat( map.get( "parameters" ), equalTo( (Value) new MapValue( expectedParameters ) ) ); + void customAuthParameters() { + HashMap parameters = new HashMap<>(); + parameters.put("list", asList(1, 2, 3)); + InternalAuthToken basic = (InternalAuthToken) custom("foo", "bar", "baz", "my_scheme", parameters); + + Map expectedParameters = new HashMap<>(); + expectedParameters.put("list", new ListValue(values(1, 2, 3))); + Map map = basic.toMap(); + + assertThat(map.size(), equalTo(5)); + assertThat(map.get("scheme"), equalTo((Value) new StringValue("my_scheme"))); + assertThat(map.get("principal"), equalTo((Value) new StringValue("foo"))); + assertThat(map.get("credentials"), equalTo((Value) new StringValue("bar"))); + assertThat(map.get("realm"), equalTo((Value) new StringValue("baz"))); + assertThat(map.get("parameters"), equalTo((Value) new MapValue(expectedParameters))); } @Test - void shouldSupportBearerAuth() - { + void shouldSupportBearerAuth() { // GIVEN String tokenStr = "token"; // WHEN - InternalAuthToken token = (InternalAuthToken) AuthTokens.bearer( tokenStr ); + InternalAuthToken token = (InternalAuthToken) AuthTokens.bearer(tokenStr); // THEN - Map map = token.toMap(); - assertThat( map.size(), equalTo( 2 ) ); - assertThat( map.get( "scheme" ), equalTo( new StringValue( "bearer" ) ) ); - assertThat( map.get( "credentials" ), equalTo( new StringValue( tokenStr ) ) ); + Map map = token.toMap(); + assertThat(map.size(), equalTo(2)); + assertThat(map.get("scheme"), equalTo(new StringValue("bearer"))); + assertThat(map.get("credentials"), equalTo(new StringValue(tokenStr))); } @Test - void basicKerberosAuthWithRealm() - { - InternalAuthToken token = (InternalAuthToken) AuthTokens.kerberos( "base64" ); - Map map = token.toMap(); - - assertThat( map.size(), equalTo( 3 ) ); - assertThat( map.get( "scheme" ), equalTo( (Value) new StringValue( "kerberos" ) ) ); - assertThat( map.get( "principal" ), equalTo( (Value) new StringValue( "" ) ) ); - assertThat( map.get( "credentials" ), equalTo( (Value) new StringValue( "base64" ) ) ); + void basicKerberosAuthWithRealm() { + InternalAuthToken token = (InternalAuthToken) AuthTokens.kerberos("base64"); + Map map = token.toMap(); + + assertThat(map.size(), equalTo(3)); + assertThat(map.get("scheme"), equalTo((Value) new StringValue("kerberos"))); + assertThat(map.get("principal"), equalTo((Value) new StringValue(""))); + assertThat(map.get("credentials"), equalTo((Value) new StringValue("base64"))); } @Test - void shouldNotAllowBasicAuthTokenWithNullUsername() - { - NullPointerException e = assertThrows( NullPointerException.class, () -> AuthTokens.basic( null, "password" ) ); - assertEquals( "Username can't be null", e.getMessage() ); + void shouldNotAllowBasicAuthTokenWithNullUsername() { + NullPointerException e = assertThrows(NullPointerException.class, () -> AuthTokens.basic(null, "password")); + assertEquals("Username can't be null", e.getMessage()); } @Test - void shouldNotAllowBasicAuthTokenWithNullPassword() - { - NullPointerException e = assertThrows( NullPointerException.class, () -> AuthTokens.basic( "username", null ) ); - assertEquals( "Password can't be null", e.getMessage() ); + void shouldNotAllowBasicAuthTokenWithNullPassword() { + NullPointerException e = assertThrows(NullPointerException.class, () -> AuthTokens.basic("username", null)); + assertEquals("Password can't be null", e.getMessage()); } @Test - void shouldAllowBasicAuthTokenWithNullRealm() - { - AuthToken token = AuthTokens.basic( "username", "password", null ); - Map map = ((InternalAuthToken) token).toMap(); - - assertEquals( 3, map.size() ); - assertEquals( "basic", map.get( "scheme" ).asString() ); - assertEquals( "username", map.get( "principal" ).asString() ); - assertEquals( "password", map.get( "credentials" ).asString() ); + void shouldAllowBasicAuthTokenWithNullRealm() { + AuthToken token = AuthTokens.basic("username", "password", null); + Map map = ((InternalAuthToken) token).toMap(); + + assertEquals(3, map.size()); + assertEquals("basic", map.get("scheme").asString()); + assertEquals("username", map.get("principal").asString()); + assertEquals("password", map.get("credentials").asString()); } @Test - void shouldNotAllowBearerAuthTokenWithNullToken() - { - NullPointerException e = assertThrows( NullPointerException.class, () -> AuthTokens.bearer( null ) ); - assertEquals( "Token can't be null", e.getMessage() ); + void shouldNotAllowBearerAuthTokenWithNullToken() { + NullPointerException e = assertThrows(NullPointerException.class, () -> AuthTokens.bearer(null)); + assertEquals("Token can't be null", e.getMessage()); } @Test - void shouldNotAllowKerberosAuthTokenWithNullTicket() - { - NullPointerException e = assertThrows( NullPointerException.class, () -> AuthTokens.kerberos( null ) ); - assertEquals( "Ticket can't be null", e.getMessage() ); + void shouldNotAllowKerberosAuthTokenWithNullTicket() { + NullPointerException e = assertThrows(NullPointerException.class, () -> AuthTokens.kerberos(null)); + assertEquals("Ticket can't be null", e.getMessage()); } @Test - void shouldNotAllowCustomAuthTokenWithNullPrincipal() - { - NullPointerException e = assertThrows( NullPointerException.class, () -> AuthTokens.custom( null, "credentials", "realm", "scheme" ) ); - assertEquals( "Principal can't be null", e.getMessage() ); + void shouldNotAllowCustomAuthTokenWithNullPrincipal() { + NullPointerException e = assertThrows( + NullPointerException.class, () -> AuthTokens.custom(null, "credentials", "realm", "scheme")); + assertEquals("Principal can't be null", e.getMessage()); } @Test - void shouldNotAllowCustomAuthTokenWithNullCredentials() - { - NullPointerException e = assertThrows( NullPointerException.class, () -> AuthTokens.custom( "principal", null, "realm", "scheme" ) ); - assertEquals( "Credentials can't be null", e.getMessage() ); + void shouldNotAllowCustomAuthTokenWithNullCredentials() { + NullPointerException e = + assertThrows(NullPointerException.class, () -> AuthTokens.custom("principal", null, "realm", "scheme")); + assertEquals("Credentials can't be null", e.getMessage()); } @Test - void shouldAllowCustomAuthTokenWithNullRealm() - { - AuthToken token = AuthTokens.custom( "principal", "credentials", null, "scheme" ); - Map map = ((InternalAuthToken) token).toMap(); - - assertEquals( 3, map.size() ); - assertEquals( "scheme", map.get( "scheme" ).asString() ); - assertEquals( "principal", map.get( "principal" ).asString() ); - assertEquals( "credentials", map.get( "credentials" ).asString() ); + void shouldAllowCustomAuthTokenWithNullRealm() { + AuthToken token = AuthTokens.custom("principal", "credentials", null, "scheme"); + Map map = ((InternalAuthToken) token).toMap(); + + assertEquals(3, map.size()); + assertEquals("scheme", map.get("scheme").asString()); + assertEquals("principal", map.get("principal").asString()); + assertEquals("credentials", map.get("credentials").asString()); } @Test - void shouldNotAllowCustomAuthTokenWithNullScheme() - { - NullPointerException e = assertThrows( NullPointerException.class, () -> AuthTokens.custom( "principal", "credentials", "realm", null ) ); - assertEquals( "Scheme can't be null", e.getMessage() ); + void shouldNotAllowCustomAuthTokenWithNullScheme() { + NullPointerException e = assertThrows( + NullPointerException.class, () -> AuthTokens.custom("principal", "credentials", "realm", null)); + assertEquals("Scheme can't be null", e.getMessage()); } } diff --git a/driver/src/test/java/org/neo4j/driver/ConfigTest.java b/driver/src/test/java/org/neo4j/driver/ConfigTest.java index 64bdbe95d3..b983d1f67f 100644 --- a/driver/src/test/java/org/neo4j/driver/ConfigTest.java +++ b/driver/src/test/java/org/neo4j/driver/ConfigTest.java @@ -18,12 +18,18 @@ */ package org.neo4j.driver; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import org.junit.platform.commons.support.HierarchyTraversalMode; -import org.junit.platform.commons.support.ReflectionSupport; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.internal.RevocationStrategy.NO_CHECKS; +import static org.neo4j.driver.internal.RevocationStrategy.STRICT; +import static org.neo4j.driver.internal.RevocationStrategy.VERIFY_IF_PRESENT; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.DEFAULT_FETCH_SIZE; import java.io.File; import java.io.IOException; @@ -32,7 +38,12 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Level; - +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; import org.neo4j.driver.internal.logging.ConsoleLogging; import org.neo4j.driver.internal.logging.DevNullLogging; import org.neo4j.driver.internal.logging.JULogging; @@ -40,24 +51,9 @@ import org.neo4j.driver.net.ServerAddressResolver; import org.neo4j.driver.util.TestUtil; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.internal.RevocationStrategy.NO_CHECKS; -import static org.neo4j.driver.internal.RevocationStrategy.STRICT; -import static org.neo4j.driver.internal.RevocationStrategy.VERIFY_IF_PRESENT; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.DEFAULT_FETCH_SIZE; - -class ConfigTest -{ +class ConfigTest { @Test - void shouldDefaultToKnownCerts() - { + void shouldDefaultToKnownCerts() { // Given Config config = Config.defaultConfig(); @@ -65,411 +61,412 @@ void shouldDefaultToKnownCerts() Config.TrustStrategy authConfig = config.trustStrategy(); // Then - assertEquals( authConfig.strategy(), Config.TrustStrategy.Strategy.TRUST_SYSTEM_CA_SIGNED_CERTIFICATES ); + assertEquals(authConfig.strategy(), Config.TrustStrategy.Strategy.TRUST_SYSTEM_CA_SIGNED_CERTIFICATES); } @Test - void shouldChangeToTrustedCert() - { + void shouldChangeToTrustedCert() { // Given - File trustedCert = new File( "trusted_cert" ); - Config config = Config.builder().withTrustStrategy( Config.TrustStrategy.trustCustomCertificateSignedBy( trustedCert ) ).build(); + File trustedCert = new File("trusted_cert"); + Config config = Config.builder() + .withTrustStrategy(Config.TrustStrategy.trustCustomCertificateSignedBy(trustedCert)) + .build(); // When Config.TrustStrategy authConfig = config.trustStrategy(); // Then - assertEquals( authConfig.strategy(), Config.TrustStrategy.Strategy.TRUST_CUSTOM_CA_SIGNED_CERTIFICATES ); - assertEquals( trustedCert.getAbsolutePath(), authConfig.certFiles().get( 0 ).getAbsolutePath() ); + assertEquals(authConfig.strategy(), Config.TrustStrategy.Strategy.TRUST_CUSTOM_CA_SIGNED_CERTIFICATES); + assertEquals( + trustedCert.getAbsolutePath(), authConfig.certFiles().get(0).getAbsolutePath()); } @Test - void shouldSupportLivenessCheckTimeoutSetting() - { - Config config = Config.builder().withConnectionLivenessCheckTimeout( 42, TimeUnit.SECONDS ).build(); + void shouldSupportLivenessCheckTimeoutSetting() { + Config config = Config.builder() + .withConnectionLivenessCheckTimeout(42, TimeUnit.SECONDS) + .build(); - assertEquals( TimeUnit.SECONDS.toMillis( 42 ), config.idleTimeBeforeConnectionTest() ); + assertEquals(TimeUnit.SECONDS.toMillis(42), config.idleTimeBeforeConnectionTest()); } @Test - void shouldAllowZeroConnectionLivenessCheckTimeout() - { - Config config = Config.builder().withConnectionLivenessCheckTimeout( 0, TimeUnit.SECONDS ).build(); + void shouldAllowZeroConnectionLivenessCheckTimeout() { + Config config = Config.builder() + .withConnectionLivenessCheckTimeout(0, TimeUnit.SECONDS) + .build(); - assertEquals( 0, config.idleTimeBeforeConnectionTest() ); + assertEquals(0, config.idleTimeBeforeConnectionTest()); } @Test - void shouldAllowNegativeConnectionLivenessCheckTimeout() - { - Config config = Config.builder().withConnectionLivenessCheckTimeout( -42, TimeUnit.SECONDS ).build(); + void shouldAllowNegativeConnectionLivenessCheckTimeout() { + Config config = Config.builder() + .withConnectionLivenessCheckTimeout(-42, TimeUnit.SECONDS) + .build(); - assertEquals( TimeUnit.SECONDS.toMillis( -42 ), config.idleTimeBeforeConnectionTest() ); + assertEquals(TimeUnit.SECONDS.toMillis(-42), config.idleTimeBeforeConnectionTest()); } @Test - void shouldHaveCorrectMaxConnectionLifetime() - { - assertEquals( TimeUnit.HOURS.toMillis( 1 ), Config.defaultConfig().maxConnectionLifetimeMillis() ); + void shouldHaveCorrectMaxConnectionLifetime() { + assertEquals(TimeUnit.HOURS.toMillis(1), Config.defaultConfig().maxConnectionLifetimeMillis()); } @Test - void shouldSupportMaxConnectionLifetimeSetting() - { - Config config = Config.builder().withMaxConnectionLifetime( 42, TimeUnit.SECONDS ).build(); + void shouldSupportMaxConnectionLifetimeSetting() { + Config config = + Config.builder().withMaxConnectionLifetime(42, TimeUnit.SECONDS).build(); - assertEquals( TimeUnit.SECONDS.toMillis( 42 ), config.maxConnectionLifetimeMillis() ); + assertEquals(TimeUnit.SECONDS.toMillis(42), config.maxConnectionLifetimeMillis()); } @Test - void shouldAllowZeroConnectionMaxConnectionLifetime() - { - Config config = Config.builder().withMaxConnectionLifetime( 0, TimeUnit.SECONDS ).build(); + void shouldAllowZeroConnectionMaxConnectionLifetime() { + Config config = + Config.builder().withMaxConnectionLifetime(0, TimeUnit.SECONDS).build(); - assertEquals( 0, config.maxConnectionLifetimeMillis() ); + assertEquals(0, config.maxConnectionLifetimeMillis()); } @Test - void shouldAllowNegativeConnectionMaxConnectionLifetime() - { - Config config = Config.builder().withMaxConnectionLifetime( -42, TimeUnit.SECONDS ).build(); + void shouldAllowNegativeConnectionMaxConnectionLifetime() { + Config config = Config.builder() + .withMaxConnectionLifetime(-42, TimeUnit.SECONDS) + .build(); - assertEquals( TimeUnit.SECONDS.toMillis( -42 ), config.maxConnectionLifetimeMillis() ); + assertEquals(TimeUnit.SECONDS.toMillis(-42), config.maxConnectionLifetimeMillis()); } @Test - void shouldTurnOnLeakedSessionsLogging() - { + void shouldTurnOnLeakedSessionsLogging() { // leaked sessions logging is turned off by default - assertFalse( Config.builder().build().logLeakedSessions() ); + assertFalse(Config.builder().build().logLeakedSessions()); // it can be turned on using config - assertTrue( Config.builder().withLeakedSessionsLogging().build().logLeakedSessions() ); + assertTrue(Config.builder().withLeakedSessionsLogging().build().logLeakedSessions()); } @Test - void shouldHaveDefaultConnectionTimeout() - { + void shouldHaveDefaultConnectionTimeout() { Config defaultConfig = Config.defaultConfig(); - assertEquals( TimeUnit.SECONDS.toMillis( 30 ), defaultConfig.connectionTimeoutMillis() ); + assertEquals(TimeUnit.SECONDS.toMillis(30), defaultConfig.connectionTimeoutMillis()); } @Test - void shouldRespectConfiguredConnectionTimeout() - { - Config config = Config.builder().withConnectionTimeout( 42, TimeUnit.HOURS ).build(); - assertEquals( TimeUnit.HOURS.toMillis( 42 ), config.connectionTimeoutMillis() ); + void shouldRespectConfiguredConnectionTimeout() { + Config config = + Config.builder().withConnectionTimeout(42, TimeUnit.HOURS).build(); + assertEquals(TimeUnit.HOURS.toMillis(42), config.connectionTimeoutMillis()); } @Test - void shouldAllowConnectionTimeoutOfZero() - { - Config config = Config.builder().withConnectionTimeout( 0, TimeUnit.SECONDS ).build(); - assertEquals( 0, config.connectionTimeoutMillis() ); + void shouldAllowConnectionTimeoutOfZero() { + Config config = + Config.builder().withConnectionTimeout(0, TimeUnit.SECONDS).build(); + assertEquals(0, config.connectionTimeoutMillis()); } @Test - void shouldThrowForNegativeConnectionTimeout() - { + void shouldThrowForNegativeConnectionTimeout() { Config.ConfigBuilder builder = Config.builder(); - assertThrows( IllegalArgumentException.class, () -> builder.withConnectionTimeout( -42, TimeUnit.SECONDS ) ); + assertThrows(IllegalArgumentException.class, () -> builder.withConnectionTimeout(-42, TimeUnit.SECONDS)); } @Test - void shouldThrowForTooLargeConnectionTimeout() - { + void shouldThrowForTooLargeConnectionTimeout() { Config.ConfigBuilder builder = Config.builder(); - assertThrows( IllegalArgumentException.class, () -> builder.withConnectionTimeout( Long.MAX_VALUE - 42, TimeUnit.SECONDS ) ); + assertThrows( + IllegalArgumentException.class, + () -> builder.withConnectionTimeout(Long.MAX_VALUE - 42, TimeUnit.SECONDS)); } @Test - void shouldNotAllowNegativeMaxRetryTimeMs() - { + void shouldNotAllowNegativeMaxRetryTimeMs() { Config.ConfigBuilder builder = Config.builder(); - assertThrows( IllegalArgumentException.class, () -> builder.withMaxTransactionRetryTime( -42, TimeUnit.SECONDS ) ); + assertThrows(IllegalArgumentException.class, () -> builder.withMaxTransactionRetryTime(-42, TimeUnit.SECONDS)); } @Test - void shouldAllowZeroMaxRetryTimeMs() - { - Config config = Config.builder().withMaxTransactionRetryTime( 0, TimeUnit.SECONDS ).build(); + void shouldAllowZeroMaxRetryTimeMs() { + Config config = Config.builder() + .withMaxTransactionRetryTime(0, TimeUnit.SECONDS) + .build(); - assertEquals( 0, config.retrySettings().maxRetryTimeMs() ); + assertEquals(0, config.retrySettings().maxRetryTimeMs()); } @Test - void shouldAllowPositiveRetryAttempts() - { - Config config = Config.builder().withMaxTransactionRetryTime( 42, TimeUnit.SECONDS ).build(); + void shouldAllowPositiveRetryAttempts() { + Config config = Config.builder() + .withMaxTransactionRetryTime(42, TimeUnit.SECONDS) + .build(); - assertEquals( TimeUnit.SECONDS.toMillis( 42 ), config.retrySettings().maxRetryTimeMs() ); + assertEquals(TimeUnit.SECONDS.toMillis(42), config.retrySettings().maxRetryTimeMs()); } @Test - void shouldHaveCorrectDefaultMaxConnectionPoolSize() - { - assertEquals( 100, Config.defaultConfig().maxConnectionPoolSize() ); + void shouldHaveCorrectDefaultMaxConnectionPoolSize() { + assertEquals(100, Config.defaultConfig().maxConnectionPoolSize()); } @Test - void shouldAllowPositiveMaxConnectionPoolSize() - { - Config config = Config.builder().withMaxConnectionPoolSize( 42 ).build(); + void shouldAllowPositiveMaxConnectionPoolSize() { + Config config = Config.builder().withMaxConnectionPoolSize(42).build(); - assertEquals( 42, config.maxConnectionPoolSize() ); + assertEquals(42, config.maxConnectionPoolSize()); } @Test - void shouldAllowNegativeMaxConnectionPoolSize() - { - Config config = Config.builder().withMaxConnectionPoolSize( -42 ).build(); + void shouldAllowNegativeMaxConnectionPoolSize() { + Config config = Config.builder().withMaxConnectionPoolSize(-42).build(); - assertEquals( Integer.MAX_VALUE, config.maxConnectionPoolSize() ); + assertEquals(Integer.MAX_VALUE, config.maxConnectionPoolSize()); } @Test - void shouldDisallowZeroMaxConnectionPoolSize() - { - IllegalArgumentException e = assertThrows( IllegalArgumentException.class, () -> Config.builder().withMaxConnectionPoolSize( 0 ).build() ); - assertEquals( "Zero value is not supported", e.getMessage() ); + void shouldDisallowZeroMaxConnectionPoolSize() { + IllegalArgumentException e = assertThrows( + IllegalArgumentException.class, + () -> Config.builder().withMaxConnectionPoolSize(0).build()); + assertEquals("Zero value is not supported", e.getMessage()); } @Test - void shouldHaveCorrectDefaultConnectionAcquisitionTimeout() - { - assertEquals( TimeUnit.SECONDS.toMillis( 60 ), Config.defaultConfig().connectionAcquisitionTimeoutMillis() ); + void shouldHaveCorrectDefaultConnectionAcquisitionTimeout() { + assertEquals(TimeUnit.SECONDS.toMillis(60), Config.defaultConfig().connectionAcquisitionTimeoutMillis()); } @Test - void shouldAllowPositiveConnectionAcquisitionTimeout() - { - Config config = Config.builder().withConnectionAcquisitionTimeout( 42, TimeUnit.SECONDS ).build(); + void shouldAllowPositiveConnectionAcquisitionTimeout() { + Config config = Config.builder() + .withConnectionAcquisitionTimeout(42, TimeUnit.SECONDS) + .build(); - assertEquals( TimeUnit.SECONDS.toMillis( 42 ), config.connectionAcquisitionTimeoutMillis() ); + assertEquals(TimeUnit.SECONDS.toMillis(42), config.connectionAcquisitionTimeoutMillis()); } @Test - void shouldAllowNegativeConnectionAcquisitionTimeout() - { - Config config = Config.builder().withConnectionAcquisitionTimeout( -42, TimeUnit.HOURS ).build(); + void shouldAllowNegativeConnectionAcquisitionTimeout() { + Config config = Config.builder() + .withConnectionAcquisitionTimeout(-42, TimeUnit.HOURS) + .build(); - assertEquals( -1, config.connectionAcquisitionTimeoutMillis() ); + assertEquals(-1, config.connectionAcquisitionTimeoutMillis()); } @Test - void shouldAllowConnectionAcquisitionTimeoutOfZero() - { - Config config = Config.builder().withConnectionAcquisitionTimeout( 0, TimeUnit.DAYS ).build(); + void shouldAllowConnectionAcquisitionTimeoutOfZero() { + Config config = Config.builder() + .withConnectionAcquisitionTimeout(0, TimeUnit.DAYS) + .build(); - assertEquals( 0, config.connectionAcquisitionTimeoutMillis() ); + assertEquals(0, config.connectionAcquisitionTimeoutMillis()); } @Test - void shouldEnableAndDisableHostnameVerificationOnTrustStrategy() - { + void shouldEnableAndDisableHostnameVerificationOnTrustStrategy() { Config.TrustStrategy trustStrategy = Config.TrustStrategy.trustSystemCertificates(); - assertTrue( trustStrategy.isHostnameVerificationEnabled() ); + assertTrue(trustStrategy.isHostnameVerificationEnabled()); - assertSame( trustStrategy, trustStrategy.withHostnameVerification() ); - assertTrue( trustStrategy.isHostnameVerificationEnabled() ); + assertSame(trustStrategy, trustStrategy.withHostnameVerification()); + assertTrue(trustStrategy.isHostnameVerificationEnabled()); - assertSame( trustStrategy, trustStrategy.withoutHostnameVerification() ); - assertFalse( trustStrategy.isHostnameVerificationEnabled() ); + assertSame(trustStrategy, trustStrategy.withoutHostnameVerification()); + assertFalse(trustStrategy.isHostnameVerificationEnabled()); } @Test - void shouldEnableAndDisableCertificateRevocationChecksOnTestStrategy() - { + void shouldEnableAndDisableCertificateRevocationChecksOnTestStrategy() { Config.TrustStrategy trustStrategy = Config.TrustStrategy.trustSystemCertificates(); - assertEquals( NO_CHECKS, trustStrategy.revocationStrategy() ); + assertEquals(NO_CHECKS, trustStrategy.revocationStrategy()); - assertSame( trustStrategy, trustStrategy.withoutCertificateRevocationChecks() ); - assertEquals( NO_CHECKS, trustStrategy.revocationStrategy() ); + assertSame(trustStrategy, trustStrategy.withoutCertificateRevocationChecks()); + assertEquals(NO_CHECKS, trustStrategy.revocationStrategy()); - assertSame( trustStrategy, trustStrategy.withStrictRevocationChecks() ); - assertEquals( STRICT, trustStrategy.revocationStrategy() ); + assertSame(trustStrategy, trustStrategy.withStrictRevocationChecks()); + assertEquals(STRICT, trustStrategy.revocationStrategy()); - assertSame( trustStrategy, trustStrategy.withVerifyIfPresentRevocationChecks() ); - assertEquals( VERIFY_IF_PRESENT, trustStrategy.revocationStrategy() ); + assertSame(trustStrategy, trustStrategy.withVerifyIfPresentRevocationChecks()); + assertEquals(VERIFY_IF_PRESENT, trustStrategy.revocationStrategy()); } @Test - void shouldAllowToConfigureResolver() - { - ServerAddressResolver resolver = mock( ServerAddressResolver.class ); - Config config = Config.builder().withResolver( resolver ).build(); + void shouldAllowToConfigureResolver() { + ServerAddressResolver resolver = mock(ServerAddressResolver.class); + Config config = Config.builder().withResolver(resolver).build(); - assertEquals( resolver, config.resolver() ); + assertEquals(resolver, config.resolver()); } @Test - void shouldNotAllowNullResolver() - { - assertThrows( NullPointerException.class, () -> Config.builder().withResolver( null ) ); + void shouldNotAllowNullResolver() { + assertThrows(NullPointerException.class, () -> Config.builder().withResolver(null)); } @Test - void shouldDefaultToDefaultFetchSize() - { + void shouldDefaultToDefaultFetchSize() { Config config = Config.defaultConfig(); - assertEquals( DEFAULT_FETCH_SIZE, config.fetchSize() ); + assertEquals(DEFAULT_FETCH_SIZE, config.fetchSize()); } @ParameterizedTest - @ValueSource( longs = {100, 1, 1000, Long.MAX_VALUE, -1} ) - void shouldChangeFetchSize( long value ) - { - Config config = Config.builder().withFetchSize( value ).build(); - assertEquals( value, config.fetchSize() ); + @ValueSource(longs = {100, 1, 1000, Long.MAX_VALUE, -1}) + void shouldChangeFetchSize(long value) { + Config config = Config.builder().withFetchSize(value).build(); + assertEquals(value, config.fetchSize()); } @ParameterizedTest - @ValueSource( longs = {0, -100, -2} ) - void shouldErrorWithIllegalFetchSize( long value ) - { - assertThrows( IllegalArgumentException.class, () -> Config.builder().withFetchSize( value ).build() ); + @ValueSource(longs = {0, -100, -2}) + void shouldErrorWithIllegalFetchSize(long value) { + assertThrows( + IllegalArgumentException.class, + () -> Config.builder().withFetchSize(value).build()); } @ParameterizedTest - @ValueSource( ints = {100, 1, 1000, Integer.MAX_VALUE} ) - void shouldChangeEventLoopThreads( int value ) - { - Config config = Config.builder().withEventLoopThreads( value ).build(); - assertEquals( value, config.eventLoopThreads() ); + @ValueSource(ints = {100, 1, 1000, Integer.MAX_VALUE}) + void shouldChangeEventLoopThreads(int value) { + Config config = Config.builder().withEventLoopThreads(value).build(); + assertEquals(value, config.eventLoopThreads()); } @ParameterizedTest - @ValueSource( ints = {0, -100, -2} ) - void shouldErrorWithIllegalEventLoopThreadsSize( int value ) - { - assertThrows( IllegalArgumentException.class, () -> Config.builder().withEventLoopThreads( value ).build() ); + @ValueSource(ints = {0, -100, -2}) + void shouldErrorWithIllegalEventLoopThreadsSize(int value) { + assertThrows( + IllegalArgumentException.class, + () -> Config.builder().withEventLoopThreads(value).build()); } @Test - void shouldChangeUserAgent() - { - Config config = Config.builder().withUserAgent( "AwesomeDriver" ).build(); - assertEquals( "AwesomeDriver", config.userAgent() ); + void shouldChangeUserAgent() { + Config config = Config.builder().withUserAgent("AwesomeDriver").build(); + assertEquals("AwesomeDriver", config.userAgent()); } @Test - void shouldErrorWithInvalidUserAgent() - { - assertThrows( IllegalArgumentException.class, () -> Config.builder().withUserAgent( null ).build() ); - assertThrows( IllegalArgumentException.class, () -> Config.builder().withUserAgent( "" ).build() ); + void shouldErrorWithInvalidUserAgent() { + assertThrows( + IllegalArgumentException.class, + () -> Config.builder().withUserAgent(null).build()); + assertThrows( + IllegalArgumentException.class, + () -> Config.builder().withUserAgent("").build()); } @Test - void shouldNotHaveMeterRegistryByDefault() - { + void shouldNotHaveMeterRegistryByDefault() { Config config = Config.builder().build(); MetricsAdapter metricsAdapter = config.metricsAdapter(); - assertEquals( MetricsAdapter.DEV_NULL, metricsAdapter ); - assertFalse( config.isMetricsEnabled() ); + assertEquals(MetricsAdapter.DEV_NULL, metricsAdapter); + assertFalse(config.isMetricsEnabled()); } @Test - void shouldNotAcceptNullMeterRegistry() - { + void shouldNotAcceptNullMeterRegistry() { Config.ConfigBuilder builder = Config.builder(); - assertThrows( NullPointerException.class, () -> builder.withMetricsAdapter( null ) ); + assertThrows(NullPointerException.class, () -> builder.withMetricsAdapter(null)); } @Test - void shouldSetMetricsAdapter() - { - Config config = Config.builder() - .withMetricsAdapter( MetricsAdapter.DEFAULT ) - .build(); + void shouldSetMetricsAdapter() { + Config config = + Config.builder().withMetricsAdapter(MetricsAdapter.DEFAULT).build(); MetricsAdapter metricsAdapter = config.metricsAdapter(); - assertEquals( MetricsAdapter.DEFAULT, metricsAdapter ); - assertTrue( config.isMetricsEnabled() ); + assertEquals(MetricsAdapter.DEFAULT, metricsAdapter); + assertTrue(config.isMetricsEnabled()); } @Nested - class SerializationTest - { + class SerializationTest { @Test - void shouldSerialize() throws Exception - { + void shouldSerialize() throws Exception { Config config = Config.builder() - .withMaxConnectionPoolSize( 123 ) - .withConnectionTimeout( 6543L, TimeUnit.MILLISECONDS ) - .withConnectionAcquisitionTimeout( 5432L, TimeUnit.MILLISECONDS ) - .withConnectionLivenessCheckTimeout( 4321L, TimeUnit.MILLISECONDS ) - .withMaxConnectionLifetime( 4711, TimeUnit.MILLISECONDS ) - .withMaxTransactionRetryTime( 3210L, TimeUnit.MILLISECONDS ) - .withFetchSize( 9876L ) - .withEventLoopThreads( 4 ) - .withoutEncryption() - .withTrustStrategy( Config.TrustStrategy.trustCustomCertificateSignedBy( new File( "doesntMatter" ) ) ) - .withUserAgent( "user-agent" ) - .withDriverMetrics() - .withRoutingTablePurgeDelay( 50000, TimeUnit.MILLISECONDS ) - .withLeakedSessionsLogging() - .withMetricsAdapter( MetricsAdapter.MICROMETER ) - .build(); - - Config verify = TestUtil.serializeAndReadBack( config, Config.class ); - - assertEquals( config.maxConnectionPoolSize(), verify.maxConnectionPoolSize() ); - assertEquals( config.connectionTimeoutMillis(), verify.connectionTimeoutMillis() ); - assertEquals( config.connectionAcquisitionTimeoutMillis(), verify.connectionAcquisitionTimeoutMillis() ); - assertEquals( config.idleTimeBeforeConnectionTest(), verify.idleTimeBeforeConnectionTest() ); - assertEquals( config.maxConnectionLifetimeMillis(), verify.maxConnectionLifetimeMillis() ); - assertNotNull( verify.retrySettings() ); - assertSame( DevNullLogging.DEV_NULL_LOGGING, verify.logging() ); - assertEquals( config.retrySettings().maxRetryTimeMs(), verify.retrySettings().maxRetryTimeMs() ); - assertEquals( config.fetchSize(), verify.fetchSize() ); - assertEquals( config.eventLoopThreads(), verify.eventLoopThreads() ); - assertEquals( config.encrypted(), verify.encrypted() ); - assertEquals( config.trustStrategy().strategy(), verify.trustStrategy().strategy() ); - assertEquals( config.trustStrategy().certFiles(), verify.trustStrategy().certFiles() ); - assertEquals( config.trustStrategy().isHostnameVerificationEnabled(), verify.trustStrategy().isHostnameVerificationEnabled() ); - assertEquals( config.trustStrategy().revocationStrategy(), verify.trustStrategy().revocationStrategy() ); - assertEquals( config.userAgent(), verify.userAgent() ); - assertEquals( config.isMetricsEnabled(), verify.isMetricsEnabled() ); - assertEquals( config.metricsAdapter(), verify.metricsAdapter() ); - assertEquals( config.routingSettings().routingTablePurgeDelayMs(), verify.routingSettings().routingTablePurgeDelayMs() ); - assertEquals( config.logLeakedSessions(), verify.logLeakedSessions() ); + .withMaxConnectionPoolSize(123) + .withConnectionTimeout(6543L, TimeUnit.MILLISECONDS) + .withConnectionAcquisitionTimeout(5432L, TimeUnit.MILLISECONDS) + .withConnectionLivenessCheckTimeout(4321L, TimeUnit.MILLISECONDS) + .withMaxConnectionLifetime(4711, TimeUnit.MILLISECONDS) + .withMaxTransactionRetryTime(3210L, TimeUnit.MILLISECONDS) + .withFetchSize(9876L) + .withEventLoopThreads(4) + .withoutEncryption() + .withTrustStrategy(Config.TrustStrategy.trustCustomCertificateSignedBy(new File("doesntMatter"))) + .withUserAgent("user-agent") + .withDriverMetrics() + .withRoutingTablePurgeDelay(50000, TimeUnit.MILLISECONDS) + .withLeakedSessionsLogging() + .withMetricsAdapter(MetricsAdapter.MICROMETER) + .build(); + + Config verify = TestUtil.serializeAndReadBack(config, Config.class); + + assertEquals(config.maxConnectionPoolSize(), verify.maxConnectionPoolSize()); + assertEquals(config.connectionTimeoutMillis(), verify.connectionTimeoutMillis()); + assertEquals(config.connectionAcquisitionTimeoutMillis(), verify.connectionAcquisitionTimeoutMillis()); + assertEquals(config.idleTimeBeforeConnectionTest(), verify.idleTimeBeforeConnectionTest()); + assertEquals(config.maxConnectionLifetimeMillis(), verify.maxConnectionLifetimeMillis()); + assertNotNull(verify.retrySettings()); + assertSame(DevNullLogging.DEV_NULL_LOGGING, verify.logging()); + assertEquals( + config.retrySettings().maxRetryTimeMs(), + verify.retrySettings().maxRetryTimeMs()); + assertEquals(config.fetchSize(), verify.fetchSize()); + assertEquals(config.eventLoopThreads(), verify.eventLoopThreads()); + assertEquals(config.encrypted(), verify.encrypted()); + assertEquals( + config.trustStrategy().strategy(), verify.trustStrategy().strategy()); + assertEquals( + config.trustStrategy().certFiles(), verify.trustStrategy().certFiles()); + assertEquals( + config.trustStrategy().isHostnameVerificationEnabled(), + verify.trustStrategy().isHostnameVerificationEnabled()); + assertEquals( + config.trustStrategy().revocationStrategy(), + verify.trustStrategy().revocationStrategy()); + assertEquals(config.userAgent(), verify.userAgent()); + assertEquals(config.isMetricsEnabled(), verify.isMetricsEnabled()); + assertEquals(config.metricsAdapter(), verify.metricsAdapter()); + assertEquals( + config.routingSettings().routingTablePurgeDelayMs(), + verify.routingSettings().routingTablePurgeDelayMs()); + assertEquals(config.logLeakedSessions(), verify.logLeakedSessions()); } @Test - void shouldSerializeSerializableLogging() throws IOException, ClassNotFoundException - { - Config config = Config.builder().withLogging( Logging.javaUtilLogging( Level.ALL ) ).build(); + void shouldSerializeSerializableLogging() throws IOException, ClassNotFoundException { + Config config = Config.builder() + .withLogging(Logging.javaUtilLogging(Level.ALL)) + .build(); - Config verify = TestUtil.serializeAndReadBack( config, Config.class ); + Config verify = TestUtil.serializeAndReadBack(config, Config.class); Logging logging = verify.logging(); - assertInstanceOf( JULogging.class, logging ); - - List loggingLevelFields = - ReflectionSupport.findFields( JULogging.class, f -> "loggingLevel".equals( f.getName() ), HierarchyTraversalMode.TOP_DOWN ); - assertFalse( loggingLevelFields.isEmpty() ); - loggingLevelFields.forEach( field -> - { - try - { - field.setAccessible( true ); - assertEquals( Level.ALL, field.get( logging ) ); - } - catch ( IllegalAccessException e ) - { - throw new RuntimeException( e ); + assertInstanceOf(JULogging.class, logging); + + List loggingLevelFields = ReflectionSupport.findFields( + JULogging.class, f -> "loggingLevel".equals(f.getName()), HierarchyTraversalMode.TOP_DOWN); + assertFalse(loggingLevelFields.isEmpty()); + loggingLevelFields.forEach(field -> { + try { + field.setAccessible(true); + assertEquals(Level.ALL, field.get(logging)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); } - } ); + }); } @ParameterizedTest - @ValueSource( classes = {DevNullLogging.class, JULogging.class, ConsoleLogging.class, Slf4jLogging.class} ) - void officialLoggingProvidersShouldBeSerializable( Class loggingClass ) - { - assertTrue( Serializable.class.isAssignableFrom( loggingClass ) ); + @ValueSource(classes = {DevNullLogging.class, JULogging.class, ConsoleLogging.class, Slf4jLogging.class}) + void officialLoggingProvidersShouldBeSerializable(Class loggingClass) { + assertTrue(Serializable.class.isAssignableFrom(loggingClass)); } } } diff --git a/driver/src/test/java/org/neo4j/driver/GraphDatabaseTest.java b/driver/src/test/java/org/neo4j/driver/GraphDatabaseTest.java index 8c6a928730..854bec853a 100644 --- a/driver/src/test/java/org/neo4j/driver/GraphDatabaseTest.java +++ b/driver/src/test/java/org/neo4j/driver/GraphDatabaseTest.java @@ -18,16 +18,29 @@ */ package org.neo4j.driver; -import io.netty.util.concurrent.EventExecutorGroup; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Logging.none; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import io.netty.util.concurrent.EventExecutorGroup; import java.io.IOException; import java.net.ServerSocket; import java.net.URI; import java.util.Arrays; import java.util.Iterator; import java.util.List; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DriverFactory; @@ -39,100 +52,69 @@ import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.util.TestUtil; -import static java.util.Arrays.asList; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Logging.none; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; - -class GraphDatabaseTest -{ - private static final Config INSECURE_CONFIG = Config.builder() - .withoutEncryption() - .withLogging( none() ) - .build(); +class GraphDatabaseTest { + private static final Config INSECURE_CONFIG = + Config.builder().withoutEncryption().withLogging(none()).build(); @Test - void throwsWhenBoltSchemeUsedWithRoutingParams() - { - assertThrows( IllegalArgumentException.class, () -> GraphDatabase.driver( "bolt://localhost:7687/?policy=my_policy" ) ); + void throwsWhenBoltSchemeUsedWithRoutingParams() { + assertThrows( + IllegalArgumentException.class, () -> GraphDatabase.driver("bolt://localhost:7687/?policy=my_policy")); } @Test - void shouldLogWhenUnableToCreateRoutingDriver() - { - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - InternalDriver driver = mock( InternalDriver.class ); - doThrow( ServiceUnavailableException.class ).when( driver ).verifyConnectivity(); - DriverFactory driverFactory = new MockSupplyingDriverFactory( Arrays.asList( driver, driver ) ); - Config config = Config.builder() - .withLogging( logging ) - .build(); - - List routingUris = asList( - URI.create( "neo4j://localhost:9001" ), - URI.create( "neo4j://localhost:9002" ) ); - - assertThrows( ServiceUnavailableException.class, () -> GraphDatabase.routingDriver( routingUris, AuthTokens.none(), config, driverFactory ) ); - - verify( logger ).warn( eq( "Unable to create routing driver for URI: neo4j://localhost:9001" ), - any( Throwable.class ) ); - - verify( logger ).warn( eq( "Unable to create routing driver for URI: neo4j://localhost:9002" ), - any( Throwable.class ) ); + void shouldLogWhenUnableToCreateRoutingDriver() { + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + InternalDriver driver = mock(InternalDriver.class); + doThrow(ServiceUnavailableException.class).when(driver).verifyConnectivity(); + DriverFactory driverFactory = new MockSupplyingDriverFactory(Arrays.asList(driver, driver)); + Config config = Config.builder().withLogging(logging).build(); + + List routingUris = asList(URI.create("neo4j://localhost:9001"), URI.create("neo4j://localhost:9002")); + + assertThrows( + ServiceUnavailableException.class, + () -> GraphDatabase.routingDriver(routingUris, AuthTokens.none(), config, driverFactory)); + + verify(logger) + .warn(eq("Unable to create routing driver for URI: neo4j://localhost:9001"), any(Throwable.class)); + + verify(logger) + .warn(eq("Unable to create routing driver for URI: neo4j://localhost:9002"), any(Throwable.class)); } @Test - void shouldNotFailRoutingDriverWhenThereIsWorkingUri() - { - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - InternalDriver failingDriver = mock( InternalDriver.class ); - doThrow( ServiceUnavailableException.class ).when( failingDriver ).verifyConnectivity(); - InternalDriver workingDriver = mock( InternalDriver.class ); - DriverFactory driverFactory = new MockSupplyingDriverFactory( Arrays.asList( failingDriver, workingDriver ) ); - Config config = Config.builder() - .withLogging( logging ) - .build(); - - List routingUris = asList( - URI.create( "neo4j://localhost:9001" ), - URI.create( "neo4j://localhost:9002" ) ); - - Driver driver = GraphDatabase.routingDriver( routingUris, AuthTokens.none(), config, driverFactory ); - - verify( logger ).warn( eq( "Unable to create routing driver for URI: neo4j://localhost:9001" ), - any( Throwable.class ) ); - assertEquals( driver, workingDriver ); + void shouldNotFailRoutingDriverWhenThereIsWorkingUri() { + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + InternalDriver failingDriver = mock(InternalDriver.class); + doThrow(ServiceUnavailableException.class).when(failingDriver).verifyConnectivity(); + InternalDriver workingDriver = mock(InternalDriver.class); + DriverFactory driverFactory = new MockSupplyingDriverFactory(Arrays.asList(failingDriver, workingDriver)); + Config config = Config.builder().withLogging(logging).build(); + + List routingUris = asList(URI.create("neo4j://localhost:9001"), URI.create("neo4j://localhost:9002")); + + Driver driver = GraphDatabase.routingDriver(routingUris, AuthTokens.none(), config, driverFactory); + + verify(logger) + .warn(eq("Unable to create routing driver for URI: neo4j://localhost:9001"), any(Throwable.class)); + assertEquals(driver, workingDriver); } @Test - void shouldRespondToInterruptsWhenConnectingToUnresponsiveServer() throws Exception - { - try ( ServerSocket serverSocket = new ServerSocket( 0 ) ) - { + void shouldRespondToInterruptsWhenConnectingToUnresponsiveServer() throws Exception { + try (ServerSocket serverSocket = new ServerSocket(0)) { // setup other thread to interrupt current thread when it blocks - TestUtil.interruptWhenInWaitingState( Thread.currentThread() ); + TestUtil.interruptWhenInWaitingState(Thread.currentThread()); - final Driver driver = GraphDatabase.driver( "bolt://localhost:" + serverSocket.getLocalPort() ); - try - { - assertThrows( ServiceUnavailableException.class, driver::verifyConnectivity ); - } - finally - { + final Driver driver = GraphDatabase.driver("bolt://localhost:" + serverSocket.getLocalPort()); + try { + assertThrows(ServiceUnavailableException.class, driver::verifyConnectivity); + } finally { // clear interrupted flag Thread.interrupted(); } @@ -140,89 +122,83 @@ void shouldRespondToInterruptsWhenConnectingToUnresponsiveServer() throws Except } @Test - void shouldPrintNiceErrorWhenConnectingToUnresponsiveServer() throws Exception - { + void shouldPrintNiceErrorWhenConnectingToUnresponsiveServer() throws Exception { int localPort = -1; - try ( ServerSocket serverSocket = new ServerSocket( 0 ) ) - { + try (ServerSocket serverSocket = new ServerSocket(0)) { localPort = serverSocket.getLocalPort(); } - final Driver driver = GraphDatabase.driver( "bolt://localhost:" + localPort, INSECURE_CONFIG ); - final ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, driver::verifyConnectivity ); - assertThat( error.getMessage(), containsString( "Unable to connect to" ) ); + final Driver driver = GraphDatabase.driver("bolt://localhost:" + localPort, INSECURE_CONFIG); + final ServiceUnavailableException error = + assertThrows(ServiceUnavailableException.class, driver::verifyConnectivity); + assertThat(error.getMessage(), containsString("Unable to connect to")); } @Test - void shouldPrintNiceRoutingErrorWhenConnectingToUnresponsiveServer() throws Exception - { + void shouldPrintNiceRoutingErrorWhenConnectingToUnresponsiveServer() throws Exception { int localPort = -1; - try ( ServerSocket serverSocket = new ServerSocket( 0 ) ) - { + try (ServerSocket serverSocket = new ServerSocket(0)) { localPort = serverSocket.getLocalPort(); } - final Driver driver = GraphDatabase.driver( "neo4j://localhost:" + localPort, INSECURE_CONFIG ); - final ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, driver::verifyConnectivity ); + final Driver driver = GraphDatabase.driver("neo4j://localhost:" + localPort, INSECURE_CONFIG); + final ServiceUnavailableException error = + assertThrows(ServiceUnavailableException.class, driver::verifyConnectivity); error.printStackTrace(); - assertThat( error.getMessage(), containsString( "Unable to connect to" ) ); + assertThat(error.getMessage(), containsString("Unable to connect to")); } @Test - void shouldFailToCreateUnencryptedDriverWhenServerDoesNotRespond() throws IOException - { - testFailureWhenServerDoesNotRespond( false ); + void shouldFailToCreateUnencryptedDriverWhenServerDoesNotRespond() throws IOException { + testFailureWhenServerDoesNotRespond(false); } @Test - void shouldFailToCreateEncryptedDriverWhenServerDoesNotRespond() throws IOException - { - testFailureWhenServerDoesNotRespond( true ); + void shouldFailToCreateEncryptedDriverWhenServerDoesNotRespond() throws IOException { + testFailureWhenServerDoesNotRespond(true); } - private static void testFailureWhenServerDoesNotRespond( boolean encrypted ) throws IOException - { - try ( ServerSocket server = new ServerSocket( 0 ) ) // server that accepts connections but does not reply + private static void testFailureWhenServerDoesNotRespond(boolean encrypted) throws IOException { + try (ServerSocket server = new ServerSocket(0)) // server that accepts connections but does not reply { int connectionTimeoutMillis = 1_000; - Config config = createConfig( encrypted, connectionTimeoutMillis ); - final Driver driver = GraphDatabase.driver( URI.create( "bolt://localhost:" + server.getLocalPort() ), config ); + Config config = createConfig(encrypted, connectionTimeoutMillis); + final Driver driver = GraphDatabase.driver(URI.create("bolt://localhost:" + server.getLocalPort()), config); - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, driver::verifyConnectivity ); - assertEquals( e.getMessage(), "Unable to establish connection in " + connectionTimeoutMillis + "ms" ); + ServiceUnavailableException e = assertThrows(ServiceUnavailableException.class, driver::verifyConnectivity); + assertEquals(e.getMessage(), "Unable to establish connection in " + connectionTimeoutMillis + "ms"); } } - private static Config createConfig( boolean encrypted, int timeoutMillis ) - { + private static Config createConfig(boolean encrypted, int timeoutMillis) { Config.ConfigBuilder configBuilder = Config.builder() - .withConnectionTimeout( timeoutMillis, MILLISECONDS ) - .withLogging( DEV_NULL_LOGGING ); + .withConnectionTimeout(timeoutMillis, MILLISECONDS) + .withLogging(DEV_NULL_LOGGING); - if ( encrypted ) - { + if (encrypted) { configBuilder.withEncryption(); - } - else - { + } else { configBuilder.withoutEncryption(); } return configBuilder.build(); } - private static class MockSupplyingDriverFactory extends DriverFactory - { + private static class MockSupplyingDriverFactory extends DriverFactory { private final Iterator driverIterator; - private MockSupplyingDriverFactory( List drivers ) - { + private MockSupplyingDriverFactory(List drivers) { driverIterator = drivers.iterator(); } @Override - protected InternalDriver createRoutingDriver( SecurityPlan securityPlan, BoltServerAddress address, ConnectionPool connectionPool, - EventExecutorGroup eventExecutorGroup, RoutingSettings routingSettings, RetryLogic retryLogic, - MetricsProvider metricsProvider, Config config ) - { + protected InternalDriver createRoutingDriver( + SecurityPlan securityPlan, + BoltServerAddress address, + ConnectionPool connectionPool, + EventExecutorGroup eventExecutorGroup, + RoutingSettings routingSettings, + RetryLogic retryLogic, + MetricsProvider metricsProvider, + Config config) { return driverIterator.next(); } } diff --git a/driver/src/test/java/org/neo4j/driver/ParametersTest.java b/driver/src/test/java/org/neo4j/driver/ParametersTest.java index 9358e7dbbc..65c30b03f8 100644 --- a/driver/src/test/java/org/neo4j/driver/ParametersTest.java +++ b/driver/src/test/java/org/neo4j/driver/ParametersTest.java @@ -18,20 +18,6 @@ */ package org.neo4j.driver; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.internal.DefaultBookmarkHolder; -import org.neo4j.driver.internal.InternalRecord; -import org.neo4j.driver.internal.InternalSession; -import org.neo4j.driver.internal.async.NetworkSession; -import org.neo4j.driver.internal.retry.RetryLogic; -import org.neo4j.driver.internal.spi.ConnectionProvider; - import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.hamcrest.Matchers.startsWith; @@ -48,70 +34,83 @@ import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -class ParametersTest -{ - static Stream addressesToParse() - { +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.internal.DefaultBookmarkHolder; +import org.neo4j.driver.internal.InternalRecord; +import org.neo4j.driver.internal.InternalSession; +import org.neo4j.driver.internal.async.NetworkSession; +import org.neo4j.driver.internal.retry.RetryLogic; +import org.neo4j.driver.internal.spi.ConnectionProvider; + +class ParametersTest { + static Stream addressesToParse() { return Stream.of( // Node - Arguments.of( emptyNodeValue(), "Nodes can't be used as parameters." ), - Arguments.of( emptyNodeValue().asNode(), "Nodes can't be used as parameters." ), + Arguments.of(emptyNodeValue(), "Nodes can't be used as parameters."), + Arguments.of(emptyNodeValue().asNode(), "Nodes can't be used as parameters."), // Relationship - Arguments.of( emptyRelationshipValue(), "Relationships can't be used as parameters." ), - Arguments.of( emptyRelationshipValue().asRelationship(), "Relationships can't be used as parameters." ), + Arguments.of(emptyRelationshipValue(), "Relationships can't be used as parameters."), + Arguments.of(emptyRelationshipValue().asRelationship(), "Relationships can't be used as parameters."), // Path - Arguments.of( filledPathValue(), "Paths can't be used as parameters." ), - Arguments.of( filledPathValue().asPath(), "Paths can't be used as parameters." ) - ); + Arguments.of(filledPathValue(), "Paths can't be used as parameters."), + Arguments.of(filledPathValue().asPath(), "Paths can't be used as parameters.")); } @ParameterizedTest - @MethodSource( "addressesToParse" ) - void shouldGiveHelpfulMessageOnMisalignedInput( Object obj, String expectedMsg ) - { - ClientException e = assertThrows( ClientException.class, () -> Values.parameters( "1", obj, "2" ) ); - assertThat( e.getMessage(), startsWith( "Parameters function requires an even number of arguments, alternating key and value." ) ); + @MethodSource("addressesToParse") + void shouldGiveHelpfulMessageOnMisalignedInput(Object obj, String expectedMsg) { + ClientException e = assertThrows(ClientException.class, () -> Values.parameters("1", obj, "2")); + assertThat( + e.getMessage(), + startsWith("Parameters function requires an even number of arguments, alternating key and value.")); } @ParameterizedTest - @MethodSource( "addressesToParse" ) - void shouldNotBePossibleToUseInvalidParameterTypesViaParameters( Object obj, String expectedMsg ) - { + @MethodSource("addressesToParse") + void shouldNotBePossibleToUseInvalidParameterTypesViaParameters(Object obj, String expectedMsg) { Session session = mockedSession(); - ClientException e = assertThrows( ClientException.class, () -> session.run( "RETURN {a}", parameters( "a", obj ) ) ); - assertEquals( expectedMsg, e.getMessage() ); + ClientException e = assertThrows(ClientException.class, () -> session.run("RETURN {a}", parameters("a", obj))); + assertEquals(expectedMsg, e.getMessage()); } @ParameterizedTest - @MethodSource( "addressesToParse" ) - void shouldNotBePossibleToUseInvalidParametersViaMap( Object obj, String expectedMsg ) - { + @MethodSource("addressesToParse") + void shouldNotBePossibleToUseInvalidParametersViaMap(Object obj, String expectedMsg) { Session session = mockedSession(); - ClientException e = assertThrows( ClientException.class, () -> session.run( "RETURN {a}", singletonMap( "a", obj ) ) ); - assertEquals( expectedMsg, e.getMessage() ); + ClientException e = + assertThrows(ClientException.class, () -> session.run("RETURN {a}", singletonMap("a", obj))); + assertEquals(expectedMsg, e.getMessage()); } @ParameterizedTest - @MethodSource( "addressesToParse" ) - void shouldNotBePossibleToUseInvalidParametersViaRecord( Object obj, String expectedMsg ) - { - assumeTrue( obj instanceof Value ); - Record record = new InternalRecord( singletonList( "a" ), new Value[]{(Value) obj} ); + @MethodSource("addressesToParse") + void shouldNotBePossibleToUseInvalidParametersViaRecord(Object obj, String expectedMsg) { + assumeTrue(obj instanceof Value); + Record record = new InternalRecord(singletonList("a"), new Value[] {(Value) obj}); Session session = mockedSession(); - ClientException e = assertThrows( ClientException.class, () -> session.run( "RETURN {a}", record ) ); - assertEquals( expectedMsg, e.getMessage() ); + ClientException e = assertThrows(ClientException.class, () -> session.run("RETURN {a}", record)); + assertEquals(expectedMsg, e.getMessage()); } - private Session mockedSession() - { - ConnectionProvider provider = mock( ConnectionProvider.class ); - RetryLogic retryLogic = mock( RetryLogic.class ); - NetworkSession session = - new NetworkSession( provider, retryLogic, defaultDatabase(), AccessMode.WRITE, new DefaultBookmarkHolder(), null, UNLIMITED_FETCH_SIZE, - DEV_NULL_LOGGING ); - return new InternalSession( session ); + private Session mockedSession() { + ConnectionProvider provider = mock(ConnectionProvider.class); + RetryLogic retryLogic = mock(RetryLogic.class); + NetworkSession session = new NetworkSession( + provider, + retryLogic, + defaultDatabase(), + AccessMode.WRITE, + new DefaultBookmarkHolder(), + null, + UNLIMITED_FETCH_SIZE, + DEV_NULL_LOGGING); + return new InternalSession(session); } } diff --git a/driver/src/test/java/org/neo4j/driver/QueryTest.java b/driver/src/test/java/org/neo4j/driver/QueryTest.java index 93e73e59c8..41132e46f1 100644 --- a/driver/src/test/java/org/neo4j/driver/QueryTest.java +++ b/driver/src/test/java/org/neo4j/driver/QueryTest.java @@ -18,111 +18,97 @@ */ package org.neo4j.driver; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.Map; - import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.neo4j.driver.Values.parameters; -class QueryTest -{ +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class QueryTest { @Test - void shouldConstructQueryWithParameters() - { + void shouldConstructQueryWithParameters() { // given String text = "MATCH (n) RETURN n"; // when - Query query = new Query( text, Values.EmptyMap ); + Query query = new Query(text, Values.EmptyMap); // then - assertThat( query.text(), equalTo( text ) ); - assertThat( query.parameters(), equalTo( Values.EmptyMap ) ); + assertThat(query.text(), equalTo(text)); + assertThat(query.parameters(), equalTo(Values.EmptyMap)); } @Test - void shouldConstructQueryWithNoParameters() - { + void shouldConstructQueryWithNoParameters() { // given String text = "MATCH (n) RETURN n"; // when - Query query = new Query( text ); + Query query = new Query(text); // then - assertThat( query.text(), equalTo( text ) ); - assertThat( query.parameters(), equalTo( Values.EmptyMap ) ); + assertThat(query.text(), equalTo(text)); + assertThat(query.parameters(), equalTo(Values.EmptyMap)); } @Test - void shouldUpdateQueryText() - { + void shouldUpdateQueryText() { // when - Query query = - new Query( "MATCH (n) RETURN n" ) - .withText( "BOO" ); + Query query = new Query("MATCH (n) RETURN n").withText("BOO"); // then - assertThat( query.text(), equalTo( "BOO" ) ); - assertThat( query.parameters(), equalTo( Values.EmptyMap ) ); + assertThat(query.text(), equalTo("BOO")); + assertThat(query.parameters(), equalTo(Values.EmptyMap)); } - @Test - void shouldReplaceQueryParameters() - { + void shouldReplaceQueryParameters() { // when String text = "MATCH (n) RETURN n"; - Value initialParameters = parameters( "a", 1, "b", 2 ); - Query query = new Query( "MATCH (n) RETURN n" ).withParameters( initialParameters ); + Value initialParameters = parameters("a", 1, "b", 2); + Query query = new Query("MATCH (n) RETURN n").withParameters(initialParameters); // then - assertThat( query.text(), equalTo( text ) ); - assertThat( query.parameters(), equalTo( initialParameters ) ); + assertThat(query.text(), equalTo(text)); + assertThat(query.parameters(), equalTo(initialParameters)); } @Test - void shouldReplaceMapParameters() - { + void shouldReplaceMapParameters() { // when String text = "MATCH (n) RETURN n"; Map parameters = new HashMap<>(); - parameters.put( "a", 1 ); - Query query = new Query( "MATCH (n) RETURN n" ).withParameters( parameters ); + parameters.put("a", 1); + Query query = new Query("MATCH (n) RETURN n").withParameters(parameters); // then - assertThat( query.text(), equalTo( text ) ); - assertThat( query.parameters(), equalTo( Values.value( parameters ) ) ); + assertThat(query.text(), equalTo(text)); + assertThat(query.parameters(), equalTo(Values.value(parameters))); } @Test - void shouldUpdateQueryParameters() - { + void shouldUpdateQueryParameters() { // when String text = "MATCH (n) RETURN n"; - Value initialParameters = parameters( "a", 1, "b", 2, "c", 3 ); - Query query = - new Query( "MATCH (n) RETURN n", initialParameters ) - .withUpdatedParameters( parameters( "a", 0, "b", Values.NULL ) ); + Value initialParameters = parameters("a", 1, "b", 2, "c", 3); + Query query = new Query("MATCH (n) RETURN n", initialParameters) + .withUpdatedParameters(parameters("a", 0, "b", Values.NULL)); // then - assertThat( query.text(), equalTo( text ) ); - assertThat( query.parameters(), equalTo( parameters( "a", 0, "c", 3 ) ) ); + assertThat(query.text(), equalTo(text)); + assertThat(query.parameters(), equalTo(parameters("a", 0, "c", 3))); } @Test - void shouldProhibitNullQuery() - { - assertThrows( IllegalArgumentException.class, () -> new Query( null ) ); + void shouldProhibitNullQuery() { + assertThrows(IllegalArgumentException.class, () -> new Query(null)); } @Test - void shouldProhibitEmptyQuery() - { - assertThrows( IllegalArgumentException.class, () -> new Query( "" ) ); + void shouldProhibitEmptyQuery() { + assertThrows(IllegalArgumentException.class, () -> new Query("")); } } diff --git a/driver/src/test/java/org/neo4j/driver/SessionConfigTest.java b/driver/src/test/java/org/neo4j/driver/SessionConfigTest.java index 62bb873bda..ad27a4eb0a 100644 --- a/driver/src/test/java/org/neo4j/driver/SessionConfigTest.java +++ b/driver/src/test/java/org/neo4j/driver/SessionConfigTest.java @@ -18,23 +18,6 @@ */ package org.neo4j.driver; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Stream; - -import org.neo4j.driver.util.TestUtil; - import static java.util.Collections.emptyList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -47,160 +30,174 @@ import static org.neo4j.driver.SessionConfig.defaultConfig; import static org.neo4j.driver.internal.InternalBookmark.parse; -class SessionConfigTest -{ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.neo4j.driver.util.TestUtil; + +class SessionConfigTest { @Test - void shouldReturnDefaultValues() - { + void shouldReturnDefaultValues() { SessionConfig config = defaultConfig(); - assertEquals( AccessMode.WRITE, config.defaultAccessMode() ); - assertFalse( config.database().isPresent() ); - assertNull( config.bookmarks() ); - assertFalse( config.fetchSize().isPresent() ); + assertEquals(AccessMode.WRITE, config.defaultAccessMode()); + assertFalse(config.database().isPresent()); + assertNull(config.bookmarks()); + assertFalse(config.fetchSize().isPresent()); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldChangeAccessMode( AccessMode mode ) - { - SessionConfig config = builder().withDefaultAccessMode( mode ).build(); - assertEquals( mode, config.defaultAccessMode() ); + @EnumSource(AccessMode.class) + void shouldChangeAccessMode(AccessMode mode) { + SessionConfig config = builder().withDefaultAccessMode(mode).build(); + assertEquals(mode, config.defaultAccessMode()); } @ParameterizedTest - @ValueSource( strings = {"foo", "data", "my awesome database", " "} ) - void shouldChangeDatabaseName( String databaseName ) - { - SessionConfig config = builder().withDatabase( databaseName ).build(); - assertTrue( config.database().isPresent() ); - assertEquals( databaseName, config.database().get() ); + @ValueSource(strings = {"foo", "data", "my awesome database", " "}) + void shouldChangeDatabaseName(String databaseName) { + SessionConfig config = builder().withDatabase(databaseName).build(); + assertTrue(config.database().isPresent()); + assertEquals(databaseName, config.database().get()); } @Test - void shouldNotAllowNullDatabaseName() - { - assertThrows( NullPointerException.class, () -> builder().withDatabase( null ) ); + void shouldNotAllowNullDatabaseName() { + assertThrows(NullPointerException.class, () -> builder().withDatabase(null)); } @ParameterizedTest @MethodSource("someConfigs") void nullDatabaseNameMustNotBreakEquals(SessionConfig config1, SessionConfig config2, boolean expectedEquals) { - assertEquals( config1.equals( config2 ), expectedEquals ); + assertEquals(config1.equals(config2), expectedEquals); } static Stream someConfigs() { return Stream.of( - arguments( SessionConfig.builder().build(), SessionConfig.builder().build(), true ), - arguments( SessionConfig.builder().withDatabase( "a" ).build(), SessionConfig.builder().build(), false ), - arguments( SessionConfig.builder().build(), SessionConfig.builder().withDatabase( "a" ).build(), false ), - arguments( SessionConfig.builder().withDatabase( "a" ).build(), SessionConfig.builder().withDatabase( "a" ).build(), true ) - ); + arguments( + SessionConfig.builder().build(), SessionConfig.builder().build(), true), + arguments( + SessionConfig.builder().withDatabase("a").build(), + SessionConfig.builder().build(), + false), + arguments( + SessionConfig.builder().build(), + SessionConfig.builder().withDatabase("a").build(), + false), + arguments( + SessionConfig.builder().withDatabase("a").build(), + SessionConfig.builder().withDatabase("a").build(), + true)); } @ParameterizedTest - @ValueSource( strings = {""} ) - void shouldForbiddenEmptyStringDatabaseName( String databaseName ) - { - IllegalArgumentException error = assertThrows( IllegalArgumentException.class, () -> builder().withDatabase( databaseName ) ); - assertTrue( error.getMessage().startsWith( "Illegal database name " ) ); + @ValueSource(strings = {""}) + void shouldForbiddenEmptyStringDatabaseName(String databaseName) { + IllegalArgumentException error = + assertThrows(IllegalArgumentException.class, () -> builder().withDatabase(databaseName)); + assertTrue(error.getMessage().startsWith("Illegal database name ")); } @Test - void shouldAcceptNullBookmarks() - { - SessionConfig config = builder().withBookmarks( (Bookmark[]) null ).build(); - assertNull( config.bookmarks() ); + void shouldAcceptNullBookmarks() { + SessionConfig config = builder().withBookmarks((Bookmark[]) null).build(); + assertNull(config.bookmarks()); - SessionConfig config2 = builder().withBookmarks( (List) null ).build(); - assertNull( config2.bookmarks() ); + SessionConfig config2 = builder().withBookmarks((List) null).build(); + assertNull(config2.bookmarks()); } @Test - void shouldAcceptEmptyBookmarks() - { + void shouldAcceptEmptyBookmarks() { SessionConfig config = builder().withBookmarks().build(); - assertEquals( emptyList(), config.bookmarks() ); + assertEquals(emptyList(), config.bookmarks()); - SessionConfig config2 = builder().withBookmarks( emptyList() ).build(); - assertEquals( emptyList(), config2.bookmarks() ); + SessionConfig config2 = builder().withBookmarks(emptyList()).build(); + assertEquals(emptyList(), config2.bookmarks()); } @Test - void shouldAcceptBookmarks() - { - Bookmark one = parse( "one" ); - Bookmark two = parse( "two" ); - SessionConfig config = builder().withBookmarks( one, two ).build(); - assertEquals( Arrays.asList( one, two ), config.bookmarks() ); - - SessionConfig config2 = builder().withBookmarks( Arrays.asList( one, two ) ).build(); - assertEquals( Arrays.asList( one, two ), config2.bookmarks() ); + void shouldAcceptBookmarks() { + Bookmark one = parse("one"); + Bookmark two = parse("two"); + SessionConfig config = builder().withBookmarks(one, two).build(); + assertEquals(Arrays.asList(one, two), config.bookmarks()); + + SessionConfig config2 = builder().withBookmarks(Arrays.asList(one, two)).build(); + assertEquals(Arrays.asList(one, two), config2.bookmarks()); } @Test - void shouldAcceptNullInBookmarks() - { - Bookmark one = parse( "one" ); - Bookmark two = parse( "two" ); - SessionConfig config = builder().withBookmarks( one, two, null ).build(); - assertEquals( Arrays.asList( one, two, null ), config.bookmarks() ); - - SessionConfig config2 = builder().withBookmarks( Arrays.asList( one, two, null ) ).build(); - assertEquals( Arrays.asList( one, two, null ), config2.bookmarks() ); + void shouldAcceptNullInBookmarks() { + Bookmark one = parse("one"); + Bookmark two = parse("two"); + SessionConfig config = builder().withBookmarks(one, two, null).build(); + assertEquals(Arrays.asList(one, two, null), config.bookmarks()); + + SessionConfig config2 = + builder().withBookmarks(Arrays.asList(one, two, null)).build(); + assertEquals(Arrays.asList(one, two, null), config2.bookmarks()); } @ParameterizedTest - @ValueSource( longs = {100, 1, 1000, Long.MAX_VALUE, -1} ) - void shouldChangeFetchSize( long value ) - { - SessionConfig config = builder().withFetchSize( value ).build(); - assertEquals( Optional.of( value ), config.fetchSize()); + @ValueSource(longs = {100, 1, 1000, Long.MAX_VALUE, -1}) + void shouldChangeFetchSize(long value) { + SessionConfig config = builder().withFetchSize(value).build(); + assertEquals(Optional.of(value), config.fetchSize()); } @ParameterizedTest - @ValueSource( longs = {0, -100, -2} ) - void shouldErrorWithIllegalFetchSize( long value ) - { - assertThrows( IllegalArgumentException.class, () -> builder().withFetchSize( value ).build() ); + @ValueSource(longs = {0, -100, -2}) + void shouldErrorWithIllegalFetchSize(long value) { + assertThrows( + IllegalArgumentException.class, + () -> builder().withFetchSize(value).build()); } @Test - void shouldTwoConfigBeEqual() - { - SessionConfig config1 = builder().withFetchSize( 100 ).build(); - SessionConfig config2 = builder().withFetchSize( 100 ).build(); + void shouldTwoConfigBeEqual() { + SessionConfig config1 = builder().withFetchSize(100).build(); + SessionConfig config2 = builder().withFetchSize(100).build(); - assertEquals( config1, config2 ); + assertEquals(config1, config2); } @Test - void shouldSerialize() throws Exception - { + void shouldSerialize() throws Exception { SessionConfig config = SessionConfig.builder() .withBookmarks( - Bookmark.from( new HashSet<>( Arrays.asList( "bookmarkA", "bookmarkB" ) ) ), - Bookmark.from( new HashSet<>( Arrays.asList( "bookmarkC", "bookmarkD" ) ) ) ) - .withDefaultAccessMode( AccessMode.WRITE ) - .withFetchSize( 54321L ) - .withDatabase( "testing" ) - .withImpersonatedUser( "impersonator" ) + Bookmark.from(new HashSet<>(Arrays.asList("bookmarkA", "bookmarkB"))), + Bookmark.from(new HashSet<>(Arrays.asList("bookmarkC", "bookmarkD")))) + .withDefaultAccessMode(AccessMode.WRITE) + .withFetchSize(54321L) + .withDatabase("testing") + .withImpersonatedUser("impersonator") .build(); - SessionConfig verify = TestUtil.serializeAndReadBack( config, SessionConfig.class ); + SessionConfig verify = TestUtil.serializeAndReadBack(config, SessionConfig.class); - assertNotNull( verify.bookmarks() ); + assertNotNull(verify.bookmarks()); List> bookmarks = new ArrayList<>(); - verify.bookmarks().forEach( b -> bookmarks.add( b.values() ) ); - assertEquals( 2, bookmarks.size() ); - assertTrue( bookmarks.get( 0 ).containsAll( Arrays.asList( "bookmarkA", "bookmarkB" ) ) ); - assertTrue( bookmarks.get( 1 ).containsAll( Arrays.asList( "bookmarkC", "bookmarkD" ) ) ); - - assertEquals( config.defaultAccessMode(), verify.defaultAccessMode() ); - assertEquals( config.fetchSize(), verify.fetchSize() ); - assertEquals( config.database(), verify.database() ); - assertEquals( config.impersonatedUser(), verify.impersonatedUser() ); + verify.bookmarks().forEach(b -> bookmarks.add(b.values())); + assertEquals(2, bookmarks.size()); + assertTrue(bookmarks.get(0).containsAll(Arrays.asList("bookmarkA", "bookmarkB"))); + assertTrue(bookmarks.get(1).containsAll(Arrays.asList("bookmarkC", "bookmarkD"))); + + assertEquals(config.defaultAccessMode(), verify.defaultAccessMode()); + assertEquals(config.fetchSize(), verify.fetchSize()); + assertEquals(config.database(), verify.database()); + assertEquals(config.impersonatedUser(), verify.impersonatedUser()); } } diff --git a/driver/src/test/java/org/neo4j/driver/TransactionConfigTest.java b/driver/src/test/java/org/neo4j/driver/TransactionConfigTest.java index 31740bdb82..378739c45d 100644 --- a/driver/src/test/java/org/neo4j/driver/TransactionConfigTest.java +++ b/driver/src/test/java/org/neo4j/driver/TransactionConfigTest.java @@ -18,135 +18,123 @@ */ package org.neo4j.driver; -import org.junit.jupiter.api.Test; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.Values.value; import java.time.Duration; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.InternalNode; import org.neo4j.driver.internal.InternalPath; import org.neo4j.driver.internal.InternalRelationship; -import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.util.TestUtil; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.Values.value; - -class TransactionConfigTest -{ +class TransactionConfigTest { @Test - void emptyConfigShouldHaveNoTimeout() - { - assertNull( TransactionConfig.empty().timeout() ); + void emptyConfigShouldHaveNoTimeout() { + assertNull(TransactionConfig.empty().timeout()); } @Test - void emptyConfigShouldHaveNoMetadata() - { - assertEquals( emptyMap(), TransactionConfig.empty().metadata() ); + void emptyConfigShouldHaveNoMetadata() { + assertEquals(emptyMap(), TransactionConfig.empty().metadata()); } @Test - void shouldDisallowNullTimeout() - { - assertThrows( NullPointerException.class, () -> TransactionConfig.builder().withTimeout( null ) ); + void shouldDisallowNullTimeout() { + assertThrows( + NullPointerException.class, () -> TransactionConfig.builder().withTimeout(null)); } @Test - void shouldDisallowZeroTimeout() - { - assertThrows( IllegalArgumentException.class, () -> TransactionConfig.builder().withTimeout( Duration.ZERO ) ); + void shouldDisallowZeroTimeout() { + assertThrows(IllegalArgumentException.class, () -> TransactionConfig.builder() + .withTimeout(Duration.ZERO)); } @Test - void shouldDisallowNegativeTimeout() - { - assertThrows( IllegalArgumentException.class, () -> TransactionConfig.builder().withTimeout( Duration.ofSeconds( -1 ) ) ); + void shouldDisallowNegativeTimeout() { + assertThrows(IllegalArgumentException.class, () -> TransactionConfig.builder() + .withTimeout(Duration.ofSeconds(-1))); } @Test - void shouldDisallowNullMetadata() - { - assertThrows( NullPointerException.class, () -> TransactionConfig.builder().withMetadata( null ) ); + void shouldDisallowNullMetadata() { + assertThrows( + NullPointerException.class, () -> TransactionConfig.builder().withMetadata(null)); } @Test - void shouldDisallowMetadataWithIllegalValues() - { - assertThrows( ClientException.class, - () -> TransactionConfig.builder().withMetadata( singletonMap( "key", new InternalNode( 1 ) ) ) ); + void shouldDisallowMetadataWithIllegalValues() { + assertThrows(ClientException.class, () -> TransactionConfig.builder() + .withMetadata(singletonMap("key", new InternalNode(1)))); - assertThrows( ClientException.class, - () -> TransactionConfig.builder().withMetadata( singletonMap( "key", new InternalRelationship( 1, 1, 1, "" ) ) ) ); + assertThrows(ClientException.class, () -> TransactionConfig.builder() + .withMetadata(singletonMap("key", new InternalRelationship(1, 1, 1, "")))); - assertThrows( ClientException.class, - () -> TransactionConfig.builder().withMetadata( singletonMap( "key", new InternalPath( new InternalNode( 1 ) ) ) ) ); + assertThrows(ClientException.class, () -> TransactionConfig.builder() + .withMetadata(singletonMap("key", new InternalPath(new InternalNode(1))))); } @Test - void shouldHaveTimeout() - { - TransactionConfig config = TransactionConfig.builder() - .withTimeout( Duration.ofSeconds( 3 ) ) - .build(); + void shouldHaveTimeout() { + TransactionConfig config = + TransactionConfig.builder().withTimeout(Duration.ofSeconds(3)).build(); - assertEquals( Duration.ofSeconds( 3 ), config.timeout() ); + assertEquals(Duration.ofSeconds(3), config.timeout()); } @Test - void shouldHaveMetadata() - { - Map map = new HashMap<>(); - map.put( "key1", "value1" ); - map.put( "key2", true ); - map.put( "key3", 42 ); + void shouldHaveMetadata() { + Map map = new HashMap<>(); + map.put("key1", "value1"); + map.put("key2", true); + map.put("key3", 42); - TransactionConfig config = TransactionConfig.builder() - .withMetadata( map ) - .build(); + TransactionConfig config = TransactionConfig.builder().withMetadata(map).build(); - Map metadata = config.metadata(); + Map metadata = config.metadata(); - assertEquals( 3, metadata.size() ); - assertEquals( value( "value1" ), metadata.get( "key1" ) ); - assertEquals( value( true ), metadata.get( "key2" ) ); - assertEquals( value( 42 ), metadata.get( "key3" ) ); + assertEquals(3, metadata.size()); + assertEquals(value("value1"), metadata.get("key1")); + assertEquals(value(true), metadata.get("key2")); + assertEquals(value(42), metadata.get("key3")); } @Test void shouldNotModifyMetadataAfterItIsSuppliedToBuilder() { - Map metadata = new HashMap<>(); - metadata.put( "key1", "value1" ); - metadata.put( "key2", true ); - metadata.put( "key3", 42 ); + Map metadata = new HashMap<>(); + metadata.put("key1", "value1"); + metadata.put("key2", true); + metadata.put("key3", 42); - TransactionConfig.Builder builder = TransactionConfig.builder().withMetadata( metadata ); - metadata.put( "key4", "what?" ); + TransactionConfig.Builder builder = TransactionConfig.builder().withMetadata(metadata); + metadata.put("key4", "what?"); TransactionConfig config = builder.build(); - assertEquals( 3, config.metadata().size() ); + assertEquals(3, config.metadata().size()); } @Test - void shouldSerialize() throws Exception - { - Map metadata = new HashMap<>(); - metadata.put( "key1", "value1" ); - metadata.put( "key2", true ); - metadata.put( "key3", 42 ); + void shouldSerialize() throws Exception { + Map metadata = new HashMap<>(); + metadata.put("key1", "value1"); + metadata.put("key2", true); + metadata.put("key3", 42); TransactionConfig config = TransactionConfig.builder() - .withTimeout( Duration.ofMillis(12345L) ) - .withMetadata( metadata ) + .withTimeout(Duration.ofMillis(12345L)) + .withMetadata(metadata) .build(); - TransactionConfig verify = TestUtil.serializeAndReadBack( config, TransactionConfig.class ); + TransactionConfig verify = TestUtil.serializeAndReadBack(config, TransactionConfig.class); assertEquals(config.timeout(), verify.timeout()); assertEquals(config.metadata(), verify.metadata()); diff --git a/driver/src/test/java/org/neo4j/driver/integration/BookmarkIT.java b/driver/src/test/java/org/neo4j/driver/integration/BookmarkIT.java index 606c874f4c..e33c21f102 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/BookmarkIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/BookmarkIT.java @@ -18,12 +18,20 @@ */ package org.neo4j.driver.integration; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.internal.InternalBookmark.parse; +import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkContainsSingleValue; +import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkIsEmpty; +import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarksContainsSingleUniqueValues; + +import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.UUID; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Driver; import org.neo4j.driver.Session; @@ -35,19 +43,8 @@ import org.neo4j.driver.util.ParallelizableIT; import org.neo4j.driver.util.SessionExtension; -import static org.hamcrest.Matchers.startsWith; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.internal.InternalBookmark.parse; -import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkContainsSingleValue; -import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkIsEmpty; -import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarksContainsSingleUniqueValues; - @ParallelizableIT -class BookmarkIT -{ +class BookmarkIT { @RegisterExtension static final SessionExtension sessionRule = new SessionExtension(); @@ -55,187 +52,163 @@ class BookmarkIT private Session session; @BeforeEach - void assumeBookmarkSupport() - { + void assumeBookmarkSupport() { driver = sessionRule.driver(); session = sessionRule; } @Test - @DisabledOnNeo4jWith( Neo4jFeature.BOLT_V4 ) - void shouldReceiveBookmarkOnSuccessfulCommit() throws Throwable - { + @DisabledOnNeo4jWith(Neo4jFeature.BOLT_V4) + void shouldReceiveBookmarkOnSuccessfulCommit() throws Throwable { // Given - assertBookmarkIsEmpty( session.lastBookmark() ); + assertBookmarkIsEmpty(session.lastBookmark()); // When - createNodeInTx( session ); + createNodeInTx(session); // Then - assertBookmarkContainsSingleValue( session.lastBookmark(), startsWith( "neo4j:bookmark:v1:tx" ) ); + assertBookmarkContainsSingleValue(session.lastBookmark(), startsWith("neo4j:bookmark:v1:tx")); } @Test - @EnabledOnNeo4jWith( Neo4jFeature.BOLT_V4 ) - void shouldReceiveNewBookmarkOnSuccessfulCommit() throws Throwable - { + @EnabledOnNeo4jWith(Neo4jFeature.BOLT_V4) + void shouldReceiveNewBookmarkOnSuccessfulCommit() throws Throwable { // Given Bookmark initialBookmark = session.lastBookmark(); - assertBookmarkIsEmpty( initialBookmark ); + assertBookmarkIsEmpty(initialBookmark); // When - createNodeInTx( session ); + createNodeInTx(session); // Then - assertBookmarkContainsSingleValue( session.lastBookmark() ); - assertNotEquals( initialBookmark, session.lastBookmark() ); + assertBookmarkContainsSingleValue(session.lastBookmark()); + assertNotEquals(initialBookmark, session.lastBookmark()); } @Test - void shouldThrowForInvalidBookmark() - { - Bookmark invalidBookmark = parse( "hi, this is an invalid bookmark" ); + void shouldThrowForInvalidBookmark() { + Bookmark invalidBookmark = parse("hi, this is an invalid bookmark"); - try ( Session session = driver.session( builder().withBookmarks( invalidBookmark ).build() ) ) - { - assertThrows( ClientException.class, session::beginTransaction ); + try (Session session = + driver.session(builder().withBookmarks(invalidBookmark).build())) { + assertThrows(ClientException.class, session::beginTransaction); } } @Test - void bookmarkRemainsAfterRolledBackTx() - { - assertBookmarkIsEmpty( session.lastBookmark() ); + void bookmarkRemainsAfterRolledBackTx() { + assertBookmarkIsEmpty(session.lastBookmark()); - createNodeInTx( session ); + createNodeInTx(session); Bookmark bookmark = session.lastBookmark(); - assertBookmarkContainsSingleValue( bookmark ); + assertBookmarkContainsSingleValue(bookmark); - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "CREATE (a:Person)" ); + try (Transaction tx = session.beginTransaction()) { + tx.run("CREATE (a:Person)"); tx.rollback(); } - assertEquals( bookmark, session.lastBookmark() ); + assertEquals(bookmark, session.lastBookmark()); } @Test - void bookmarkRemainsAfterTxFailure() - { - assertBookmarkIsEmpty( session.lastBookmark() ); + void bookmarkRemainsAfterTxFailure() { + assertBookmarkIsEmpty(session.lastBookmark()); - createNodeInTx( session ); + createNodeInTx(session); Bookmark bookmark = session.lastBookmark(); - assertBookmarkContainsSingleValue( bookmark ); + assertBookmarkContainsSingleValue(bookmark); Transaction tx = session.beginTransaction(); - assertThrows( ClientException.class, () -> tx.run( "RETURN" ) ); - assertEquals( bookmark, session.lastBookmark() ); + assertThrows(ClientException.class, () -> tx.run("RETURN")); + assertEquals(bookmark, session.lastBookmark()); } @Test - void bookmarkRemainsAfterSuccessfulSessionRun() - { - assertBookmarkIsEmpty( session.lastBookmark() ); + void bookmarkRemainsAfterSuccessfulSessionRun() { + assertBookmarkIsEmpty(session.lastBookmark()); - createNodeInTx( session ); + createNodeInTx(session); Bookmark bookmark = session.lastBookmark(); - assertBookmarkContainsSingleValue( bookmark ); + assertBookmarkContainsSingleValue(bookmark); - session.run( "RETURN 1" ).consume(); + session.run("RETURN 1").consume(); - assertEquals( bookmark, session.lastBookmark() ); + assertEquals(bookmark, session.lastBookmark()); } @Test - void bookmarkRemainsAfterFailedSessionRun() - { - assertBookmarkIsEmpty( session.lastBookmark() ); + void bookmarkRemainsAfterFailedSessionRun() { + assertBookmarkIsEmpty(session.lastBookmark()); - createNodeInTx( session ); + createNodeInTx(session); Bookmark bookmark = session.lastBookmark(); - assertBookmarkContainsSingleValue( bookmark ); + assertBookmarkContainsSingleValue(bookmark); - assertThrows( ClientException.class, () -> session.run( "RETURN" ).consume() ); - assertEquals( bookmark, session.lastBookmark() ); + assertThrows(ClientException.class, () -> session.run("RETURN").consume()); + assertEquals(bookmark, session.lastBookmark()); } @Test - void bookmarkIsUpdatedOnEveryCommittedTx() - { - assertBookmarkIsEmpty( session.lastBookmark() ); + void bookmarkIsUpdatedOnEveryCommittedTx() { + assertBookmarkIsEmpty(session.lastBookmark()); - createNodeInTx( session ); + createNodeInTx(session); Bookmark bookmark1 = session.lastBookmark(); - assertBookmarkContainsSingleValue( bookmark1 ); + assertBookmarkContainsSingleValue(bookmark1); - createNodeInTx( session ); + createNodeInTx(session); Bookmark bookmark2 = session.lastBookmark(); - assertBookmarkContainsSingleValue( bookmark2 ); + assertBookmarkContainsSingleValue(bookmark2); - createNodeInTx( session ); + createNodeInTx(session); Bookmark bookmark3 = session.lastBookmark(); - assertBookmarkContainsSingleValue( bookmark3 ); + assertBookmarkContainsSingleValue(bookmark3); - assertBookmarksContainsSingleUniqueValues( bookmark1, bookmark2, bookmark3 ); + assertBookmarksContainsSingleUniqueValues(bookmark1, bookmark2, bookmark3); } @Test - void createSessionWithInitialBookmark() - { - Bookmark bookmark = parse( "TheBookmark" ); - try ( Session session = driver.session( builder().withBookmarks( bookmark ).build() ) ) - { - assertEquals( bookmark, session.lastBookmark() ); + void createSessionWithInitialBookmark() { + Bookmark bookmark = parse("TheBookmark"); + try (Session session = driver.session(builder().withBookmarks(bookmark).build())) { + assertEquals(bookmark, session.lastBookmark()); } } @Test - void createSessionWithAccessModeAndInitialBookmark() - { - Bookmark bookmark = parse( "TheBookmark" ); - try ( Session session = driver.session( builder().withBookmarks( bookmark ).build() ) ) - { - assertEquals( bookmark, session.lastBookmark() ); + void createSessionWithAccessModeAndInitialBookmark() { + Bookmark bookmark = parse("TheBookmark"); + try (Session session = driver.session(builder().withBookmarks(bookmark).build())) { + assertEquals(bookmark, session.lastBookmark()); } } - private static void createNodeInTx( Session session ) - { - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "CREATE (a:Person)" ); + private static void createNodeInTx(Session session) { + try (Transaction tx = session.beginTransaction()) { + tx.run("CREATE (a:Person)"); tx.commit(); } } - private static boolean isUuid( String string ) - { - try - { - UUID.fromString( string ); - } - catch ( IllegalArgumentException | NullPointerException e ) - { + private static boolean isUuid(String string) { + try { + UUID.fromString(string); + } catch (IllegalArgumentException | NullPointerException e) { return false; } return true; } - private static boolean isNumeric( String string ) - { - try - { - Long.parseLong( string ); - } - catch ( NumberFormatException | NullPointerException e ) - { + private static boolean isNumeric(String string) { + try { + Long.parseLong(string); + } catch (NumberFormatException | NullPointerException e) { return false; } return true; diff --git a/driver/src/test/java/org/neo4j/driver/integration/ChannelConnectorImplIT.java b/driver/src/test/java/org/neo4j/driver/integration/ChannelConnectorImplIT.java index a939ebebde..1f2a1d6e9d 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ChannelConnectorImplIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ChannelConnectorImplIT.java @@ -18,16 +18,24 @@ */ package org.neo4j.driver.integration; +import static java.util.concurrent.CompletableFuture.runAsync; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.util.TestUtil.await; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelPipeline; import io.netty.handler.ssl.SslHandler; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - import java.io.IOException; import java.io.UncheckedIOException; import java.net.ServerSocket; @@ -35,7 +43,10 @@ import java.security.GeneralSecurityException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.exceptions.AuthenticationException; @@ -55,191 +66,162 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.util.concurrent.CompletableFuture.runAsync; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.util.TestUtil.await; - @ParallelizableIT -class ChannelConnectorImplIT -{ +class ChannelConnectorImplIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private Bootstrap bootstrap; @BeforeEach - void setUp() - { - bootstrap = BootstrapFactory.newBootstrap( 1 ); + void setUp() { + bootstrap = BootstrapFactory.newBootstrap(1); } @AfterEach - void tearDown() - { - if ( bootstrap != null ) - { + void tearDown() { + if (bootstrap != null) { bootstrap.config().group().shutdownGracefully().syncUninterruptibly(); } } @Test - void shouldConnect() throws Exception - { - ChannelConnector connector = newConnector( neo4j.authToken() ); + void shouldConnect() throws Exception { + ChannelConnector connector = newConnector(neo4j.authToken()); - ChannelFuture channelFuture = connector.connect( neo4j.address(), bootstrap ); - assertTrue( channelFuture.await( 10, TimeUnit.SECONDS ) ); + ChannelFuture channelFuture = connector.connect(neo4j.address(), bootstrap); + assertTrue(channelFuture.await(10, TimeUnit.SECONDS)); Channel channel = channelFuture.channel(); - assertNull( channelFuture.get() ); - assertTrue( channel.isActive() ); + assertNull(channelFuture.get()); + assertTrue(channel.isActive()); } @Test - void shouldSetupHandlers() throws Exception - { - ChannelConnector connector = newConnector( neo4j.authToken(), trustAllCertificates(), 10_000 ); + void shouldSetupHandlers() throws Exception { + ChannelConnector connector = newConnector(neo4j.authToken(), trustAllCertificates(), 10_000); - ChannelFuture channelFuture = connector.connect( neo4j.address(), bootstrap ); - assertTrue( channelFuture.await( 10, TimeUnit.SECONDS ) ); + ChannelFuture channelFuture = connector.connect(neo4j.address(), bootstrap); + assertTrue(channelFuture.await(10, TimeUnit.SECONDS)); Channel channel = channelFuture.channel(); ChannelPipeline pipeline = channel.pipeline(); - assertTrue( channel.isActive() ); + assertTrue(channel.isActive()); - assertNotNull( pipeline.get( SslHandler.class ) ); - assertNull( pipeline.get( ConnectTimeoutHandler.class ) ); + assertNotNull(pipeline.get(SslHandler.class)); + assertNull(pipeline.get(ConnectTimeoutHandler.class)); } @Test - void shouldFailToConnectToWrongAddress() throws Exception - { - ChannelConnector connector = newConnector( neo4j.authToken() ); + void shouldFailToConnectToWrongAddress() throws Exception { + ChannelConnector connector = newConnector(neo4j.authToken()); - ChannelFuture channelFuture = connector.connect( new BoltServerAddress( "wrong-localhost" ), bootstrap ); - assertTrue( channelFuture.await( 10, TimeUnit.SECONDS ) ); + ChannelFuture channelFuture = connector.connect(new BoltServerAddress("wrong-localhost"), bootstrap); + assertTrue(channelFuture.await(10, TimeUnit.SECONDS)); Channel channel = channelFuture.channel(); - ExecutionException e = assertThrows( ExecutionException.class, channelFuture::get ); + ExecutionException e = assertThrows(ExecutionException.class, channelFuture::get); - assertThat( e.getCause(), instanceOf( ServiceUnavailableException.class ) ); - assertThat( e.getCause().getMessage(), startsWith( "Unable to connect" ) ); - assertFalse( channel.isActive() ); + assertThat(e.getCause(), instanceOf(ServiceUnavailableException.class)); + assertThat(e.getCause().getMessage(), startsWith("Unable to connect")); + assertFalse(channel.isActive()); } @Test - void shouldFailToConnectWithWrongCredentials() throws Exception - { - AuthToken authToken = AuthTokens.basic( "neo4j", "wrong-password" ); - ChannelConnector connector = newConnector( authToken ); + void shouldFailToConnectWithWrongCredentials() throws Exception { + AuthToken authToken = AuthTokens.basic("neo4j", "wrong-password"); + ChannelConnector connector = newConnector(authToken); - ChannelFuture channelFuture = connector.connect( neo4j.address(), bootstrap ); - assertTrue( channelFuture.await( 10, TimeUnit.SECONDS ) ); + ChannelFuture channelFuture = connector.connect(neo4j.address(), bootstrap); + assertTrue(channelFuture.await(10, TimeUnit.SECONDS)); Channel channel = channelFuture.channel(); - ExecutionException e = assertThrows( ExecutionException.class, channelFuture::get ); - assertThat( e.getCause(), instanceOf( AuthenticationException.class ) ); - assertFalse( channel.isActive() ); + ExecutionException e = assertThrows(ExecutionException.class, channelFuture::get); + assertThat(e.getCause(), instanceOf(AuthenticationException.class)); + assertFalse(channel.isActive()); } @Test - void shouldEnforceConnectTimeout() throws Exception - { - ChannelConnector connector = newConnector( neo4j.authToken(), 1000 ); + void shouldEnforceConnectTimeout() throws Exception { + ChannelConnector connector = newConnector(neo4j.authToken(), 1000); // try connect to a non-routable ip address 10.0.0.0, it will never respond - ChannelFuture channelFuture = connector.connect( new BoltServerAddress( "10.0.0.0" ), bootstrap ); + ChannelFuture channelFuture = connector.connect(new BoltServerAddress("10.0.0.0"), bootstrap); - assertThrows( ServiceUnavailableException.class, () -> await( channelFuture ) ); + assertThrows(ServiceUnavailableException.class, () -> await(channelFuture)); } @Test - void shouldFailWhenProtocolNegotiationTakesTooLong() throws Exception - { + void shouldFailWhenProtocolNegotiationTakesTooLong() throws Exception { // run without TLS so that Bolt handshake is the very first operation after connection is established - testReadTimeoutOnConnect( SecurityPlanImpl.insecure() ); + testReadTimeoutOnConnect(SecurityPlanImpl.insecure()); } @Test - void shouldFailWhenTLSHandshakeTakesTooLong() throws Exception - { + void shouldFailWhenTLSHandshakeTakesTooLong() throws Exception { // run with TLS so that TLS handshake is the very first operation after connection is established - testReadTimeoutOnConnect( trustAllCertificates() ); + testReadTimeoutOnConnect(trustAllCertificates()); } @Test - void shouldThrowServiceUnavailableExceptionOnFailureDuringConnect() throws Exception - { - ServerSocket server = new ServerSocket( 0 ); - BoltServerAddress address = new BoltServerAddress( "localhost", server.getLocalPort() ); + void shouldThrowServiceUnavailableExceptionOnFailureDuringConnect() throws Exception { + ServerSocket server = new ServerSocket(0); + BoltServerAddress address = new BoltServerAddress("localhost", server.getLocalPort()); - runAsync( () -> - { - try - { + runAsync(() -> { + try { // wait for a connection Socket socket = server.accept(); // and terminate it immediately so that client gets a "reset by peer" IOException socket.close(); server.close(); + } catch (IOException e) { + throw new UncheckedIOException(e); } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } ); + }); - ChannelConnector connector = newConnector( neo4j.authToken() ); - ChannelFuture channelFuture = connector.connect( address, bootstrap ); + ChannelConnector connector = newConnector(neo4j.authToken()); + ChannelFuture channelFuture = connector.connect(address, bootstrap); // connect operation should fail with ServiceUnavailableException - assertThrows( ServiceUnavailableException.class, () -> await( channelFuture ) ); + assertThrows(ServiceUnavailableException.class, () -> await(channelFuture)); } - private void testReadTimeoutOnConnect( SecurityPlan securityPlan ) throws IOException - { - try ( ServerSocket server = new ServerSocket( 0 ) ) // server that accepts connections but does not reply + private void testReadTimeoutOnConnect(SecurityPlan securityPlan) throws IOException { + try (ServerSocket server = new ServerSocket(0)) // server that accepts connections but does not reply { int timeoutMillis = 1_000; - BoltServerAddress address = new BoltServerAddress( "localhost", server.getLocalPort() ); - ChannelConnector connector = newConnector( neo4j.authToken(), securityPlan, timeoutMillis ); + BoltServerAddress address = new BoltServerAddress("localhost", server.getLocalPort()); + ChannelConnector connector = newConnector(neo4j.authToken(), securityPlan, timeoutMillis); - ChannelFuture channelFuture = connector.connect( address, bootstrap ); + ChannelFuture channelFuture = connector.connect(address, bootstrap); - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, () -> await( channelFuture ) ); - assertEquals( e.getMessage(), "Unable to establish connection in " + timeoutMillis + "ms" ); + ServiceUnavailableException e = assertThrows(ServiceUnavailableException.class, () -> await(channelFuture)); + assertEquals(e.getMessage(), "Unable to establish connection in " + timeoutMillis + "ms"); } } - private ChannelConnectorImpl newConnector( AuthToken authToken ) throws Exception - { - return newConnector( authToken, Integer.MAX_VALUE ); + private ChannelConnectorImpl newConnector(AuthToken authToken) throws Exception { + return newConnector(authToken, Integer.MAX_VALUE); } - private ChannelConnectorImpl newConnector( AuthToken authToken, int connectTimeoutMillis ) throws Exception - { - return newConnector( authToken, trustAllCertificates(), connectTimeoutMillis ); + private ChannelConnectorImpl newConnector(AuthToken authToken, int connectTimeoutMillis) throws Exception { + return newConnector(authToken, trustAllCertificates(), connectTimeoutMillis); } - private ChannelConnectorImpl newConnector( AuthToken authToken, SecurityPlan securityPlan, - int connectTimeoutMillis ) - { - ConnectionSettings settings = new ConnectionSettings( authToken, "test", connectTimeoutMillis ); - return new ChannelConnectorImpl( settings, securityPlan, DEV_NULL_LOGGING, new FakeClock(), RoutingContext.EMPTY, - DefaultDomainNameResolver.getInstance() ); + private ChannelConnectorImpl newConnector( + AuthToken authToken, SecurityPlan securityPlan, int connectTimeoutMillis) { + ConnectionSettings settings = new ConnectionSettings(authToken, "test", connectTimeoutMillis); + return new ChannelConnectorImpl( + settings, + securityPlan, + DEV_NULL_LOGGING, + new FakeClock(), + RoutingContext.EMPTY, + DefaultDomainNameResolver.getInstance()); } - private static SecurityPlan trustAllCertificates() throws GeneralSecurityException - { - return SecurityPlanImpl.forAllCertificates( false, RevocationStrategy.NO_CHECKS ); + private static SecurityPlan trustAllCertificates() throws GeneralSecurityException { + return SecurityPlanImpl.forAllCertificates(false, RevocationStrategy.NO_CHECKS); } } 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 551910430b..ae3f48b72e 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ConnectionHandlingIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ConnectionHandlingIT.java @@ -18,23 +18,33 @@ */ package org.neo4j.driver.integration; -import io.netty.bootstrap.Bootstrap; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.Mockito; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; +import static org.neo4j.driver.util.TestUtil.await; +import io.netty.bootstrap.Bootstrap; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.Mockito; import org.neo4j.driver.AuthToken; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @@ -53,8 +63,8 @@ import org.neo4j.driver.internal.async.pool.PoolSettings; import org.neo4j.driver.internal.cluster.RoutingContext; import org.neo4j.driver.internal.cluster.RoutingSettings; -import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.internal.metrics.DevNullMetricsListener; +import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.internal.retry.RetrySettings; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.security.SecurityPlanImpl; @@ -68,26 +78,13 @@ import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; - -import static java.util.Collections.singletonList; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; -import static org.neo4j.driver.util.TestUtil.await; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; @ParallelizableIT -class ConnectionHandlingIT -{ +class ConnectionHandlingIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @@ -95,432 +92,414 @@ class ConnectionHandlingIT private MemorizingConnectionPool connectionPool; @BeforeEach - void createDriver() - { + void createDriver() { DriverFactoryWithConnectionPool driverFactory = new DriverFactoryWithConnectionPool(); AuthToken auth = neo4j.authToken(); RoutingSettings routingSettings = RoutingSettings.DEFAULT; RetrySettings retrySettings = RetrySettings.DEFAULT; - driver = driverFactory - .newInstance( neo4j.uri(), auth, routingSettings, retrySettings, Config.builder().withFetchSize( 1 ).build(), SecurityPlanImpl.insecure() ); + driver = driverFactory.newInstance( + neo4j.uri(), + auth, + routingSettings, + retrySettings, + Config.builder().withFetchSize(1).build(), + SecurityPlanImpl.insecure()); connectionPool = driverFactory.connectionPool; connectionPool.startMemorizing(); // start memorizing connections after driver creation } @AfterEach - void closeDriver() - { + void closeDriver() { driver.close(); } @Test - void connectionUsedForSessionRunReturnedToThePoolWhenResultConsumed() - { - Result result = createNodesInNewSession( 12 ); + void connectionUsedForSessionRunReturnedToThePoolWhenResultConsumed() { + Result result = createNodesInNewSession(12); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); result.consume(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1 ).release(); + assertSame(connection1, connection2); + verify(connection1).release(); } @Test - void connectionUsedForSessionRunReturnedToThePoolWhenResultSummaryObtained() - { - Result result = createNodesInNewSession( 5 ); + void connectionUsedForSessionRunReturnedToThePoolWhenResultSummaryObtained() { + Result result = createNodesInNewSession(5); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); ResultSummary summary = result.consume(); - assertEquals( 5, summary.counters().nodesCreated() ); + assertEquals(5, summary.counters().nodesCreated()); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1 ).release(); + assertSame(connection1, connection2); + verify(connection1).release(); } @Test - void connectionUsedForSessionRunReturnedToThePoolWhenResultFetchedInList() - { - Result result = createNodesInNewSession( 2 ); + void connectionUsedForSessionRunReturnedToThePoolWhenResultFetchedInList() { + Result result = createNodesInNewSession(2); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); List records = result.list(); - assertEquals( 2, records.size() ); + assertEquals(2, records.size()); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1 ).release(); + assertSame(connection1, connection2); + verify(connection1).release(); } @Test - void connectionUsedForSessionRunReturnedToThePoolWhenSingleRecordFetched() - { - Result result = createNodesInNewSession( 1 ); + void connectionUsedForSessionRunReturnedToThePoolWhenSingleRecordFetched() { + Result result = createNodesInNewSession(1); - assertNotNull( result.single() ); + assertNotNull(result.single()); Connection connection = connectionPool.lastAcquiredConnectionSpy; - verify( connection ).release(); + verify(connection).release(); } @Test - void connectionUsedForSessionRunReturnedToThePoolWhenResultFetchedAsIterator() - { - Result result = createNodesInNewSession( 6 ); + void connectionUsedForSessionRunReturnedToThePoolWhenResultFetchedAsIterator() { + Result result = createNodesInNewSession(6); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); int seenRecords = 0; - while ( result.hasNext() ) - { - assertNotNull( result.next() ); + while (result.hasNext()) { + assertNotNull(result.next()); seenRecords++; } - assertEquals( 6, seenRecords ); + assertEquals(6, seenRecords); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1 ).release(); + assertSame(connection1, connection2); + verify(connection1).release(); } @Test - void connectionUsedForSessionRunReturnedToThePoolOnServerFailure() - { - try ( Session session = driver.session() ) - { + void connectionUsedForSessionRunReturnedToThePoolOnServerFailure() { + try (Session session = driver.session()) { // provoke division by zero - assertThrows( ClientException.class, () -> session.run( "UNWIND range(10, -1, 0) AS i CREATE (n {index: 10/i}) RETURN n" ).consume() ); + assertThrows(ClientException.class, () -> session.run( + "UNWIND range(10, -1, 0) AS i CREATE (n {index: 10/i}) RETURN n") + .consume()); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1 ).release(); + verify(connection1).release(); } } @Test - void connectionUsedForTransactionReturnedToThePoolWhenTransactionCommitted() - { + void connectionUsedForTransactionReturnedToThePoolWhenTransactionCommitted() { Session session = driver.session(); Transaction tx = session.beginTransaction(); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); - Result result = createNodes( 5, tx ); + Result result = createNodes(5, tx); int size = result.list().size(); tx.commit(); tx.close(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1 ).release(); + assertSame(connection1, connection2); + verify(connection1).release(); - assertEquals( 5, size ); + assertEquals(5, size); } @Test - void connectionUsedForTransactionReturnedToThePoolWhenTransactionRolledBack() - { + void connectionUsedForTransactionReturnedToThePoolWhenTransactionRolledBack() { Session session = driver.session(); Transaction tx = session.beginTransaction(); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); - Result result = createNodes( 8, tx ); + Result result = createNodes(8, tx); int size = result.list().size(); tx.rollback(); tx.close(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1 ).release(); + assertSame(connection1, connection2); + verify(connection1).release(); - assertEquals( 8, size ); + assertEquals(8, size); } @Test - void connectionUsedForTransactionReturnedToThePoolWhenTransactionFailsToCommitted() - { - try ( Session session = driver.session() ) - { - session.run( "CREATE CONSTRAINT ON (book:Library) ASSERT exists(book.isbn)" ); + void connectionUsedForTransactionReturnedToThePoolWhenTransactionFailsToCommitted() { + try (Session session = driver.session()) { + session.run("CREATE CONSTRAINT ON (book:Library) ASSERT exists(book.isbn)"); } Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, atLeastOnce() ).release(); // connection used for constraint creation + verify(connection1, atLeastOnce()).release(); // connection used for constraint creation Session session = driver.session(); Transaction tx = session.beginTransaction(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - verify( connection2, never() ).release(); + verify(connection2, never()).release(); // property existence constraints are verified on commit, try to violate it - tx.run( "CREATE (:Library)" ); + tx.run("CREATE (:Library)"); - assertThrows( ClientException.class, tx::commit ); + assertThrows(ClientException.class, tx::commit); // connection should have been released after failed node creation - verify( connection2 ).release(); + verify(connection2).release(); } @Test - void connectionUsedForSessionRunReturnedToThePoolWhenSessionClose() - { + void connectionUsedForSessionRunReturnedToThePoolWhenSessionClose() { Session session = driver.session(); - createNodes( 12, session ); + createNodes(12, session); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); session.close(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1, times( 2 ) ).release(); + assertSame(connection1, connection2); + verify(connection1, times(2)).release(); } @Test - void connectionUsedForBeginTxReturnedToThePoolWhenSessionClose() - { + void connectionUsedForBeginTxReturnedToThePoolWhenSessionClose() { Session session = driver.session(); Transaction tx = session.beginTransaction(); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); session.close(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1, times( 2 ) ).release(); + assertSame(connection1, connection2); + verify(connection1, times(2)).release(); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void sessionCloseShouldReleaseConnectionUsedBySessionRun() - { + @EnabledOnNeo4jWith(BOLT_V4) + void sessionCloseShouldReleaseConnectionUsedBySessionRun() { RxSession session = driver.rxSession(); - RxResult res = session.run( "UNWIND [1,2,3,4] AS a RETURN a" ); + RxResult res = session.run("UNWIND [1,2,3,4] AS a RETURN a"); // When we only run but not pull - StepVerifier.create( Flux.from( res.keys() ) ).expectNext( singletonList( "a" ) ).verifyComplete(); + StepVerifier.create(Flux.from(res.keys())) + .expectNext(singletonList("a")) + .verifyComplete(); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); // Then we shall discard all results and commit - StepVerifier.create( Mono.from( session.close() ) ).verifyComplete(); + StepVerifier.create(Mono.from(session.close())).verifyComplete(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1, times( 2 ) ).release(); + assertSame(connection1, connection2); + verify(connection1, times(2)).release(); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void resultRecordsShouldReleaseConnectionUsedBySessionRun() - { + @EnabledOnNeo4jWith(BOLT_V4) + void resultRecordsShouldReleaseConnectionUsedBySessionRun() { RxSession session = driver.rxSession(); - RxResult res = session.run( "UNWIND [1,2,3,4] AS a RETURN a" ); + RxResult res = session.run("UNWIND [1,2,3,4] AS a RETURN a"); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - assertNull( connection1 ); + assertNull(connection1); // When we run and pull - StepVerifier.create( Flux.from( res.records() ).map( record -> record.get( "a" ).asInt() ) ) - .expectNext( 1, 2, 3, 4 ).verifyComplete(); + StepVerifier.create( + Flux.from(res.records()).map(record -> record.get("a").asInt())) + .expectNext(1, 2, 3, 4) + .verifyComplete(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertNotSame( connection1, connection2 ); - verify( connection2 ).release(); + assertNotSame(connection1, connection2); + verify(connection2).release(); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void resultSummaryShouldReleaseConnectionUsedBySessionRun() - { + @EnabledOnNeo4jWith(BOLT_V4) + void resultSummaryShouldReleaseConnectionUsedBySessionRun() { RxSession session = driver.rxSession(); - RxResult res = session.run( "UNWIND [1,2,3,4] AS a RETURN a" ); + RxResult res = session.run("UNWIND [1,2,3,4] AS a RETURN a"); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - assertNull( connection1 ); + assertNull(connection1); - StepVerifier.create( Mono.from( res.consume() ) ).expectNextCount( 1 ).verifyComplete(); + StepVerifier.create(Mono.from(res.consume())).expectNextCount(1).verifyComplete(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertNotSame( connection1, connection2 ); - verify( connection2 ).release(); + assertNotSame(connection1, connection2); + verify(connection2).release(); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void txCommitShouldReleaseConnectionUsedByBeginTx() - { + @EnabledOnNeo4jWith(BOLT_V4) + void txCommitShouldReleaseConnectionUsedByBeginTx() { AtomicReference connection1Ref = new AtomicReference<>(); - Function> sessionToRecordPublisher = ( RxSession session ) -> Flux.usingWhen( - Mono.fromDirect( session.beginTransaction() ), - tx -> - { - connection1Ref.set( connectionPool.lastAcquiredConnectionSpy ); - verify( connection1Ref.get(), never() ).release(); - return tx.run( "UNWIND [1,2,3,4] AS a RETURN a" ).records(); + Function> sessionToRecordPublisher = (RxSession session) -> Flux.usingWhen( + Mono.fromDirect(session.beginTransaction()), + tx -> { + connection1Ref.set(connectionPool.lastAcquiredConnectionSpy); + verify(connection1Ref.get(), never()).release(); + return tx.run("UNWIND [1,2,3,4] AS a RETURN a").records(); }, RxTransaction::commit, - ( tx, error ) -> tx.rollback(), - RxTransaction::rollback - ); + (tx, error) -> tx.rollback(), + RxTransaction::rollback); Flux resultsFlux = Flux.usingWhen( - Mono.fromSupplier( driver::rxSession ), - sessionToRecordPublisher, - session -> - { - Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1Ref.get(), connection2 ); - verify( connection1Ref.get() ).release(); - return Mono.empty(); - }, - ( session, error ) -> session.close(), - RxSession::close - ).map( record -> record.get( "a" ).asInt() ); - - StepVerifier.create( resultsFlux ) - .expectNext( 1, 2, 3, 4 ) - .expectComplete() - .verify(); + Mono.fromSupplier(driver::rxSession), + sessionToRecordPublisher, + session -> { + Connection connection2 = connectionPool.lastAcquiredConnectionSpy; + assertSame(connection1Ref.get(), connection2); + verify(connection1Ref.get()).release(); + return Mono.empty(); + }, + (session, error) -> session.close(), + RxSession::close) + .map(record -> record.get("a").asInt()); + + StepVerifier.create(resultsFlux).expectNext(1, 2, 3, 4).expectComplete().verify(); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void txRollbackShouldReleaseConnectionUsedByBeginTx() - { + @EnabledOnNeo4jWith(BOLT_V4) + void txRollbackShouldReleaseConnectionUsedByBeginTx() { AtomicReference connection1Ref = new AtomicReference<>(); - Function> sessionToRecordPublisher = ( RxSession session ) -> Flux.usingWhen( - Mono.fromDirect( session.beginTransaction() ), - tx -> - { - connection1Ref.set( connectionPool.lastAcquiredConnectionSpy ); - verify( connection1Ref.get(), never() ).release(); - return tx.run( "UNWIND [1,2,3,4] AS a RETURN a" ).records(); + Function> sessionToRecordPublisher = (RxSession session) -> Flux.usingWhen( + Mono.fromDirect(session.beginTransaction()), + tx -> { + connection1Ref.set(connectionPool.lastAcquiredConnectionSpy); + verify(connection1Ref.get(), never()).release(); + return tx.run("UNWIND [1,2,3,4] AS a RETURN a").records(); }, RxTransaction::rollback, - ( tx, error ) -> tx.rollback(), - RxTransaction::rollback - ); + (tx, error) -> tx.rollback(), + RxTransaction::rollback); Flux resultsFlux = Flux.usingWhen( - Mono.fromSupplier( driver::rxSession ), - sessionToRecordPublisher, - session -> - { - Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1Ref.get(), connection2 ); - verify( connection1Ref.get() ).release(); - return Mono.empty(); - }, - ( session, error ) -> session.close(), - RxSession::close - ).map( record -> record.get( "a" ).asInt() ); - - StepVerifier.create( resultsFlux ) - .expectNext( 1, 2, 3, 4 ) - .expectComplete() - .verify(); + Mono.fromSupplier(driver::rxSession), + sessionToRecordPublisher, + session -> { + Connection connection2 = connectionPool.lastAcquiredConnectionSpy; + assertSame(connection1Ref.get(), connection2); + verify(connection1Ref.get()).release(); + return Mono.empty(); + }, + (session, error) -> session.close(), + RxSession::close) + .map(record -> record.get("a").asInt()); + + StepVerifier.create(resultsFlux).expectNext(1, 2, 3, 4).expectComplete().verify(); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void sessionCloseShouldReleaseConnectionUsedByBeginTx() - { + @EnabledOnNeo4jWith(BOLT_V4) + void sessionCloseShouldReleaseConnectionUsedByBeginTx() { // Given RxSession session = driver.rxSession(); Publisher tx = session.beginTransaction(); // When we created a tx - StepVerifier.create( Mono.from( tx ) ).expectNextCount( 1 ).verifyComplete(); + StepVerifier.create(Mono.from(tx)).expectNextCount(1).verifyComplete(); Connection connection1 = connectionPool.lastAcquiredConnectionSpy; - verify( connection1, never() ).release(); + verify(connection1, never()).release(); // Then we shall discard all results and commit - StepVerifier.create( Mono.from( session.close() ) ).verifyComplete(); + StepVerifier.create(Mono.from(session.close())).verifyComplete(); Connection connection2 = connectionPool.lastAcquiredConnectionSpy; - assertSame( connection1, connection2 ); - verify( connection1, times( 2 ) ).release(); + assertSame(connection1, connection2); + verify(connection1, times(2)).release(); } - private Result createNodesInNewSession(int nodesToCreate ) - { - return createNodes( nodesToCreate, driver.session() ); + private Result createNodesInNewSession(int nodesToCreate) { + return createNodes(nodesToCreate, driver.session()); } - private Result createNodes(int nodesToCreate, QueryRunner queryRunner) - { - return queryRunner.run( "UNWIND range(1, $nodesToCreate) AS i CREATE (n {index: i}) RETURN n", - parameters( "nodesToCreate", nodesToCreate ) ); + private Result createNodes(int nodesToCreate, QueryRunner queryRunner) { + return queryRunner.run( + "UNWIND range(1, $nodesToCreate) AS i CREATE (n {index: i}) RETURN n", + parameters("nodesToCreate", nodesToCreate)); } - private static class DriverFactoryWithConnectionPool extends DriverFactory - { + private static class DriverFactoryWithConnectionPool extends DriverFactory { MemorizingConnectionPool connectionPool; @Override - protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, - MetricsProvider ignored, Config config, boolean ownsEventLoopGroup, - RoutingContext routingContext ) - { - ConnectionSettings connectionSettings = new ConnectionSettings( authToken, "test", 1000 ); - PoolSettings poolSettings = new PoolSettings( config.maxConnectionPoolSize(), - config.connectionAcquisitionTimeoutMillis(), config.maxConnectionLifetimeMillis(), - config.idleTimeBeforeConnectionTest() ); + protected ConnectionPool createConnectionPool( + AuthToken authToken, + SecurityPlan securityPlan, + Bootstrap bootstrap, + MetricsProvider ignored, + Config config, + boolean ownsEventLoopGroup, + RoutingContext routingContext) { + ConnectionSettings connectionSettings = new ConnectionSettings(authToken, "test", 1000); + PoolSettings poolSettings = new PoolSettings( + config.maxConnectionPoolSize(), + config.connectionAcquisitionTimeoutMillis(), + config.maxConnectionLifetimeMillis(), + config.idleTimeBeforeConnectionTest()); Clock clock = createClock(); - ChannelConnector connector = super.createConnector( connectionSettings, securityPlan, config, clock, routingContext ); - connectionPool = new MemorizingConnectionPool( connector, bootstrap, poolSettings, config.logging(), clock, ownsEventLoopGroup ); + ChannelConnector connector = + super.createConnector(connectionSettings, securityPlan, config, clock, routingContext); + connectionPool = new MemorizingConnectionPool( + connector, bootstrap, poolSettings, config.logging(), clock, ownsEventLoopGroup); return connectionPool; } } - private static class MemorizingConnectionPool extends ConnectionPoolImpl - { + private static class MemorizingConnectionPool extends ConnectionPoolImpl { Connection lastAcquiredConnectionSpy; boolean memorize; - MemorizingConnectionPool( ChannelConnector connector, Bootstrap bootstrap, PoolSettings settings, - Logging logging, Clock clock, boolean ownsEventLoopGroup ) - { - super( connector, bootstrap, settings, DevNullMetricsListener.INSTANCE, logging, clock, ownsEventLoopGroup ); + MemorizingConnectionPool( + ChannelConnector connector, + Bootstrap bootstrap, + PoolSettings settings, + Logging logging, + Clock clock, + boolean ownsEventLoopGroup) { + super(connector, bootstrap, settings, DevNullMetricsListener.INSTANCE, logging, clock, ownsEventLoopGroup); } - void startMemorizing() - { + void startMemorizing() { memorize = true; } @Override - public CompletionStage acquire( final BoltServerAddress address ) - { - Connection connection = await( super.acquire( address ) ); + public CompletionStage acquire(final BoltServerAddress address) { + Connection connection = await(super.acquire(address)); - if ( memorize ) - { + if (memorize) { // this connection pool returns spies so spies will be returned to the pool // prevent spying on spies... - if ( !Mockito.mockingDetails( connection ).isSpy() ) - { - connection = spy( connection ); + if (!Mockito.mockingDetails(connection).isSpy()) { + connection = spy(connection); } lastAcquiredConnectionSpy = connection; } - return CompletableFuture.completedFuture( connection ); + return CompletableFuture.completedFuture(connection); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/ConnectionPoolIT.java b/driver/src/test/java/org/neo4j/driver/integration/ConnectionPoolIT.java index cfb0d2e544..02b849ae19 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ConnectionPoolIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ConnectionPoolIT.java @@ -18,16 +18,25 @@ */ package org.neo4j.driver.integration; -import io.netty.channel.Channel; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.neo4j.driver.internal.retry.RetrySettings.DEFAULT; +import static org.neo4j.driver.internal.util.Matchers.connectionAcquisitionTimeoutError; +import io.netty.channel.Channel; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; @@ -42,20 +51,8 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import static org.neo4j.driver.internal.retry.RetrySettings.DEFAULT; -import static org.neo4j.driver.internal.util.Matchers.connectionAcquisitionTimeoutError; - @ParallelizableIT -class ConnectionPoolIT -{ +class ConnectionPoolIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @@ -63,148 +60,132 @@ class ConnectionPoolIT private SessionGrabber sessionGrabber; @AfterEach - void cleanup() throws Exception - { - if ( driver != null ) - { + void cleanup() throws Exception { + if (driver != null) { driver.close(); } - if ( sessionGrabber != null ) - { + if (sessionGrabber != null) { sessionGrabber.stop(); } } @Test - void shouldRecoverFromDownedServer() throws Throwable - { + void shouldRecoverFromDownedServer() throws Throwable { // Given a driver - driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken() ); + driver = GraphDatabase.driver(neo4j.uri(), neo4j.authToken()); // and given I'm heavily using it to acquire and release sessions - sessionGrabber = new SessionGrabber( driver ); + sessionGrabber = new SessionGrabber(driver); sessionGrabber.start(); // When neo4j.forceRestartDb(); // Then we accept a hump with failing sessions, but demand that failures stop as soon as the server is back up. - sessionGrabber.assertSessionsAvailableWithin( 120 ); + sessionGrabber.assertSessionsAvailableWithin(120); } @Test - void shouldDisposeChannelsBasedOnMaxLifetime() throws Exception - { + void shouldDisposeChannelsBasedOnMaxLifetime() throws Exception { FakeClock clock = new FakeClock(); - ChannelTrackingDriverFactory driverFactory = new ChannelTrackingDriverFactory( clock ); + ChannelTrackingDriverFactory driverFactory = new ChannelTrackingDriverFactory(clock); int maxConnLifetimeHours = 3; - Config config = Config.builder().withMaxConnectionLifetime( maxConnLifetimeHours, TimeUnit.HOURS ).build(); - driver = driverFactory.newInstance( neo4j.uri(), neo4j.authToken(), RoutingSettings.DEFAULT, DEFAULT, config, SecurityPlanImpl.insecure() ); + Config config = Config.builder() + .withMaxConnectionLifetime(maxConnLifetimeHours, TimeUnit.HOURS) + .build(); + driver = driverFactory.newInstance( + neo4j.uri(), neo4j.authToken(), RoutingSettings.DEFAULT, DEFAULT, config, SecurityPlanImpl.insecure()); // force driver create channel and return it to the pool - startAndCloseTransactions( driver, 1 ); + startAndCloseTransactions(driver, 1); // verify that channel was created, it should be open and idle in the pool List channels1 = driverFactory.channels(); - assertEquals( 1, channels1.size() ); - assertTrue( channels1.get( 0 ).isActive() ); + assertEquals(1, channels1.size()); + assertTrue(channels1.get(0).isActive()); // await channel to be returned to the pool - awaitNoActiveChannels( driverFactory, 20, SECONDS ); + awaitNoActiveChannels(driverFactory, 20, SECONDS); // move the clock forward so that idle channel seem too old - clock.progress( TimeUnit.HOURS.toMillis( maxConnLifetimeHours + 1 ) ); + clock.progress(TimeUnit.HOURS.toMillis(maxConnLifetimeHours + 1)); // force driver to acquire new connection and put it back to the pool - startAndCloseTransactions( driver, 1 ); + startAndCloseTransactions(driver, 1); // old existing channel should not be reused because it is too old List channels2 = driverFactory.channels(); - assertEquals( 2, channels2.size() ); + assertEquals(2, channels2.size()); - Channel channel1 = channels2.get( 0 ); - Channel channel2 = channels2.get( 1 ); + Channel channel1 = channels2.get(0); + Channel channel2 = channels2.get(1); // old existing should be closed in reasonable time - assertTrue( channel1.closeFuture().await( 20, SECONDS ) ); - assertFalse( channel1.isActive() ); + assertTrue(channel1.closeFuture().await(20, SECONDS)); + assertFalse(channel1.isActive()); // new channel should remain open and idle in the pool - assertTrue( channel2.isActive() ); + assertTrue(channel2.isActive()); } @Test - void shouldRespectMaxConnectionPoolSize() - { + void shouldRespectMaxConnectionPoolSize() { int maxPoolSize = 3; Config config = Config.builder() - .withMaxConnectionPoolSize( maxPoolSize ) - .withConnectionAcquisitionTimeout( 542, TimeUnit.MILLISECONDS ) - .withEventLoopThreads( 1 ) + .withMaxConnectionPoolSize(maxPoolSize) + .withConnectionAcquisitionTimeout(542, TimeUnit.MILLISECONDS) + .withEventLoopThreads(1) .build(); - driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), config ); - - ClientException e = assertThrows( ClientException.class, () -> startAndCloseTransactions( driver, maxPoolSize + 1 ) ); - assertThat( e, is( connectionAcquisitionTimeoutError( 542 ) ) ); + driver = GraphDatabase.driver(neo4j.uri(), neo4j.authToken(), config); + ClientException e = + assertThrows(ClientException.class, () -> startAndCloseTransactions(driver, maxPoolSize + 1)); + assertThat(e, is(connectionAcquisitionTimeoutError(542))); } - private static void startAndCloseTransactions( Driver driver, int txCount ) - { - List sessions = new ArrayList<>( txCount ); - List transactions = new ArrayList<>( txCount ); - List results = new ArrayList<>( txCount ); - try - { - for ( int i = 0; i < txCount; i++ ) - { + private static void startAndCloseTransactions(Driver driver, int txCount) { + List sessions = new ArrayList<>(txCount); + List transactions = new ArrayList<>(txCount); + List results = new ArrayList<>(txCount); + try { + for (int i = 0; i < txCount; i++) { Session session = driver.session(); - sessions.add( session ); + sessions.add(session); Transaction tx = session.beginTransaction(); - transactions.add( tx ); + transactions.add(tx); - Result result = tx.run( "RETURN 1" ); - results.add( result ); + Result result = tx.run("RETURN 1"); + results.add(result); } - } - finally - { - for ( Result result : results ) - { + } finally { + for (Result result : results) { result.consume(); } - for ( Transaction tx : transactions ) - { + for (Transaction tx : transactions) { tx.commit(); } - for ( Session session : sessions ) - { + for (Session session : sessions) { session.close(); } } } - private void awaitNoActiveChannels( ChannelTrackingDriverFactory driverFactory, long value, TimeUnit unit ) - throws InterruptedException - { - long deadline = System.currentTimeMillis() + unit.toMillis( value ); + private void awaitNoActiveChannels(ChannelTrackingDriverFactory driverFactory, long value, TimeUnit unit) + throws InterruptedException { + long deadline = System.currentTimeMillis() + unit.toMillis(value); int activeChannels = -1; - while ( System.currentTimeMillis() < deadline ) - { - activeChannels = driverFactory.activeChannels( neo4j.address() ); - if ( activeChannels == 0 ) - { + while (System.currentTimeMillis() < deadline) { + activeChannels = driverFactory.activeChannels(neo4j.address()); + if (activeChannels == 0) { return; - } - else - { - Thread.sleep( 100 ); + } else { + Thread.sleep(100); } } - throw new AssertionError( "Active channels present: " + activeChannels ); + throw new AssertionError("Active channels present: " + activeChannels); } /** @@ -213,83 +194,66 @@ private void awaitNoActiveChannels( ChannelTrackingDriverFactory driverFactory, * * This can thus be used to judge the state of the driver - is it currently healthy or not? */ - private class SessionGrabber implements Runnable - { + private class SessionGrabber implements Runnable { private final Driver driver; - private final CountDownLatch stopped = new CountDownLatch( 1 ); + private final CountDownLatch stopped = new CountDownLatch(1); private volatile boolean sessionsAreAvailable = false; private volatile boolean run = true; private volatile Throwable lastExceptionFromDriver; private final int sleepTimeout = 100; - SessionGrabber( Driver driver ) - { + SessionGrabber(Driver driver) { this.driver = driver; } - public void start() - { - new Thread( this ).start(); + public void start() { + new Thread(this).start(); } @Override - public void run() - { - try - { - while ( run ) - { - try - { + public void run() { + try { + while (run) { + try { // Try and launch 8 concurrent sessions - startAndCloseTransactions( driver, 8 ); + startAndCloseTransactions(driver, 8); // Success! We created 8 sessions without failures sessionsAreAvailable = true; - } - catch ( Throwable e ) - { + } catch (Throwable e) { lastExceptionFromDriver = e; sessionsAreAvailable = false; } - try - { - Thread.sleep( sleepTimeout ); - } - catch ( InterruptedException e ) - { - throw new RuntimeException( e ); + try { + Thread.sleep(sleepTimeout); + } catch (InterruptedException e) { + throw new RuntimeException(e); } } - } finally - { + } finally { stopped.countDown(); } } - void assertSessionsAvailableWithin( int timeoutSeconds ) throws InterruptedException - { + void assertSessionsAvailableWithin(int timeoutSeconds) throws InterruptedException { long deadline = System.currentTimeMillis() + 1000 * timeoutSeconds; - while( System.currentTimeMillis() < deadline ) - { - if( sessionsAreAvailable ) - { + while (System.currentTimeMillis() < deadline) { + if (sessionsAreAvailable) { // Success! return; } - Thread.sleep( sleepTimeout ); + Thread.sleep(sleepTimeout); } // Failure - timeout :( lastExceptionFromDriver.printStackTrace(); - fail( "sessions did not become available from the driver after the db restart within the specified " + - "timeout. Last failure was: " + lastExceptionFromDriver.getMessage() ); + fail("sessions did not become available from the driver after the db restart within the specified " + + "timeout. Last failure was: " + lastExceptionFromDriver.getMessage()); } - public void stop() throws InterruptedException - { + public void stop() throws InterruptedException { run = false; - stopped.await( 10, SECONDS ); + stopped.await(10, SECONDS); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/CredentialsIT.java b/driver/src/test/java/org/neo4j/driver/integration/CredentialsIT.java index ad8c7ded2c..c5d2777878 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/CredentialsIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/CredentialsIT.java @@ -18,14 +18,23 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Collections.singletonMap; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.AuthTokens.basic; +import static org.neo4j.driver.AuthTokens.custom; +import static org.neo4j.driver.Values.ofValue; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.util.Neo4jRunner.PASSWORD; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Map; - -import org.neo4j.driver.internal.security.InternalAuthToken; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; @@ -35,151 +44,122 @@ import org.neo4j.driver.Value; import org.neo4j.driver.exceptions.AuthenticationException; import org.neo4j.driver.exceptions.SecurityException; +import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.util.DisabledOnNeo4jWith; import org.neo4j.driver.internal.util.Neo4jFeature; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.Neo4jSettings; import org.neo4j.driver.util.ParallelizableIT; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.AuthTokens.basic; -import static org.neo4j.driver.AuthTokens.custom; -import static org.neo4j.driver.Values.ofValue; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.util.Neo4jRunner.PASSWORD; @ParallelizableIT -class CredentialsIT -{ +class CredentialsIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - @DisabledOnNeo4jWith( Neo4jFeature.BOLT_V4 ) + @DisabledOnNeo4jWith(Neo4jFeature.BOLT_V4) // This feature is removed in 4.0 - void shouldBePossibleToChangePassword() throws Exception - { + void shouldBePossibleToChangePassword() throws Exception { String newPassword = "secret"; - String tmpDataDir = Files.createTempDirectory( Paths.get( "target" ), "tmp" ).toAbsolutePath().toString().replace( "\\", "/" ); + String tmpDataDir = Files.createTempDirectory(Paths.get("target"), "tmp") + .toAbsolutePath() + .toString() + .replace("\\", "/"); - neo4j.restartDb( Neo4jSettings.TEST_SETTINGS - .updateWith( Neo4jSettings.DATA_DIR, tmpDataDir ) ); + neo4j.restartDb(Neo4jSettings.TEST_SETTINGS.updateWith(Neo4jSettings.DATA_DIR, tmpDataDir)); - AuthToken authToken = new InternalAuthToken( parameters( - "scheme", "basic", - "principal", "neo4j", - "credentials", "neo4j", - "new_credentials", newPassword ).asMap( ofValue() ) ); + AuthToken authToken = new InternalAuthToken(parameters( + "scheme", "basic", + "principal", "neo4j", + "credentials", "neo4j", + "new_credentials", newPassword) + .asMap(ofValue())); // change the password - try ( Driver driver = GraphDatabase.driver( neo4j.uri(), authToken ); - Session session = driver.session() ) - { - session.run( "RETURN 1" ).consume(); + try (Driver driver = GraphDatabase.driver(neo4j.uri(), authToken); + Session session = driver.session()) { + session.run("RETURN 1").consume(); } // verify old password does not work - final Driver badDriver = GraphDatabase.driver( CredentialsIT.neo4j.uri(), basic( "neo4j", PASSWORD ) ); - assertThrows( AuthenticationException.class, badDriver::verifyConnectivity ); + final Driver badDriver = GraphDatabase.driver(CredentialsIT.neo4j.uri(), basic("neo4j", PASSWORD)); + assertThrows(AuthenticationException.class, badDriver::verifyConnectivity); // verify new password works - try ( Driver driver = GraphDatabase.driver( CredentialsIT.neo4j.uri(), AuthTokens.basic( "neo4j", newPassword ) ); - Session session = driver.session() ) - { - session.run( "RETURN 2" ).consume(); + try (Driver driver = GraphDatabase.driver(CredentialsIT.neo4j.uri(), AuthTokens.basic("neo4j", newPassword)); + Session session = driver.session()) { + session.run("RETURN 2").consume(); } } @Test - void basicCredentialsShouldWork() - { + void basicCredentialsShouldWork() { // When & Then - try( Driver driver = GraphDatabase.driver( neo4j.uri(), - basic( "neo4j", PASSWORD ) ); - Session session = driver.session() ) - { - Value single = session.run( "RETURN 1" ).single().get( 0 ); - assertThat( single.asLong(), equalTo( 1L ) ); + try (Driver driver = GraphDatabase.driver(neo4j.uri(), basic("neo4j", PASSWORD)); + Session session = driver.session()) { + Value single = session.run("RETURN 1").single().get(0); + assertThat(single.asLong(), equalTo(1L)); } } @Test - void shouldGetHelpfulErrorOnInvalidCredentials() - { - SecurityException e = assertThrows( SecurityException.class, () -> - { - try ( Driver driver = GraphDatabase.driver( neo4j.uri(), basic( "thisisnotthepassword", PASSWORD ) ); - Session session = driver.session() ) - { - session.run( "RETURN 1" ); + void shouldGetHelpfulErrorOnInvalidCredentials() { + SecurityException e = assertThrows(SecurityException.class, () -> { + try (Driver driver = GraphDatabase.driver(neo4j.uri(), basic("thisisnotthepassword", PASSWORD)); + Session session = driver.session()) { + session.run("RETURN 1"); } - } ); - assertThat( e.getMessage(), containsString( "The client is unauthorized due to authentication failure." ) ); + }); + assertThat(e.getMessage(), containsString("The client is unauthorized due to authentication failure.")); } @Test - void shouldBeAbleToProvideRealmWithBasicAuth() - { + void shouldBeAbleToProvideRealmWithBasicAuth() { // When & Then - try( Driver driver = GraphDatabase.driver( neo4j.uri(), - basic( "neo4j", PASSWORD, "native" ) ); - Session session = driver.session() ) - { - Value single = session.run( "CREATE () RETURN 1" ).single().get( 0 ); - assertThat( single.asLong(), equalTo( 1L ) ); + try (Driver driver = GraphDatabase.driver(neo4j.uri(), basic("neo4j", PASSWORD, "native")); + Session session = driver.session()) { + Value single = session.run("CREATE () RETURN 1").single().get(0); + assertThat(single.asLong(), equalTo(1L)); } } @Test - void shouldBeAbleToConnectWithCustomToken() - { + void shouldBeAbleToConnectWithCustomToken() { // When & Then - try( Driver driver = GraphDatabase.driver( neo4j.uri(), - custom( "neo4j", PASSWORD, "native", "basic" ) ); - Session session = driver.session() ) - { - Value single = session.run( "CREATE () RETURN 1" ).single().get( 0 ); - assertThat( single.asLong(), equalTo( 1L ) ); + try (Driver driver = GraphDatabase.driver(neo4j.uri(), custom("neo4j", PASSWORD, "native", "basic")); + Session session = driver.session()) { + Value single = session.run("CREATE () RETURN 1").single().get(0); + assertThat(single.asLong(), equalTo(1L)); } } @Test - void shouldBeAbleToConnectWithCustomTokenWithAdditionalParameters() - { - Map params = singletonMap( "secret", 16 ); + void shouldBeAbleToConnectWithCustomTokenWithAdditionalParameters() { + Map params = singletonMap("secret", 16); // When & Then - try( Driver driver = GraphDatabase.driver( neo4j.uri(), - custom( "neo4j", PASSWORD, "native", "basic", params ) ); - Session session = driver.session() ) - { - Value single = session.run( "CREATE () RETURN 1" ).single().get( 0 ); - assertThat( single.asLong(), equalTo( 1L ) ); + try (Driver driver = GraphDatabase.driver(neo4j.uri(), custom("neo4j", PASSWORD, "native", "basic", params)); + Session session = driver.session()) { + Value single = session.run("CREATE () RETURN 1").single().get(0); + assertThat(single.asLong(), equalTo(1L)); } } @Test - void directDriverShouldFailEarlyOnWrongCredentials() - { - testDriverFailureOnWrongCredentials( "bolt://localhost:" + neo4j.boltPort() ); + void directDriverShouldFailEarlyOnWrongCredentials() { + testDriverFailureOnWrongCredentials("bolt://localhost:" + neo4j.boltPort()); } @Test - void routingDriverShouldFailEarlyOnWrongCredentials() - { - testDriverFailureOnWrongCredentials( "neo4j://localhost:" + neo4j.boltPort() ); + void routingDriverShouldFailEarlyOnWrongCredentials() { + testDriverFailureOnWrongCredentials("neo4j://localhost:" + neo4j.boltPort()); } - private void testDriverFailureOnWrongCredentials( String uri ) - { - Config config = Config.builder().withLogging( DEV_NULL_LOGGING ).build(); - AuthToken authToken = AuthTokens.basic( "neo4j", "wrongSecret" ); + private void testDriverFailureOnWrongCredentials(String uri) { + Config config = Config.builder().withLogging(DEV_NULL_LOGGING).build(); + AuthToken authToken = AuthTokens.basic("neo4j", "wrongSecret"); - final Driver driver = GraphDatabase.driver( uri, authToken, config ); - assertThrows( AuthenticationException.class, driver::verifyConnectivity ); + final Driver driver = GraphDatabase.driver(uri, authToken, config); + assertThrows(AuthenticationException.class, driver::verifyConnectivity); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/DirectDriverIT.java b/driver/src/test/java/org/neo4j/driver/integration/DirectDriverIT.java index 473b1479a6..442ab39b56 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/DirectDriverIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/DirectDriverIT.java @@ -18,14 +18,17 @@ */ package org.neo4j.driver.integration; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.internal.util.Matchers.directDriverWithAddress; + +import java.net.URI; import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.net.URI; - -import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.Result; @@ -34,81 +37,67 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.core.IsEqual.equalTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.util.Matchers.directDriverWithAddress; - @ParallelizableIT -class DirectDriverIT -{ +class DirectDriverIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private Driver driver; @AfterEach - void closeDriver() - { - if ( driver != null ) - { + void closeDriver() { + if (driver != null) { driver.close(); } } @Test - void shouldAllowIPv6Address() - { + void shouldAllowIPv6Address() { // Given - URI uri = URI.create( "bolt://[::1]:" + neo4j.boltPort() ); - BoltServerAddress address = new BoltServerAddress( uri ); + URI uri = URI.create("bolt://[::1]:" + neo4j.boltPort()); + BoltServerAddress address = new BoltServerAddress(uri); // When - driver = GraphDatabase.driver( uri, neo4j.authToken() ); + driver = GraphDatabase.driver(uri, neo4j.authToken()); // Then - assertThat( driver, is( directDriverWithAddress( address ) ) ); + assertThat(driver, is(directDriverWithAddress(address))); } @Test - void shouldRejectInvalidAddress() - { + void shouldRejectInvalidAddress() { // Given - URI uri = URI.create( "*" ); + URI uri = URI.create("*"); // When & Then - IllegalArgumentException e = assertThrows( IllegalArgumentException.class, () -> GraphDatabase.driver( uri, neo4j.authToken() ) ); - assertThat( e.getMessage(), equalTo( "Scheme must not be null" ) ); + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> GraphDatabase.driver(uri, neo4j.authToken())); + assertThat(e.getMessage(), equalTo("Scheme must not be null")); } @Test - void shouldRegisterSingleServer() - { + void shouldRegisterSingleServer() { // Given URI uri = neo4j.uri(); - BoltServerAddress address = new BoltServerAddress( uri ); + BoltServerAddress address = new BoltServerAddress(uri); // When - driver = GraphDatabase.driver( uri, neo4j.authToken() ); + driver = GraphDatabase.driver(uri, neo4j.authToken()); // Then - assertThat( driver, is( directDriverWithAddress( address ) ) ); + assertThat(driver, is(directDriverWithAddress(address))); } @Test - void shouldConnectIPv6Uri() - { + void shouldConnectIPv6Uri() { // Given - try ( Driver driver = GraphDatabase.driver( "bolt://[::1]:" + neo4j.boltPort(), neo4j.authToken() ); - Session session = driver.session() ) - { + try (Driver driver = GraphDatabase.driver("bolt://[::1]:" + neo4j.boltPort(), neo4j.authToken()); + Session session = driver.session()) { // When - Result result = session.run( "RETURN 1" ); + Result result = session.run("RETURN 1"); // Then - assertThat( result.single().get( 0 ).asInt(), CoreMatchers.equalTo( 1 ) ); + assertThat(result.single().get(0).asInt(), CoreMatchers.equalTo(1)); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/DriverCloseIT.java b/driver/src/test/java/org/neo4j/driver/integration/DriverCloseIT.java index 5840e5fc04..93c27f75d8 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/DriverCloseIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/DriverCloseIT.java @@ -18,9 +18,11 @@ */ package org.neo4j.driver.integration; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.SessionConfig.builder; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; @@ -28,48 +30,43 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.SessionConfig.builder; - @ParallelizableIT -class DriverCloseIT -{ +class DriverCloseIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - void isEncryptedThrowsForClosedDriver() - { + void isEncryptedThrowsForClosedDriver() { Driver driver = createDriver(); driver.close(); - assertThrows( IllegalStateException.class, driver::isEncrypted ); + assertThrows(IllegalStateException.class, driver::isEncrypted); } @Test - void sessionThrowsForClosedDriver() - { + void sessionThrowsForClosedDriver() { Driver driver = createDriver(); driver.close(); - assertThrows( IllegalStateException.class, driver::session ); + assertThrows(IllegalStateException.class, driver::session); } @Test - void sessionWithModeThrowsForClosedDriver() - { + void sessionWithModeThrowsForClosedDriver() { Driver driver = createDriver(); driver.close(); - assertThrows( IllegalStateException.class, () -> driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ) ); + assertThrows( + IllegalStateException.class, + () -> driver.session( + builder().withDefaultAccessMode(AccessMode.WRITE).build())); } @Test - void closeClosedDriver() - { + void closeClosedDriver() { Driver driver = createDriver(); driver.close(); @@ -78,18 +75,16 @@ void closeClosedDriver() } @Test - void useSessionAfterDriverIsClosed() - { + void useSessionAfterDriverIsClosed() { Driver driver = createDriver(); Session session = driver.session(); driver.close(); - assertThrows( IllegalStateException.class, () -> session.run( "CREATE ()" ) ); + assertThrows(IllegalStateException.class, () -> session.run("CREATE ()")); } - private static Driver createDriver() - { - return GraphDatabase.driver( neo4j.uri(), neo4j.authToken() ); + private static Driver createDriver() { + return GraphDatabase.driver(neo4j.uri(), neo4j.authToken()); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/EncryptionIT.java b/driver/src/test/java/org/neo4j/driver/integration/EncryptionIT.java index bc4ca1a754..692fd1245c 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/EncryptionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/EncryptionIT.java @@ -18,11 +18,15 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.Config.TrustStrategy.trustAllCertificates; import java.net.URI; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; @@ -36,112 +40,95 @@ import org.neo4j.driver.util.Neo4jSettings.BoltTlsLevel; import org.neo4j.driver.util.ParallelizableIT; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.Config.TrustStrategy.trustAllCertificates; - @ParallelizableIT -class EncryptionIT -{ +class EncryptionIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - void shouldOperateWithNoEncryptionWhenItIsOptionalInTheDatabase() - { - testMatchingEncryption( BoltTlsLevel.OPTIONAL, false, neo4j.uri().getScheme() ); + void shouldOperateWithNoEncryptionWhenItIsOptionalInTheDatabase() { + testMatchingEncryption(BoltTlsLevel.OPTIONAL, false, neo4j.uri().getScheme()); } @Test - void shouldOperateWithEncryptionWhenItIsOptionalInTheDatabase() - { - testMatchingEncryption( BoltTlsLevel.OPTIONAL, true, neo4j.uri().getScheme() ); + void shouldOperateWithEncryptionWhenItIsOptionalInTheDatabase() { + testMatchingEncryption(BoltTlsLevel.OPTIONAL, true, neo4j.uri().getScheme()); } @Test - void shouldFailWithoutEncryptionWhenItIsRequiredInTheDatabase() - { - testMismatchingEncryption( BoltTlsLevel.REQUIRED, false ); + void shouldFailWithoutEncryptionWhenItIsRequiredInTheDatabase() { + testMismatchingEncryption(BoltTlsLevel.REQUIRED, false); } @Test - void shouldOperateWithEncryptionWhenItIsAlsoRequiredInTheDatabase() - { - testMatchingEncryption( BoltTlsLevel.REQUIRED, true, neo4j.uri().getScheme() ); + void shouldOperateWithEncryptionWhenItIsAlsoRequiredInTheDatabase() { + testMatchingEncryption(BoltTlsLevel.REQUIRED, true, neo4j.uri().getScheme()); } @Test - void shouldOperateWithEncryptionWhenConfiguredUsingBoltSscURI() - { - testMatchingEncryption( BoltTlsLevel.REQUIRED, true, "bolt+ssc" ); + void shouldOperateWithEncryptionWhenConfiguredUsingBoltSscURI() { + testMatchingEncryption(BoltTlsLevel.REQUIRED, true, "bolt+ssc"); } @Test - void shouldFailWithEncryptionWhenItIsDisabledInTheDatabase() - { - testMismatchingEncryption( BoltTlsLevel.DISABLED, true ); + void shouldFailWithEncryptionWhenItIsDisabledInTheDatabase() { + testMismatchingEncryption(BoltTlsLevel.DISABLED, true); } @Test - void shouldOperateWithoutEncryptionWhenItIsAlsoDisabledInTheDatabase() - { - testMatchingEncryption( BoltTlsLevel.DISABLED, false, neo4j.uri().getScheme() ); + void shouldOperateWithoutEncryptionWhenItIsAlsoDisabledInTheDatabase() { + testMatchingEncryption(BoltTlsLevel.DISABLED, false, neo4j.uri().getScheme()); } - private void testMatchingEncryption( BoltTlsLevel tlsLevel, boolean driverEncrypted, String scheme ) - { - neo4j.restartDb( Neo4jSettings.TEST_SETTINGS.updateWith( Neo4jSettings.BOLT_TLS_LEVEL, tlsLevel.toString() ) ); + private void testMatchingEncryption(BoltTlsLevel tlsLevel, boolean driverEncrypted, String scheme) { + neo4j.restartDb(Neo4jSettings.TEST_SETTINGS.updateWith(Neo4jSettings.BOLT_TLS_LEVEL, tlsLevel.toString())); Config config; - if ( scheme.equals( Scheme.BOLT_LOW_TRUST_URI_SCHEME ) ) - { + if (scheme.equals(Scheme.BOLT_LOW_TRUST_URI_SCHEME)) { config = Config.builder().build(); } else { - config = newConfig( driverEncrypted ); + config = newConfig(driverEncrypted); } - URI uri = URI.create( String.format( "%s://%s:%s", scheme, neo4j.uri().getHost(), neo4j.uri().getPort()) ); + URI uri = URI.create(String.format( + "%s://%s:%s", scheme, neo4j.uri().getHost(), neo4j.uri().getPort())); - try ( Driver driver = GraphDatabase.driver( uri, neo4j.authToken(), config ) ) - { - assertThat( driver.isEncrypted(), equalTo( driverEncrypted ) ); + try (Driver driver = GraphDatabase.driver(uri, neo4j.authToken(), config)) { + assertThat(driver.isEncrypted(), equalTo(driverEncrypted)); - try ( Session session = driver.session() ) - { - Result result = session.run( "RETURN 1" ); + try (Session session = driver.session()) { + Result result = session.run("RETURN 1"); Record record = result.next(); - int value = record.get( 0 ).asInt(); - assertThat( value, equalTo( 1 ) ); + int value = record.get(0).asInt(); + assertThat(value, equalTo(1)); } } } - private void testMismatchingEncryption( BoltTlsLevel tlsLevel, boolean driverEncrypted ) - { - neo4j.restartDb( Neo4jSettings.TEST_SETTINGS.updateWith( Neo4jSettings.BOLT_TLS_LEVEL, tlsLevel.toString() ) ); - Config config = newConfig( driverEncrypted ); + private void testMismatchingEncryption(BoltTlsLevel tlsLevel, boolean driverEncrypted) { + neo4j.restartDb(Neo4jSettings.TEST_SETTINGS.updateWith(Neo4jSettings.BOLT_TLS_LEVEL, tlsLevel.toString())); + Config config = newConfig(driverEncrypted); - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, - () -> GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), config ).verifyConnectivity() ); + ServiceUnavailableException e = assertThrows( + ServiceUnavailableException.class, () -> GraphDatabase.driver(neo4j.uri(), neo4j.authToken(), config) + .verifyConnectivity()); - assertThat( e.getMessage(), startsWith( "Connection to the database terminated" ) ); + assertThat(e.getMessage(), startsWith("Connection to the database terminated")); } - private static Config newConfig( boolean withEncryption ) - { + private static Config newConfig(boolean withEncryption) { return withEncryption ? configWithEncryption() : configWithoutEncryption(); } - private static Config configWithEncryption() - { - return Config.builder().withEncryption().withTrustStrategy( trustAllCertificates() ).build(); + private static Config configWithEncryption() { + return Config.builder() + .withEncryption() + .withTrustStrategy(trustAllCertificates()) + .build(); } - private static Config configWithoutEncryption() - { + private static Config configWithoutEncryption() { return Config.builder().withoutEncryption().build(); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/EntityTypeIT.java b/driver/src/test/java/org/neo4j/driver/integration/EntityTypeIT.java index fcc0d138e8..6b3205ef35 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/EntityTypeIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/EntityTypeIT.java @@ -18,9 +18,11 @@ */ package org.neo4j.driver.integration; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - import org.neo4j.driver.Result; import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Path; @@ -28,55 +30,47 @@ import org.neo4j.driver.util.ParallelizableIT; import org.neo4j.driver.util.SessionExtension; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.greaterThan; - @ParallelizableIT -class EntityTypeIT -{ +class EntityTypeIT { @RegisterExtension static final SessionExtension session = new SessionExtension(); @Test - void shouldReturnIdentitiesOfNodes() - { + void shouldReturnIdentitiesOfNodes() { // When - Result cursor = session.run( "CREATE (n) RETURN n" ); - Node node = cursor.single().get( "n" ).asNode(); + Result cursor = session.run("CREATE (n) RETURN n"); + Node node = cursor.single().get("n").asNode(); // Then - assertThat( node.id(), greaterThan(-1L)); + assertThat(node.id(), greaterThan(-1L)); } @Test - void shouldReturnIdentitiesOfRelationships() - { + void shouldReturnIdentitiesOfRelationships() { // When - Result cursor = session.run( "CREATE ()-[r:T]->() RETURN r" ); - Relationship rel = cursor.single().get( "r" ).asRelationship(); + Result cursor = session.run("CREATE ()-[r:T]->() RETURN r"); + Relationship rel = cursor.single().get("r").asRelationship(); // Then - assertThat( rel.startNodeId(), greaterThan(-1L)); - assertThat( rel.endNodeId(), greaterThan(-1L)); - assertThat( rel.id(), greaterThan(-1L)); + assertThat(rel.startNodeId(), greaterThan(-1L)); + assertThat(rel.endNodeId(), greaterThan(-1L)); + assertThat(rel.id(), greaterThan(-1L)); } @Test - void shouldReturnIdentitiesOfPaths() - { + void shouldReturnIdentitiesOfPaths() { // When - Result cursor = session.run( "CREATE p=()-[r:T]->() RETURN p" ); - Path path = cursor.single().get( "p" ).asPath(); + Result cursor = session.run("CREATE p=()-[r:T]->() RETURN p"); + Path path = cursor.single().get("p").asPath(); // Then - assertThat( path.start().id(), greaterThan( -1L )); - assertThat( path.end().id(), greaterThan( -1L )); + assertThat(path.start().id(), greaterThan(-1L)); + assertThat(path.end().id(), greaterThan(-1L)); Path.Segment segment = path.iterator().next(); - assertThat( segment.start().id(), greaterThan( -1L )); - assertThat( segment.relationship().id(), greaterThan( -1L )); - assertThat( segment.end().id(), greaterThan( -1L )); + assertThat(segment.start().id(), greaterThan(-1L)); + assertThat(segment.relationship().id(), greaterThan(-1L)); + assertThat(segment.end().id(), greaterThan(-1L)); } - } diff --git a/driver/src/test/java/org/neo4j/driver/integration/ErrorIT.java b/driver/src/test/java/org/neo4j/driver/integration/ErrorIT.java index 27ddd792ae..c03e749c9b 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ErrorIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ErrorIT.java @@ -18,11 +18,24 @@ */ package org.neo4j.driver.integration; -import io.netty.channel.Channel; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Arrays.asList; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.util.Iterables.single; +import io.netty.channel.Channel; import java.io.IOException; import java.lang.reflect.Method; import java.net.URI; @@ -32,7 +45,9 @@ import java.util.UUID; import java.util.function.Consumer; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.AuthToken; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @@ -53,275 +68,246 @@ import org.neo4j.driver.util.ParallelizableIT; import org.neo4j.driver.util.SessionExtension; -import static java.util.Arrays.asList; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.util.Iterables.single; - @ParallelizableIT -class ErrorIT -{ +class ErrorIT { @RegisterExtension static final SessionExtension session = new SessionExtension(); @Test - void shouldThrowHelpfulSyntaxError() - { - ClientException e = assertThrows( ClientException.class, () -> - { - Result result = session.run( "invalid query" ); + void shouldThrowHelpfulSyntaxError() { + ClientException e = assertThrows(ClientException.class, () -> { + Result result = session.run("invalid query"); result.consume(); - } ); + }); - assertThat( e.getMessage(), startsWith( "Invalid input" ) ); + assertThat(e.getMessage(), startsWith("Invalid input")); } @Test - void shouldNotAllowMoreTxAfterClientException() - { + void shouldNotAllowMoreTxAfterClientException() { // Given Transaction tx = session.beginTransaction(); // And Given an error has occurred - try { tx.run( "invalid" ).consume(); } catch ( ClientException e ) {/*empty*/} + try { + tx.run("invalid").consume(); + } catch (ClientException e) { + /*empty*/ + } // Expect - ClientException e = assertThrows( ClientException.class, () -> - { - Result cursor = tx.run( "RETURN 1" ); - cursor.single().get( "1" ).asInt(); - } ); - assertThat( e.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); + ClientException e = assertThrows(ClientException.class, () -> { + Result cursor = tx.run("RETURN 1"); + cursor.single().get("1").asInt(); + }); + assertThat(e.getMessage(), startsWith("Cannot run more queries in this transaction")); } @Test - void shouldAllowNewQueryAfterRecoverableError() - { + void shouldAllowNewQueryAfterRecoverableError() { // Given an error has occurred - try { session.run( "invalid" ).consume(); } catch ( ClientException e ) {/*empty*/} + try { + session.run("invalid").consume(); + } catch (ClientException e) { + /*empty*/ + } // When - Result cursor = session.run( "RETURN 1" ); - int val = cursor.single().get( "1" ).asInt(); + Result cursor = session.run("RETURN 1"); + int val = cursor.single().get("1").asInt(); // Then - assertThat( val, equalTo( 1 ) ); + assertThat(val, equalTo(1)); } @Test - void shouldAllowNewTransactionAfterRecoverableError() - { + void shouldAllowNewTransactionAfterRecoverableError() { // Given an error has occurred in a prior transaction - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "invalid" ).consume(); + try (Transaction tx = session.beginTransaction()) { + tx.run("invalid").consume(); + } catch (ClientException e) { + /*empty*/ } - catch ( ClientException e ) {/*empty*/} // When - try ( Transaction tx = session.beginTransaction() ) - { - Result cursor = tx.run( "RETURN 1" ); - int val = cursor.single().get( "1" ).asInt(); + try (Transaction tx = session.beginTransaction()) { + Result cursor = tx.run("RETURN 1"); + int val = cursor.single().get("1").asInt(); // Then - assertThat( val, equalTo( 1 ) ); + assertThat(val, equalTo(1)); } } @Test - void shouldExplainConnectionError() - { - final Driver driver = GraphDatabase.driver( "bolt://localhost:7777" ); - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, driver::verifyConnectivity ); - - assertEquals( "Unable to connect to localhost:7777, ensure the database is running " + - "and that there is a working network connection to it.", e.getMessage() ); + void shouldExplainConnectionError() { + final Driver driver = GraphDatabase.driver("bolt://localhost:7777"); + ServiceUnavailableException e = assertThrows(ServiceUnavailableException.class, driver::verifyConnectivity); + + assertEquals( + "Unable to connect to localhost:7777, ensure the database is running " + + "and that there is a working network connection to it.", + e.getMessage()); } @Test - void shouldHandleFailureAtRunTime() - { - String label = UUID.randomUUID().toString(); // avoid clashes with other tests + void shouldHandleFailureAtRunTime() { + String label = UUID.randomUUID().toString(); // avoid clashes with other tests // given Transaction tx = session.beginTransaction(); - tx.run( "CREATE CONSTRAINT ON (a:`" + label + "`) ASSERT a.name IS UNIQUE" ); + tx.run("CREATE CONSTRAINT ON (a:`" + label + "`) ASSERT a.name IS UNIQUE"); tx.commit(); // and Transaction anotherTx = session.beginTransaction(); // then expect - ClientException e = assertThrows( ClientException.class, () -> anotherTx.run( "CREATE INDEX ON :`" + label + "`(name)" ) ); + ClientException e = + assertThrows(ClientException.class, () -> anotherTx.run("CREATE INDEX ON :`" + label + "`(name)")); anotherTx.rollback(); - assertThat( e.getMessage(), containsString( label ) ); - assertThat( e.getMessage(), containsString( "name" ) ); + assertThat(e.getMessage(), containsString(label)); + assertThat(e.getMessage(), containsString("name")); } @Test - void shouldGetHelpfulErrorWhenTryingToConnectToHttpPort() throws Throwable - { - //the http server needs some time to start up - Thread.sleep( 2000 ); + void shouldGetHelpfulErrorWhenTryingToConnectToHttpPort() throws Throwable { + // the http server needs some time to start up + Thread.sleep(2000); Config config = Config.builder().withoutEncryption().build(); - final Driver driver = GraphDatabase.driver( "bolt://localhost:" + session.httpPort(), config ); - ClientException e = assertThrows( ClientException.class, driver::verifyConnectivity ); - assertEquals( "Server responded HTTP. Make sure you are not trying to connect to the http endpoint " + - "(HTTP defaults to port 7474 whereas BOLT defaults to port 7687)", e.getMessage() ); + final Driver driver = GraphDatabase.driver("bolt://localhost:" + session.httpPort(), config); + ClientException e = assertThrows(ClientException.class, driver::verifyConnectivity); + assertEquals( + "Server responded HTTP. Make sure you are not trying to connect to the http endpoint " + + "(HTTP defaults to port 7474 whereas BOLT defaults to port 7687)", + e.getMessage()); } @Test - void shouldCloseChannelOnRuntimeExceptionInOutboundMessage() throws InterruptedException - { - RuntimeException error = new RuntimeException( "Unable to encode message" ); - Throwable queryError = testChannelErrorHandling( messageFormat -> messageFormat.makeWriterThrow( error ) ); + void shouldCloseChannelOnRuntimeExceptionInOutboundMessage() throws InterruptedException { + RuntimeException error = new RuntimeException("Unable to encode message"); + Throwable queryError = testChannelErrorHandling(messageFormat -> messageFormat.makeWriterThrow(error)); - assertEquals( error, queryError ); + assertEquals(error, queryError); } @Test - void shouldCloseChannelOnIOExceptionInOutboundMessage() throws InterruptedException - { - IOException error = new IOException( "Unable to write" ); - Throwable queryError = testChannelErrorHandling( messageFormat -> messageFormat.makeWriterThrow( error ) ); - - assertThat( queryError, instanceOf( ServiceUnavailableException.class ) ); - assertEquals( "Connection to the database failed", queryError.getMessage() ); - assertEquals( error, queryError.getCause() ); + void shouldCloseChannelOnIOExceptionInOutboundMessage() throws InterruptedException { + IOException error = new IOException("Unable to write"); + Throwable queryError = testChannelErrorHandling(messageFormat -> messageFormat.makeWriterThrow(error)); + + assertThat(queryError, instanceOf(ServiceUnavailableException.class)); + assertEquals("Connection to the database failed", queryError.getMessage()); + assertEquals(error, queryError.getCause()); } @Test - void shouldCloseChannelOnRuntimeExceptionInInboundMessage() throws InterruptedException - { - RuntimeException error = new RuntimeException( "Unable to decode message" ); - Throwable queryError = testChannelErrorHandling( messageFormat -> messageFormat.makeReaderThrow( error ) ); + void shouldCloseChannelOnRuntimeExceptionInInboundMessage() throws InterruptedException { + RuntimeException error = new RuntimeException("Unable to decode message"); + Throwable queryError = testChannelErrorHandling(messageFormat -> messageFormat.makeReaderThrow(error)); - assertEquals( error, queryError ); + assertEquals(error, queryError); } @Test - void shouldCloseChannelOnIOExceptionInInboundMessage() throws InterruptedException - { - IOException error = new IOException( "Unable to read" ); - Throwable queryError = testChannelErrorHandling( messageFormat -> messageFormat.makeReaderThrow( error ) ); - - assertThat( queryError, instanceOf( ServiceUnavailableException.class ) ); - assertEquals( "Connection to the database failed", queryError.getMessage() ); - assertEquals( error, queryError.getCause() ); + void shouldCloseChannelOnIOExceptionInInboundMessage() throws InterruptedException { + IOException error = new IOException("Unable to read"); + Throwable queryError = testChannelErrorHandling(messageFormat -> messageFormat.makeReaderThrow(error)); + + assertThat(queryError, instanceOf(ServiceUnavailableException.class)); + assertEquals("Connection to the database failed", queryError.getMessage()); + assertEquals(error, queryError.getCause()); } @Test - void shouldCloseChannelOnInboundFatalFailureMessage() throws InterruptedException - { + void shouldCloseChannelOnInboundFatalFailureMessage() throws InterruptedException { String errorCode = "Neo.ClientError.Request.Invalid"; String errorMessage = "Very wrong request"; - FailureMessage failureMsg = new FailureMessage( errorCode, errorMessage ); + FailureMessage failureMsg = new FailureMessage(errorCode, errorMessage); - Throwable queryError = testChannelErrorHandling( messageFormat -> messageFormat.makeReaderFail( failureMsg ) ); + Throwable queryError = testChannelErrorHandling(messageFormat -> messageFormat.makeReaderFail(failureMsg)); - assertThat( queryError, instanceOf( ClientException.class ) ); - assertEquals( ((ClientException) queryError).code(), errorCode ); - assertEquals( queryError.getMessage(), errorMessage ); + assertThat(queryError, instanceOf(ClientException.class)); + assertEquals(((ClientException) queryError).code(), errorCode); + assertEquals(queryError.getMessage(), errorMessage); } @Test - void shouldThrowErrorWithNiceStackTrace( TestInfo testInfo ) - { - ClientException error = assertThrows( ClientException.class, () -> session.run( "RETURN 10 / 0" ).consume() ); + void shouldThrowErrorWithNiceStackTrace(TestInfo testInfo) { + ClientException error = assertThrows( + ClientException.class, () -> session.run("RETURN 10 / 0").consume()); // thrown error should have this class & method in the stacktrace StackTraceElement[] stackTrace = error.getStackTrace(); - assertTrue( Stream.of( stackTrace ).anyMatch( element -> testClassAndMethodMatch( testInfo, element ) ), - () -> "Expected stacktrace element is absent:\n" + Arrays.toString( stackTrace ) ); + assertTrue( + Stream.of(stackTrace).anyMatch(element -> testClassAndMethodMatch(testInfo, element)), + () -> "Expected stacktrace element is absent:\n" + Arrays.toString(stackTrace)); // thrown error should have a suppressed error with an async stacktrace - assertThat( asList( error.getSuppressed() ), hasSize( greaterThanOrEqualTo( 1 ) ) ); + assertThat(asList(error.getSuppressed()), hasSize(greaterThanOrEqualTo(1))); } - private Throwable testChannelErrorHandling( Consumer messageFormatSetup ) - throws InterruptedException - { - ChannelTrackingDriverFactoryWithFailingMessageFormat driverFactory = new ChannelTrackingDriverFactoryWithFailingMessageFormat( new FakeClock() ); + private Throwable testChannelErrorHandling(Consumer messageFormatSetup) + throws InterruptedException { + ChannelTrackingDriverFactoryWithFailingMessageFormat driverFactory = + new ChannelTrackingDriverFactoryWithFailingMessageFormat(new FakeClock()); URI uri = session.uri(); AuthToken authToken = session.authToken(); RoutingSettings routingSettings = RoutingSettings.DEFAULT; RetrySettings retrySettings = RetrySettings.DEFAULT; - Config config = Config.builder().withLogging( DEV_NULL_LOGGING ).build(); + Config config = Config.builder().withLogging(DEV_NULL_LOGGING).build(); Throwable queryError = null; - try ( Driver driver = driverFactory.newInstance( uri, authToken, routingSettings, retrySettings, config, SecurityPlanImpl.insecure() ) ) - { + try (Driver driver = driverFactory.newInstance( + uri, authToken, routingSettings, retrySettings, config, SecurityPlanImpl.insecure())) { driver.verifyConnectivity(); - try(Session session = driver.session() ) - { - messageFormatSetup.accept( driverFactory.getFailingMessageFormat() ); - - try - { - session.run( "RETURN 1" ).consume(); - fail( "Exception expected" ); - } - catch ( Throwable error ) - { + try (Session session = driver.session()) { + messageFormatSetup.accept(driverFactory.getFailingMessageFormat()); + + try { + session.run("RETURN 1").consume(); + fail("Exception expected"); + } catch (Throwable error) { queryError = error; } - assertSingleChannelIsClosed( driverFactory ); - assertNewQueryCanBeExecuted( session, driverFactory ); + assertSingleChannelIsClosed(driverFactory); + assertNewQueryCanBeExecuted(session, driverFactory); } } - return queryError; } - private void assertSingleChannelIsClosed( ChannelTrackingDriverFactory driverFactory ) throws InterruptedException - { - Channel channel = single( driverFactory.channels() ); - assertTrue( channel.closeFuture().await( 10, SECONDS ) ); - assertFalse( channel.isActive() ); + private void assertSingleChannelIsClosed(ChannelTrackingDriverFactory driverFactory) throws InterruptedException { + Channel channel = single(driverFactory.channels()); + assertTrue(channel.closeFuture().await(10, SECONDS)); + assertFalse(channel.isActive()); } - private void assertNewQueryCanBeExecuted( Session session, ChannelTrackingDriverFactory driverFactory ) - { - assertEquals( 42, session.run( "RETURN 42" ).single().get( 0 ).asInt() ); + private void assertNewQueryCanBeExecuted(Session session, ChannelTrackingDriverFactory driverFactory) { + assertEquals(42, session.run("RETURN 42").single().get(0).asInt()); List channels = driverFactory.channels(); - Channel lastChannel = channels.get( channels.size() - 1 ); - assertTrue( lastChannel.isActive() ); + Channel lastChannel = channels.get(channels.size() - 1); + assertTrue(lastChannel.isActive()); } - private static boolean testClassAndMethodMatch( TestInfo testInfo, StackTraceElement element ) - { - return testClassMatches( testInfo, element ) && testMethodMatches( testInfo, element ); + private static boolean testClassAndMethodMatch(TestInfo testInfo, StackTraceElement element) { + return testClassMatches(testInfo, element) && testMethodMatches(testInfo, element); } - private static boolean testClassMatches( TestInfo testInfo, StackTraceElement element ) - { - String expectedName = testInfo.getTestClass().map( Class::getName ).orElse( "" ); + private static boolean testClassMatches(TestInfo testInfo, StackTraceElement element) { + String expectedName = testInfo.getTestClass().map(Class::getName).orElse(""); String actualName = element.getClassName(); - return Objects.equals( expectedName, actualName ); + return Objects.equals(expectedName, actualName); } - private static boolean testMethodMatches( TestInfo testInfo, StackTraceElement element ) - { - String expectedName = testInfo.getTestMethod().map( Method::getName ).orElse( "" ); + private static boolean testMethodMatches(TestInfo testInfo, StackTraceElement element) { + String expectedName = testInfo.getTestMethod().map(Method::getName).orElse(""); String actualName = element.getMethodName(); - return Objects.equals( expectedName, actualName ); + return Objects.equals(expectedName, actualName); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/LoadCSVIT.java b/driver/src/test/java/org/neo4j/driver/integration/LoadCSVIT.java index ed22914b59..db41d87b10 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/LoadCSVIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/LoadCSVIT.java @@ -18,223 +18,209 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.neo4j.driver.Values.parameters; import java.io.IOException; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.Neo4jSettings; import org.neo4j.driver.util.ParallelizableIT; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.neo4j.driver.Values.parameters; - @ParallelizableIT -class LoadCSVIT -{ +class LoadCSVIT { @RegisterExtension - static final DatabaseExtension neo4j = new DatabaseExtension( Neo4jSettings.TEST_SETTINGS.without( Neo4jSettings.IMPORT_DIR ) ); + static final DatabaseExtension neo4j = + new DatabaseExtension(Neo4jSettings.TEST_SETTINGS.without(Neo4jSettings.IMPORT_DIR)); @Test - void shouldLoadCSV() throws Throwable - { - try( Driver driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken() ); - Session session = driver.session() ) - { - String csvFileUrl = createLocalIrisData( session ); + void shouldLoadCSV() throws Throwable { + try (Driver driver = GraphDatabase.driver(neo4j.uri(), neo4j.authToken()); + Session session = driver.session()) { + String csvFileUrl = createLocalIrisData(session); // When Result result = session.run( - "USING PERIODIC COMMIT 40\n" + - "LOAD CSV WITH HEADERS FROM $csvFileUrl AS l\n" + - "MATCH (c:Class {name: l.class_name})\n" + - "CREATE (s:Sample {sepal_length: l.sepal_length, sepal_width: l.sepal_width, petal_length: l.petal_length, petal_width: l.petal_width})\n" + - - "CREATE (c)<-[:HAS_CLASS]-(s) " + - "RETURN count(*) AS c", - parameters( "csvFileUrl", csvFileUrl ) ); + "USING PERIODIC COMMIT 40\n" + "LOAD CSV WITH HEADERS FROM $csvFileUrl AS l\n" + + "MATCH (c:Class {name: l.class_name})\n" + + "CREATE (s:Sample {sepal_length: l.sepal_length, sepal_width: l.sepal_width, petal_length: l.petal_length, petal_width: l.petal_width})\n" + + "CREATE (c)<-[:HAS_CLASS]-(s) " + + "RETURN count(*) AS c", + parameters("csvFileUrl", csvFileUrl)); // Then - assertThat( result.next().get( "c" ).asInt(), equalTo( 150 ) ); - assertFalse( result.hasNext() ); + assertThat(result.next().get("c").asInt(), equalTo(150)); + assertFalse(result.hasNext()); } } - private String createLocalIrisData( Session session ) throws IOException - { - for ( String className : IRIS_CLASS_NAMES ) - { - session.run( "CREATE (c:Class {name: $className}) RETURN c", parameters( "className", className ) ); + private String createLocalIrisData(Session session) throws IOException { + for (String className : IRIS_CLASS_NAMES) { + session.run("CREATE (c:Class {name: $className}) RETURN c", parameters("className", className)); } - return neo4j.putTmpFile( "iris", ".csv", IRIS_DATA ).toExternalForm(); + return neo4j.putTmpFile("iris", ".csv", IRIS_DATA).toExternalForm(); } - private static String[] IRIS_CLASS_NAMES = - new String[] { - "Iris-setosa", - "Iris-versicolor", - "Iris-virginica" - }; + private static String[] IRIS_CLASS_NAMES = new String[] {"Iris-setosa", "Iris-versicolor", "Iris-virginica"}; private static String IRIS_DATA = - "sepal_length,sepal_width,petal_length,petal_width,class_name\n" + - "5.1,3.5,1.4,0.2,Iris-setosa\n" + - "4.9,3.0,1.4,0.2,Iris-setosa\n" + - "4.7,3.2,1.3,0.2,Iris-setosa\n" + - "4.6,3.1,1.5,0.2,Iris-setosa\n" + - "5.0,3.6,1.4,0.2,Iris-setosa\n" + - "5.4,3.9,1.7,0.4,Iris-setosa\n" + - "4.6,3.4,1.4,0.3,Iris-setosa\n" + - "5.0,3.4,1.5,0.2,Iris-setosa\n" + - "4.4,2.9,1.4,0.2,Iris-setosa\n" + - "4.9,3.1,1.5,0.1,Iris-setosa\n" + - "5.4,3.7,1.5,0.2,Iris-setosa\n" + - "4.8,3.4,1.6,0.2,Iris-setosa\n" + - "4.8,3.0,1.4,0.1,Iris-setosa\n" + - "4.3,3.0,1.1,0.1,Iris-setosa\n" + - "5.8,4.0,1.2,0.2,Iris-setosa\n" + - "5.7,4.4,1.5,0.4,Iris-setosa\n" + - "5.4,3.9,1.3,0.4,Iris-setosa\n" + - "5.1,3.5,1.4,0.3,Iris-setosa\n" + - "5.7,3.8,1.7,0.3,Iris-setosa\n" + - "5.1,3.8,1.5,0.3,Iris-setosa\n" + - "5.4,3.4,1.7,0.2,Iris-setosa\n" + - "5.1,3.7,1.5,0.4,Iris-setosa\n" + - "4.6,3.6,1.0,0.2,Iris-setosa\n" + - "5.1,3.3,1.7,0.5,Iris-setosa\n" + - "4.8,3.4,1.9,0.2,Iris-setosa\n" + - "5.0,3.0,1.6,0.2,Iris-setosa\n" + - "5.0,3.4,1.6,0.4,Iris-setosa\n" + - "5.2,3.5,1.5,0.2,Iris-setosa\n" + - "5.2,3.4,1.4,0.2,Iris-setosa\n" + - "4.7,3.2,1.6,0.2,Iris-setosa\n" + - "4.8,3.1,1.6,0.2,Iris-setosa\n" + - "5.4,3.4,1.5,0.4,Iris-setosa\n" + - "5.2,4.1,1.5,0.1,Iris-setosa\n" + - "5.5,4.2,1.4,0.2,Iris-setosa\n" + - "4.9,3.1,1.5,0.2,Iris-setosa\n" + - "5.0,3.2,1.2,0.2,Iris-setosa\n" + - "5.5,3.5,1.3,0.2,Iris-setosa\n" + - "4.9,3.6,1.4,0.1,Iris-setosa\n" + - "4.4,3.0,1.3,0.2,Iris-setosa\n" + - "5.1,3.4,1.5,0.2,Iris-setosa\n" + - "5.0,3.5,1.3,0.3,Iris-setosa\n" + - "4.5,2.3,1.3,0.3,Iris-setosa\n" + - "4.4,3.2,1.3,0.2,Iris-setosa\n" + - "5.0,3.5,1.6,0.6,Iris-setosa\n" + - "5.1,3.8,1.9,0.4,Iris-setosa\n" + - "4.8,3.0,1.4,0.3,Iris-setosa\n" + - "5.1,3.8,1.6,0.2,Iris-setosa\n" + - "4.6,3.2,1.4,0.2,Iris-setosa\n" + - "5.3,3.7,1.5,0.2,Iris-setosa\n" + - "5.0,3.3,1.4,0.2,Iris-setosa\n" + - "7.0,3.2,4.7,1.4,Iris-versicolor\n" + - "6.4,3.2,4.5,1.5,Iris-versicolor\n" + - "6.9,3.1,4.9,1.5,Iris-versicolor\n" + - "5.5,2.3,4.0,1.3,Iris-versicolor\n" + - "6.5,2.8,4.6,1.5,Iris-versicolor\n" + - "5.7,2.8,4.5,1.3,Iris-versicolor\n" + - "6.3,3.3,4.7,1.6,Iris-versicolor\n" + - "4.9,2.4,3.3,1.0,Iris-versicolor\n" + - "6.6,2.9,4.6,1.3,Iris-versicolor\n" + - "5.2,2.7,3.9,1.4,Iris-versicolor\n" + - "5.0,2.0,3.5,1.0,Iris-versicolor\n" + - "5.9,3.0,4.2,1.5,Iris-versicolor\n" + - "6.0,2.2,4.0,1.0,Iris-versicolor\n" + - "6.1,2.9,4.7,1.4,Iris-versicolor\n" + - "5.6,2.9,3.6,1.3,Iris-versicolor\n" + - "6.7,3.1,4.4,1.4,Iris-versicolor\n" + - "5.6,3.0,4.5,1.5,Iris-versicolor\n" + - "5.8,2.7,4.1,1.0,Iris-versicolor\n" + - "6.2,2.2,4.5,1.5,Iris-versicolor\n" + - "5.6,2.5,3.9,1.1,Iris-versicolor\n" + - "5.9,3.2,4.8,1.8,Iris-versicolor\n" + - "6.1,2.8,4.0,1.3,Iris-versicolor\n" + - "6.3,2.5,4.9,1.5,Iris-versicolor\n" + - "6.1,2.8,4.7,1.2,Iris-versicolor\n" + - "6.4,2.9,4.3,1.3,Iris-versicolor\n" + - "6.6,3.0,4.4,1.4,Iris-versicolor\n" + - "6.8,2.8,4.8,1.4,Iris-versicolor\n" + - "6.7,3.0,5.0,1.7,Iris-versicolor\n" + - "6.0,2.9,4.5,1.5,Iris-versicolor\n" + - "5.7,2.6,3.5,1.0,Iris-versicolor\n" + - "5.5,2.4,3.8,1.1,Iris-versicolor\n" + - "5.5,2.4,3.7,1.0,Iris-versicolor\n" + - "5.8,2.7,3.9,1.2,Iris-versicolor\n" + - "6.0,2.7,5.1,1.6,Iris-versicolor\n" + - "5.4,3.0,4.5,1.5,Iris-versicolor\n" + - "6.0,3.4,4.5,1.6,Iris-versicolor\n" + - "6.7,3.1,4.7,1.5,Iris-versicolor\n" + - "6.3,2.3,4.4,1.3,Iris-versicolor\n" + - "5.6,3.0,4.1,1.3,Iris-versicolor\n" + - "5.5,2.5,4.0,1.3,Iris-versicolor\n" + - "5.5,2.6,4.4,1.2,Iris-versicolor\n" + - "6.1,3.0,4.6,1.4,Iris-versicolor\n" + - "5.8,2.6,4.0,1.2,Iris-versicolor\n" + - "5.0,2.3,3.3,1.0,Iris-versicolor\n" + - "5.6,2.7,4.2,1.3,Iris-versicolor\n" + - "5.7,3.0,4.2,1.2,Iris-versicolor\n" + - "5.7,2.9,4.2,1.3,Iris-versicolor\n" + - "6.2,2.9,4.3,1.3,Iris-versicolor\n" + - "5.1,2.5,3.0,1.1,Iris-versicolor\n" + - "5.7,2.8,4.1,1.3,Iris-versicolor\n" + - "6.3,3.3,6.0,2.5,Iris-virginica\n" + - "5.8,2.7,5.1,1.9,Iris-virginica\n" + - "7.1,3.0,5.9,2.1,Iris-virginica\n" + - "6.3,2.9,5.6,1.8,Iris-virginica\n" + - "6.5,3.0,5.8,2.2,Iris-virginica\n" + - "7.6,3.0,6.6,2.1,Iris-virginica\n" + - "4.9,2.5,4.5,1.7,Iris-virginica\n" + - "7.3,2.9,6.3,1.8,Iris-virginica\n" + - "6.7,2.5,5.8,1.8,Iris-virginica\n" + - "7.2,3.6,6.1,2.5,Iris-virginica\n" + - "6.5,3.2,5.1,2.0,Iris-virginica\n" + - "6.4,2.7,5.3,1.9,Iris-virginica\n" + - "6.8,3.0,5.5,2.1,Iris-virginica\n" + - "5.7,2.5,5.0,2.0,Iris-virginica\n" + - "5.8,2.8,5.1,2.4,Iris-virginica\n" + - "6.4,3.2,5.3,2.3,Iris-virginica\n" + - "6.5,3.0,5.5,1.8,Iris-virginica\n" + - "7.7,3.8,6.7,2.2,Iris-virginica\n" + - "7.7,2.6,6.9,2.3,Iris-virginica\n" + - "6.0,2.2,5.0,1.5,Iris-virginica\n" + - "6.9,3.2,5.7,2.3,Iris-virginica\n" + - "5.6,2.8,4.9,2.0,Iris-virginica\n" + - "7.7,2.8,6.7,2.0,Iris-virginica\n" + - "6.3,2.7,4.9,1.8,Iris-virginica\n" + - "6.7,3.3,5.7,2.1,Iris-virginica\n" + - "7.2,3.2,6.0,1.8,Iris-virginica\n" + - "6.2,2.8,4.8,1.8,Iris-virginica\n" + - "6.1,3.0,4.9,1.8,Iris-virginica\n" + - "6.4,2.8,5.6,2.1,Iris-virginica\n" + - "7.2,3.0,5.8,1.6,Iris-virginica\n" + - "7.4,2.8,6.1,1.9,Iris-virginica\n" + - "7.9,3.8,6.4,2.0,Iris-virginica\n" + - "6.4,2.8,5.6,2.2,Iris-virginica\n" + - "6.3,2.8,5.1,1.5,Iris-virginica\n" + - "6.1,2.6,5.6,1.4,Iris-virginica\n" + - "7.7,3.0,6.1,2.3,Iris-virginica\n" + - "6.3,3.4,5.6,2.4,Iris-virginica\n" + - "6.4,3.1,5.5,1.8,Iris-virginica\n" + - "6.0,3.0,4.8,1.8,Iris-virginica\n" + - "6.9,3.1,5.4,2.1,Iris-virginica\n" + - "6.7,3.1,5.6,2.4,Iris-virginica\n" + - "6.9,3.1,5.1,2.3,Iris-virginica\n" + - "5.8,2.7,5.1,1.9,Iris-virginica\n" + - "6.8,3.2,5.9,2.3,Iris-virginica\n" + - "6.7,3.3,5.7,2.5,Iris-virginica\n" + - "6.7,3.0,5.2,2.3,Iris-virginica\n" + - "6.3,2.5,5.0,1.9,Iris-virginica\n" + - "6.5,3.0,5.2,2.0,Iris-virginica\n" + - "6.2,3.4,5.4,2.3,Iris-virginica\n" + - "5.9,3.0,5.1,1.8,Iris-virginica\n" + - "\n"; + "sepal_length,sepal_width,petal_length,petal_width,class_name\n" + "5.1,3.5,1.4,0.2,Iris-setosa\n" + + "4.9,3.0,1.4,0.2,Iris-setosa\n" + + "4.7,3.2,1.3,0.2,Iris-setosa\n" + + "4.6,3.1,1.5,0.2,Iris-setosa\n" + + "5.0,3.6,1.4,0.2,Iris-setosa\n" + + "5.4,3.9,1.7,0.4,Iris-setosa\n" + + "4.6,3.4,1.4,0.3,Iris-setosa\n" + + "5.0,3.4,1.5,0.2,Iris-setosa\n" + + "4.4,2.9,1.4,0.2,Iris-setosa\n" + + "4.9,3.1,1.5,0.1,Iris-setosa\n" + + "5.4,3.7,1.5,0.2,Iris-setosa\n" + + "4.8,3.4,1.6,0.2,Iris-setosa\n" + + "4.8,3.0,1.4,0.1,Iris-setosa\n" + + "4.3,3.0,1.1,0.1,Iris-setosa\n" + + "5.8,4.0,1.2,0.2,Iris-setosa\n" + + "5.7,4.4,1.5,0.4,Iris-setosa\n" + + "5.4,3.9,1.3,0.4,Iris-setosa\n" + + "5.1,3.5,1.4,0.3,Iris-setosa\n" + + "5.7,3.8,1.7,0.3,Iris-setosa\n" + + "5.1,3.8,1.5,0.3,Iris-setosa\n" + + "5.4,3.4,1.7,0.2,Iris-setosa\n" + + "5.1,3.7,1.5,0.4,Iris-setosa\n" + + "4.6,3.6,1.0,0.2,Iris-setosa\n" + + "5.1,3.3,1.7,0.5,Iris-setosa\n" + + "4.8,3.4,1.9,0.2,Iris-setosa\n" + + "5.0,3.0,1.6,0.2,Iris-setosa\n" + + "5.0,3.4,1.6,0.4,Iris-setosa\n" + + "5.2,3.5,1.5,0.2,Iris-setosa\n" + + "5.2,3.4,1.4,0.2,Iris-setosa\n" + + "4.7,3.2,1.6,0.2,Iris-setosa\n" + + "4.8,3.1,1.6,0.2,Iris-setosa\n" + + "5.4,3.4,1.5,0.4,Iris-setosa\n" + + "5.2,4.1,1.5,0.1,Iris-setosa\n" + + "5.5,4.2,1.4,0.2,Iris-setosa\n" + + "4.9,3.1,1.5,0.2,Iris-setosa\n" + + "5.0,3.2,1.2,0.2,Iris-setosa\n" + + "5.5,3.5,1.3,0.2,Iris-setosa\n" + + "4.9,3.6,1.4,0.1,Iris-setosa\n" + + "4.4,3.0,1.3,0.2,Iris-setosa\n" + + "5.1,3.4,1.5,0.2,Iris-setosa\n" + + "5.0,3.5,1.3,0.3,Iris-setosa\n" + + "4.5,2.3,1.3,0.3,Iris-setosa\n" + + "4.4,3.2,1.3,0.2,Iris-setosa\n" + + "5.0,3.5,1.6,0.6,Iris-setosa\n" + + "5.1,3.8,1.9,0.4,Iris-setosa\n" + + "4.8,3.0,1.4,0.3,Iris-setosa\n" + + "5.1,3.8,1.6,0.2,Iris-setosa\n" + + "4.6,3.2,1.4,0.2,Iris-setosa\n" + + "5.3,3.7,1.5,0.2,Iris-setosa\n" + + "5.0,3.3,1.4,0.2,Iris-setosa\n" + + "7.0,3.2,4.7,1.4,Iris-versicolor\n" + + "6.4,3.2,4.5,1.5,Iris-versicolor\n" + + "6.9,3.1,4.9,1.5,Iris-versicolor\n" + + "5.5,2.3,4.0,1.3,Iris-versicolor\n" + + "6.5,2.8,4.6,1.5,Iris-versicolor\n" + + "5.7,2.8,4.5,1.3,Iris-versicolor\n" + + "6.3,3.3,4.7,1.6,Iris-versicolor\n" + + "4.9,2.4,3.3,1.0,Iris-versicolor\n" + + "6.6,2.9,4.6,1.3,Iris-versicolor\n" + + "5.2,2.7,3.9,1.4,Iris-versicolor\n" + + "5.0,2.0,3.5,1.0,Iris-versicolor\n" + + "5.9,3.0,4.2,1.5,Iris-versicolor\n" + + "6.0,2.2,4.0,1.0,Iris-versicolor\n" + + "6.1,2.9,4.7,1.4,Iris-versicolor\n" + + "5.6,2.9,3.6,1.3,Iris-versicolor\n" + + "6.7,3.1,4.4,1.4,Iris-versicolor\n" + + "5.6,3.0,4.5,1.5,Iris-versicolor\n" + + "5.8,2.7,4.1,1.0,Iris-versicolor\n" + + "6.2,2.2,4.5,1.5,Iris-versicolor\n" + + "5.6,2.5,3.9,1.1,Iris-versicolor\n" + + "5.9,3.2,4.8,1.8,Iris-versicolor\n" + + "6.1,2.8,4.0,1.3,Iris-versicolor\n" + + "6.3,2.5,4.9,1.5,Iris-versicolor\n" + + "6.1,2.8,4.7,1.2,Iris-versicolor\n" + + "6.4,2.9,4.3,1.3,Iris-versicolor\n" + + "6.6,3.0,4.4,1.4,Iris-versicolor\n" + + "6.8,2.8,4.8,1.4,Iris-versicolor\n" + + "6.7,3.0,5.0,1.7,Iris-versicolor\n" + + "6.0,2.9,4.5,1.5,Iris-versicolor\n" + + "5.7,2.6,3.5,1.0,Iris-versicolor\n" + + "5.5,2.4,3.8,1.1,Iris-versicolor\n" + + "5.5,2.4,3.7,1.0,Iris-versicolor\n" + + "5.8,2.7,3.9,1.2,Iris-versicolor\n" + + "6.0,2.7,5.1,1.6,Iris-versicolor\n" + + "5.4,3.0,4.5,1.5,Iris-versicolor\n" + + "6.0,3.4,4.5,1.6,Iris-versicolor\n" + + "6.7,3.1,4.7,1.5,Iris-versicolor\n" + + "6.3,2.3,4.4,1.3,Iris-versicolor\n" + + "5.6,3.0,4.1,1.3,Iris-versicolor\n" + + "5.5,2.5,4.0,1.3,Iris-versicolor\n" + + "5.5,2.6,4.4,1.2,Iris-versicolor\n" + + "6.1,3.0,4.6,1.4,Iris-versicolor\n" + + "5.8,2.6,4.0,1.2,Iris-versicolor\n" + + "5.0,2.3,3.3,1.0,Iris-versicolor\n" + + "5.6,2.7,4.2,1.3,Iris-versicolor\n" + + "5.7,3.0,4.2,1.2,Iris-versicolor\n" + + "5.7,2.9,4.2,1.3,Iris-versicolor\n" + + "6.2,2.9,4.3,1.3,Iris-versicolor\n" + + "5.1,2.5,3.0,1.1,Iris-versicolor\n" + + "5.7,2.8,4.1,1.3,Iris-versicolor\n" + + "6.3,3.3,6.0,2.5,Iris-virginica\n" + + "5.8,2.7,5.1,1.9,Iris-virginica\n" + + "7.1,3.0,5.9,2.1,Iris-virginica\n" + + "6.3,2.9,5.6,1.8,Iris-virginica\n" + + "6.5,3.0,5.8,2.2,Iris-virginica\n" + + "7.6,3.0,6.6,2.1,Iris-virginica\n" + + "4.9,2.5,4.5,1.7,Iris-virginica\n" + + "7.3,2.9,6.3,1.8,Iris-virginica\n" + + "6.7,2.5,5.8,1.8,Iris-virginica\n" + + "7.2,3.6,6.1,2.5,Iris-virginica\n" + + "6.5,3.2,5.1,2.0,Iris-virginica\n" + + "6.4,2.7,5.3,1.9,Iris-virginica\n" + + "6.8,3.0,5.5,2.1,Iris-virginica\n" + + "5.7,2.5,5.0,2.0,Iris-virginica\n" + + "5.8,2.8,5.1,2.4,Iris-virginica\n" + + "6.4,3.2,5.3,2.3,Iris-virginica\n" + + "6.5,3.0,5.5,1.8,Iris-virginica\n" + + "7.7,3.8,6.7,2.2,Iris-virginica\n" + + "7.7,2.6,6.9,2.3,Iris-virginica\n" + + "6.0,2.2,5.0,1.5,Iris-virginica\n" + + "6.9,3.2,5.7,2.3,Iris-virginica\n" + + "5.6,2.8,4.9,2.0,Iris-virginica\n" + + "7.7,2.8,6.7,2.0,Iris-virginica\n" + + "6.3,2.7,4.9,1.8,Iris-virginica\n" + + "6.7,3.3,5.7,2.1,Iris-virginica\n" + + "7.2,3.2,6.0,1.8,Iris-virginica\n" + + "6.2,2.8,4.8,1.8,Iris-virginica\n" + + "6.1,3.0,4.9,1.8,Iris-virginica\n" + + "6.4,2.8,5.6,2.1,Iris-virginica\n" + + "7.2,3.0,5.8,1.6,Iris-virginica\n" + + "7.4,2.8,6.1,1.9,Iris-virginica\n" + + "7.9,3.8,6.4,2.0,Iris-virginica\n" + + "6.4,2.8,5.6,2.2,Iris-virginica\n" + + "6.3,2.8,5.1,1.5,Iris-virginica\n" + + "6.1,2.6,5.6,1.4,Iris-virginica\n" + + "7.7,3.0,6.1,2.3,Iris-virginica\n" + + "6.3,3.4,5.6,2.4,Iris-virginica\n" + + "6.4,3.1,5.5,1.8,Iris-virginica\n" + + "6.0,3.0,4.8,1.8,Iris-virginica\n" + + "6.9,3.1,5.4,2.1,Iris-virginica\n" + + "6.7,3.1,5.6,2.4,Iris-virginica\n" + + "6.9,3.1,5.1,2.3,Iris-virginica\n" + + "5.8,2.7,5.1,1.9,Iris-virginica\n" + + "6.8,3.2,5.9,2.3,Iris-virginica\n" + + "6.7,3.3,5.7,2.5,Iris-virginica\n" + + "6.7,3.0,5.2,2.3,Iris-virginica\n" + + "6.3,2.5,5.0,1.9,Iris-virginica\n" + + "6.5,3.0,5.2,2.0,Iris-virginica\n" + + "6.2,3.4,5.4,2.3,Iris-virginica\n" + + "5.9,3.0,5.1,1.8,Iris-virginica\n" + + "\n"; } diff --git a/driver/src/test/java/org/neo4j/driver/integration/LoggingIT.java b/driver/src/test/java/org/neo4j/driver/integration/LoggingIT.java index 5671577e2e..0b6fef5894 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/LoggingIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/LoggingIT.java @@ -18,9 +18,15 @@ */ package org.neo4j.driver.integration; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; @@ -30,45 +36,32 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - @ParallelizableIT -class LoggingIT -{ +class LoggingIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - void logShouldRecordDebugAndTraceInfo() - { + void logShouldRecordDebugAndTraceInfo() { // Given - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - when( logger.isDebugEnabled() ).thenReturn( true ); - when( logger.isTraceEnabled() ).thenReturn( true ); + when(logging.getLog(any(Class.class))).thenReturn(logger); + when(logger.isDebugEnabled()).thenReturn(true); + when(logger.isTraceEnabled()).thenReturn(true); - Config config = Config.builder() - .withLogging( logging ) - .build(); + Config config = Config.builder().withLogging(logging).build(); - try ( Driver driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), config ) ) - { + try (Driver driver = GraphDatabase.driver(neo4j.uri(), neo4j.authToken(), config)) { // When - try ( Session session = driver.session() ) - { - session.run( "CREATE (a {name:'Cat'})" ); + try (Session session = driver.session()) { + session.run("CREATE (a {name:'Cat'})"); } } // Then - verify( logger, atLeastOnce() ).debug( anyString(), any( Object[].class ) ); - verify( logger, atLeastOnce() ).trace( anyString(), any() ); + verify(logger, atLeastOnce()).debug(anyString(), any(Object[].class)); + verify(logger, atLeastOnce()).trace(anyString(), any()); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/MetricsIT.java b/driver/src/test/java/org/neo4j/driver/integration/MetricsIT.java index 4c777a90ef..70d74f7bfa 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/MetricsIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/MetricsIT.java @@ -18,6 +18,9 @@ */ package org.neo4j.driver.integration; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.neo4j.driver.Values.parameters; + import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; @@ -25,23 +28,17 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.RegisterExtension; - import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.MetricsAdapter; import org.neo4j.driver.QueryRunner; import org.neo4j.driver.Result; -import org.neo4j.driver.internal.metrics.MicrometerMetricsProvider; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.neo4j.driver.Values.parameters; - @ParallelizableIT -class MetricsIT -{ +class MetricsIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @@ -49,45 +46,45 @@ class MetricsIT private MeterRegistry meterRegistry = new SimpleMeterRegistry(); @BeforeEach - void createDriver() - { - driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), - Config.builder().withMetricsAdapter( MetricsAdapter.MICROMETER ).build() ); + void createDriver() { + driver = GraphDatabase.driver( + neo4j.uri(), + neo4j.authToken(), + Config.builder().withMetricsAdapter(MetricsAdapter.MICROMETER).build()); } @AfterEach - void closeDriver() - { + void closeDriver() { driver.close(); } @Test - void driverMetricsUpdatedWithDriverUse() - { - Result result = createNodesInNewSession( 12 ); + void driverMetricsUpdatedWithDriverUse() { + Result result = createNodesInNewSession(12); // assert in use - Timer acquisitionTimer = meterRegistry.get( "neo4j.driver.connections.acquisition" ).timer(); - Timer creationTimer = meterRegistry.get( "neo4j.driver.connections.creation" ).timer(); - Timer usageTimer = meterRegistry.get( "neo4j.driver.connections.usage" ).timer(); - assertEquals( 1, acquisitionTimer.count() ); - assertEquals( 1, creationTimer.count() ); - assertEquals( 0, usageTimer.count() ); + Timer acquisitionTimer = + meterRegistry.get("neo4j.driver.connections.acquisition").timer(); + Timer creationTimer = + meterRegistry.get("neo4j.driver.connections.creation").timer(); + Timer usageTimer = meterRegistry.get("neo4j.driver.connections.usage").timer(); + assertEquals(1, acquisitionTimer.count()); + assertEquals(1, creationTimer.count()); + assertEquals(0, usageTimer.count()); result.consume(); // assert released - assertEquals( 1, acquisitionTimer.count() ); - assertEquals( 1, creationTimer.count() ); - assertEquals( 1, usageTimer.count() ); + assertEquals(1, acquisitionTimer.count()); + assertEquals(1, creationTimer.count()); + assertEquals(1, usageTimer.count()); } - private Result createNodesInNewSession( int nodesToCreate ) - { - return createNodes( nodesToCreate, driver.session() ); + private Result createNodesInNewSession(int nodesToCreate) { + return createNodes(nodesToCreate, driver.session()); } - private Result createNodes( int nodesToCreate, QueryRunner queryRunner ) - { - return queryRunner.run( "UNWIND range(1, $nodesToCreate) AS i CREATE (n {index: i}) RETURN n", - parameters( "nodesToCreate", nodesToCreate ) ); + private Result createNodes(int nodesToCreate, QueryRunner queryRunner) { + return queryRunner.run( + "UNWIND range(1, $nodesToCreate) AS i CREATE (n {index: i}) RETURN n", + parameters("nodesToCreate", nodesToCreate)); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/NestedQueries.java b/driver/src/test/java/org/neo4j/driver/integration/NestedQueries.java index 3d1648e50e..f18ab770a9 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/NestedQueries.java +++ b/driver/src/test/java/org/neo4j/driver/integration/NestedQueries.java @@ -18,157 +18,136 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import java.util.List; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.AccessMode; +import org.neo4j.driver.QueryRunner; import org.neo4j.driver.Record; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; -import org.neo4j.driver.QueryRunner; +import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -public interface NestedQueries -{ +public interface NestedQueries { String OUTER_QUERY = "UNWIND range(1, 10000) AS x RETURN x"; String INNER_QUERY = "UNWIND range(1, 10) AS y RETURN y"; int EXPECTED_RECORDS = 10_000 * 10 + 10_000; - Session newSession( AccessMode mode ); + Session newSession(AccessMode mode); @Test - default void shouldAllowNestedQueriesInTransactionConsumedAsIterators() throws Exception - { - try ( Session session = newSession( AccessMode.READ ); Transaction tx = session.beginTransaction() ) - { - testNestedQueriesConsumedAsIterators( tx ); + default void shouldAllowNestedQueriesInTransactionConsumedAsIterators() throws Exception { + try (Session session = newSession(AccessMode.READ); + Transaction tx = session.beginTransaction()) { + testNestedQueriesConsumedAsIterators(tx); tx.commit(); } } @Test - default void shouldAllowNestedQueriesInTransactionConsumedAsLists() throws Exception - { - try ( Session session = newSession( AccessMode.READ ); Transaction tx = session.beginTransaction() ) - { - testNestedQueriesConsumedAsLists( tx ); + default void shouldAllowNestedQueriesInTransactionConsumedAsLists() throws Exception { + try (Session session = newSession(AccessMode.READ); + Transaction tx = session.beginTransaction()) { + testNestedQueriesConsumedAsLists(tx); tx.commit(); } } @Test - default void shouldAllowNestedQueriesInTransactionConsumedAsIteratorAndList() throws Exception - { - try ( Session session = newSession( AccessMode.READ ); Transaction tx = session.beginTransaction() ) - { - testNestedQueriesConsumedAsIteratorAndList( tx ); + default void shouldAllowNestedQueriesInTransactionConsumedAsIteratorAndList() throws Exception { + try (Session session = newSession(AccessMode.READ); + Transaction tx = session.beginTransaction()) { + testNestedQueriesConsumedAsIteratorAndList(tx); tx.commit(); } } @Test - default void shouldAllowNestedQueriesInSessionConsumedAsIterators() throws Exception - { - try ( Session session = newSession( AccessMode.READ ) ) - { - testNestedQueriesConsumedAsIterators( session ); + default void shouldAllowNestedQueriesInSessionConsumedAsIterators() throws Exception { + try (Session session = newSession(AccessMode.READ)) { + testNestedQueriesConsumedAsIterators(session); } } @Test - default void shouldAllowNestedQueriesInSessionConsumedAsLists() throws Exception - { - try ( Session session = newSession( AccessMode.READ ) ) - { - testNestedQueriesConsumedAsLists( session ); + default void shouldAllowNestedQueriesInSessionConsumedAsLists() throws Exception { + try (Session session = newSession(AccessMode.READ)) { + testNestedQueriesConsumedAsLists(session); } } @Test - default void shouldAllowNestedQueriesInSessionConsumedAsIteratorAndList() throws Exception - { - try ( Session session = newSession( AccessMode.READ ) ) - { - testNestedQueriesConsumedAsIteratorAndList( session ); + default void shouldAllowNestedQueriesInSessionConsumedAsIteratorAndList() throws Exception { + try (Session session = newSession(AccessMode.READ)) { + testNestedQueriesConsumedAsIteratorAndList(session); } } - default void testNestedQueriesConsumedAsIterators( QueryRunner queryRunner) throws Exception - { + default void testNestedQueriesConsumedAsIterators(QueryRunner queryRunner) throws Exception { int recordsSeen = 0; - Result result1 = queryRunner.run( OUTER_QUERY ); - Thread.sleep( 1000 ); // allow some result records to arrive and be buffered + Result result1 = queryRunner.run(OUTER_QUERY); + Thread.sleep(1000); // allow some result records to arrive and be buffered - while ( result1.hasNext() ) - { + while (result1.hasNext()) { Record record1 = result1.next(); - assertFalse( record1.get( "x" ).isNull() ); + assertFalse(record1.get("x").isNull()); recordsSeen++; - Result result2 = queryRunner.run( INNER_QUERY ); - while ( result2.hasNext() ) - { + Result result2 = queryRunner.run(INNER_QUERY); + while (result2.hasNext()) { Record record2 = result2.next(); - assertFalse( record2.get( "y" ).isNull() ); + assertFalse(record2.get("y").isNull()); recordsSeen++; } } - assertEquals( EXPECTED_RECORDS, recordsSeen ); + assertEquals(EXPECTED_RECORDS, recordsSeen); } - default void testNestedQueriesConsumedAsLists( QueryRunner queryRunner) throws Exception - { + default void testNestedQueriesConsumedAsLists(QueryRunner queryRunner) throws Exception { int recordsSeen = 0; - Result result1 = queryRunner.run( OUTER_QUERY ); - Thread.sleep( 1000 ); // allow some result records to arrive and be buffered + Result result1 = queryRunner.run(OUTER_QUERY); + Thread.sleep(1000); // allow some result records to arrive and be buffered List records1 = result1.list(); - for ( Record record1 : records1 ) - { - assertFalse( record1.get( "x" ).isNull() ); + for (Record record1 : records1) { + assertFalse(record1.get("x").isNull()); recordsSeen++; - Result result2 = queryRunner.run( "UNWIND range(1, 10) AS y RETURN y" ); + Result result2 = queryRunner.run("UNWIND range(1, 10) AS y RETURN y"); List records2 = result2.list(); - for ( Record record2 : records2 ) - { - assertFalse( record2.get( "y" ).isNull() ); + for (Record record2 : records2) { + assertFalse(record2.get("y").isNull()); recordsSeen++; } } - assertEquals( EXPECTED_RECORDS, recordsSeen ); + assertEquals(EXPECTED_RECORDS, recordsSeen); } - default void testNestedQueriesConsumedAsIteratorAndList( QueryRunner queryRunner) throws Exception - { + default void testNestedQueriesConsumedAsIteratorAndList(QueryRunner queryRunner) throws Exception { int recordsSeen = 0; - Result result1 = queryRunner.run( OUTER_QUERY ); - Thread.sleep( 1000 ); // allow some result records to arrive and be buffered + Result result1 = queryRunner.run(OUTER_QUERY); + Thread.sleep(1000); // allow some result records to arrive and be buffered - while ( result1.hasNext() ) - { + while (result1.hasNext()) { Record record1 = result1.next(); - assertFalse( record1.get( "x" ).isNull() ); + assertFalse(record1.get("x").isNull()); recordsSeen++; - Result result2 = queryRunner.run( "UNWIND range(1, 10) AS y RETURN y" ); + Result result2 = queryRunner.run("UNWIND range(1, 10) AS y RETURN y"); List records2 = result2.list(); - for ( Record record2 : records2 ) - { - assertFalse( record2.get( "y" ).isNull() ); + for (Record record2 : records2) { + assertFalse(record2.get("y").isNull()); recordsSeen++; } } - assertEquals( EXPECTED_RECORDS, recordsSeen ); + assertEquals(EXPECTED_RECORDS, recordsSeen); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/NestedQueriesIT.java b/driver/src/test/java/org/neo4j/driver/integration/NestedQueriesIT.java index 186b9874d4..beeb16ea1c 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/NestedQueriesIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/NestedQueriesIT.java @@ -18,24 +18,21 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.extension.RegisterExtension; +import static org.neo4j.driver.SessionConfig.builder; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Session; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.neo4j.driver.SessionConfig.builder; - @ParallelizableIT -public class NestedQueriesIT implements NestedQueries -{ +public class NestedQueriesIT implements NestedQueries { @RegisterExtension static final DatabaseExtension server = new DatabaseExtension(); @Override - public Session newSession( AccessMode mode ) - { - return server.driver().session( builder().withDefaultAccessMode( mode ).build() ); + public Session newSession(AccessMode mode) { + return server.driver().session(builder().withDefaultAccessMode(mode).build()); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/ParametersIT.java b/driver/src/test/java/org/neo4j/driver/integration/ParametersIT.java index 2c70c68e5d..eb89acc37e 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ParametersIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ParametersIT.java @@ -18,8 +18,21 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonMap; +import static java.util.stream.Collectors.toList; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.Values.ofInteger; +import static org.neo4j.driver.Values.ofValue; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; import java.io.IOException; import java.util.HashMap; @@ -27,7 +40,8 @@ import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.Value; @@ -38,473 +52,384 @@ import org.neo4j.driver.util.SessionExtension; import org.neo4j.driver.util.TestUtil; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonMap; -import static java.util.stream.Collectors.toList; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.Values.ofInteger; -import static org.neo4j.driver.Values.ofValue; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; - @ParallelizableIT -class ParametersIT -{ +class ParametersIT { private static final int LONG_VALUE_SIZE = 1_000_000; @RegisterExtension static final SessionExtension session = new SessionExtension(); @Test - void shouldBeAbleToSetAndReturnBooleanProperty() - { + void shouldBeAbleToSetAndReturnBooleanProperty() { // When - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", true ) ); + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", true)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().BOOLEAN() ), equalTo( true ) ); - assertThat( value.asBoolean(), equalTo( true ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().BOOLEAN()), equalTo(true)); + assertThat(value.asBoolean(), equalTo(true)); } } @Test - void shouldBeAbleToSetAndReturnByteProperty() - { + void shouldBeAbleToSetAndReturnByteProperty() { // When - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", (byte) 1 ) ); + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", (byte) 1)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().INTEGER() ), equalTo( true ) ); - assertThat( value.asLong(), equalTo( 1L ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().INTEGER()), equalTo(true)); + assertThat(value.asLong(), equalTo(1L)); } } @Test - void shouldBeAbleToSetAndReturnShortProperty() - { + void shouldBeAbleToSetAndReturnShortProperty() { // When - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", (short) 1 ) ); + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", (short) 1)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().INTEGER() ), equalTo( true ) ); - assertThat( value.asLong(), equalTo( 1L ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().INTEGER()), equalTo(true)); + assertThat(value.asLong(), equalTo(1L)); } } @Test - void shouldBeAbleToSetAndReturnIntegerProperty() - { + void shouldBeAbleToSetAndReturnIntegerProperty() { // When - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", 1 ) ); + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", 1)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().INTEGER() ), equalTo( true ) ); - assertThat( value.asLong(), equalTo( 1L ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().INTEGER()), equalTo(true)); + assertThat(value.asLong(), equalTo(1L)); } - } @Test - void shouldBeAbleToSetAndReturnLongProperty() - { + void shouldBeAbleToSetAndReturnLongProperty() { // When - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", 1L ) ); + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", 1L)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().INTEGER() ), equalTo( true ) ); - assertThat( value.asLong(), equalTo( 1L ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().INTEGER()), equalTo(true)); + assertThat(value.asLong(), equalTo(1L)); } - } @Test - void shouldBeAbleToSetAndReturnDoubleProperty() - { + void shouldBeAbleToSetAndReturnDoubleProperty() { // When - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", 6.28 ) ); + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", 6.28)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().FLOAT() ), equalTo( true ) ); - assertThat( value.asDouble(), equalTo( 6.28 ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().FLOAT()), equalTo(true)); + assertThat(value.asDouble(), equalTo(6.28)); } } @Test - void shouldBeAbleToSetAndReturnBytesProperty() - { - testBytesProperty( new byte[0] ); - for ( int i = 0; i < 16; i++ ) - { - int length = (int) Math.pow( 2, i ); - testBytesProperty( randomByteArray( length ) ); - testBytesProperty( randomByteArray( length - 1 ) ); + void shouldBeAbleToSetAndReturnBytesProperty() { + testBytesProperty(new byte[0]); + for (int i = 0; i < 16; i++) { + int length = (int) Math.pow(2, i); + testBytesProperty(randomByteArray(length)); + testBytesProperty(randomByteArray(length - 1)); } } @Test - void shouldBeAbleToSetAndReturnStringProperty() - { - testStringProperty( "" ); - testStringProperty( "π≈3.14" ); - testStringProperty( "Mjölnir" ); - testStringProperty( "*** Hello World! ***" ); + void shouldBeAbleToSetAndReturnStringProperty() { + testStringProperty(""); + testStringProperty("π≈3.14"); + testStringProperty("Mjölnir"); + testStringProperty("*** Hello World! ***"); } @Test - void shouldBeAbleToSetAndReturnBooleanArrayProperty() - { + void shouldBeAbleToSetAndReturnBooleanArrayProperty() { // When - boolean[] arrayValue = new boolean[]{true, true, true}; - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", arrayValue ) ); + boolean[] arrayValue = new boolean[] {true, true, true}; + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", arrayValue)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().LIST() ), equalTo( true ) ); - assertThat( value.size(), equalTo( 3 ) ); - for ( Value item : value.asList( ofValue() ) ) - { - assertThat( item.hasType( session.typeSystem().BOOLEAN() ), equalTo( true ) ); - assertThat( item.asBoolean(), equalTo( true ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().LIST()), equalTo(true)); + assertThat(value.size(), equalTo(3)); + for (Value item : value.asList(ofValue())) { + assertThat(item.hasType(session.typeSystem().BOOLEAN()), equalTo(true)); + assertThat(item.asBoolean(), equalTo(true)); } } - } @Test - void shouldBeAbleToSetAndReturnIntegerArrayProperty() - { + void shouldBeAbleToSetAndReturnIntegerArrayProperty() { // When - int[] arrayValue = new int[]{42, 42, 42}; - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", arrayValue ) ); + int[] arrayValue = new int[] {42, 42, 42}; + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", arrayValue)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().LIST() ), equalTo( true ) ); - assertThat( value.size(), equalTo( 3 ) ); - for ( Value item : value.asList( ofValue() ) ) - { - assertThat( item.hasType( session.typeSystem().INTEGER() ), equalTo( true ) ); - assertThat( item.asLong(), equalTo( 42L ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().LIST()), equalTo(true)); + assertThat(value.size(), equalTo(3)); + for (Value item : value.asList(ofValue())) { + assertThat(item.hasType(session.typeSystem().INTEGER()), equalTo(true)); + assertThat(item.asLong(), equalTo(42L)); } } - } @Test - void shouldBeAbleToSetAndReturnDoubleArrayProperty() - { + void shouldBeAbleToSetAndReturnDoubleArrayProperty() { // When - double[] arrayValue = new double[]{6.28, 6.28, 6.28}; - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", arrayValue ) ); + double[] arrayValue = new double[] {6.28, 6.28, 6.28}; + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", arrayValue)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().LIST() ), equalTo( true ) ); - assertThat( value.size(), equalTo( 3 ) ); - for ( Value item : value.asList( ofValue()) ) - { - assertThat( item.hasType( session.typeSystem().FLOAT() ), equalTo( true ) ); - assertThat( item.asDouble(), equalTo( 6.28 ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().LIST()), equalTo(true)); + assertThat(value.size(), equalTo(3)); + for (Value item : value.asList(ofValue())) { + assertThat(item.hasType(session.typeSystem().FLOAT()), equalTo(true)); + assertThat(item.asDouble(), equalTo(6.28)); } } } @Test - void shouldBeAbleToSetAndReturnStringArrayProperty() - { - testStringArrayContaining( "cat" ); - testStringArrayContaining( "Mjölnir" ); + void shouldBeAbleToSetAndReturnStringArrayProperty() { + testStringArrayContaining("cat"); + testStringArrayContaining("Mjölnir"); } - private static void testStringArrayContaining( String str ) - { - String[] arrayValue = new String[]{str, str, str}; + private static void testStringArrayContaining(String str) { + String[] arrayValue = new String[] {str, str, str}; - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", arrayValue ) ); + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", arrayValue)); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().LIST() ), equalTo( true ) ); - assertThat( value.size(), equalTo( 3 ) ); - for ( Value item : value.asList( ofValue()) ) - { - assertThat( item.hasType( session.typeSystem().STRING() ), equalTo( true ) ); - assertThat( item.asString(), equalTo( str ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().LIST()), equalTo(true)); + assertThat(value.size(), equalTo(3)); + for (Value item : value.asList(ofValue())) { + assertThat(item.hasType(session.typeSystem().STRING()), equalTo(true)); + assertThat(item.asString(), equalTo(str)); } } } @Test - void shouldHandleLargeString() - { + void shouldHandleLargeString() { // Given char[] bigStr = new char[1024 * 10]; - for ( int i = 0; i < bigStr.length; i+=4 ) - { + for (int i = 0; i < bigStr.length; i += 4) { bigStr[i] = 'a'; - bigStr[i+1] = 'b'; - bigStr[i+2] = 'c'; - bigStr[i+3] = 'd'; + bigStr[i + 1] = 'b'; + bigStr[i + 2] = 'c'; + bigStr[i + 3] = 'd'; } - String bigString = new String( bigStr ); + String bigString = new String(bigStr); // When - Value val = session.run( "RETURN $p AS p", parameters( "p", bigString ) ).peek().get( "p" ); + Value val = + session.run("RETURN $p AS p", parameters("p", bigString)).peek().get("p"); // Then - assertThat( val.asString(), equalTo( bigString ) ); + assertThat(val.asString(), equalTo(bigString)); } @Test - void shouldBeAbleToSetAndReturnBooleanPropertyWithinMap() - { + void shouldBeAbleToSetAndReturnBooleanPropertyWithinMap() { // When - Result result = session.run( - "CREATE (a {value:$value.v}) RETURN a.value", - parameters( "value", parameters( "v", true ) ) ); + Result result = + session.run("CREATE (a {value:$value.v}) RETURN a.value", parameters("value", parameters("v", true))); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().BOOLEAN() ), equalTo( true ) ); - assertThat( value.asBoolean(), equalTo( true ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().BOOLEAN()), equalTo(true)); + assertThat(value.asBoolean(), equalTo(true)); } - } @Test - void shouldBeAbleToSetAndReturnIntegerPropertyWithinMap() - { + void shouldBeAbleToSetAndReturnIntegerPropertyWithinMap() { // When - Result result = session.run( - "CREATE (a {value:$value.v}) RETURN a.value", - parameters( "value", parameters( "v", 42 ) ) ); + Result result = + session.run("CREATE (a {value:$value.v}) RETURN a.value", parameters("value", parameters("v", 42))); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().INTEGER() ), equalTo( true ) ); - assertThat( value.asLong(), equalTo( 42L ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().INTEGER()), equalTo(true)); + assertThat(value.asLong(), equalTo(42L)); } - } @Test - void shouldBeAbleToSetAndReturnDoublePropertyWithinMap() - { + void shouldBeAbleToSetAndReturnDoublePropertyWithinMap() { // When - Result result = session.run( - "CREATE (a {value:$value.v}) RETURN a.value", - parameters( "value", parameters( "v", 6.28 ) ) ); + Result result = + session.run("CREATE (a {value:$value.v}) RETURN a.value", parameters("value", parameters("v", 6.28))); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().FLOAT() ), equalTo( true ) ); - assertThat( value.asDouble(), equalTo( 6.28 ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().FLOAT()), equalTo(true)); + assertThat(value.asDouble(), equalTo(6.28)); } - } @Test - void shouldBeAbleToSetAndReturnStringPropertyWithinMap() - { + void shouldBeAbleToSetAndReturnStringPropertyWithinMap() { // When Result result = session.run( - "CREATE (a {value:$value.v}) RETURN a.value", - parameters( "value", parameters( "v", "Mjölnir" ) ) ); + "CREATE (a {value:$value.v}) RETURN a.value", parameters("value", parameters("v", "Mjölnir"))); // Then - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().STRING() ), equalTo( true ) ); - assertThat( value.asString(), equalTo( "Mjölnir" ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().STRING()), equalTo(true)); + assertThat(value.asString(), equalTo("Mjölnir")); } } @Test - void settingInvalidParameterTypeShouldThrowHelpfulError() - { - ClientException e = assertThrows( ClientException.class, () -> session.run( "anything", parameters( "k", new Object() ) ) ); - assertEquals( "Unable to convert java.lang.Object to Neo4j Value.", e.getMessage() ); + void settingInvalidParameterTypeShouldThrowHelpfulError() { + ClientException e = + assertThrows(ClientException.class, () -> session.run("anything", parameters("k", new Object()))); + assertEquals("Unable to convert java.lang.Object to Neo4j Value.", e.getMessage()); } @Test - void settingInvalidParameterTypeDirectlyShouldThrowHelpfulError() - { - IllegalArgumentException e = assertThrows( IllegalArgumentException.class, () -> session.run( "anything", emptyNodeValue() ) ); - assertEquals( "The parameters should be provided as Map type. Unsupported parameters type: NODE", e.getMessage() ); + void settingInvalidParameterTypeDirectlyShouldThrowHelpfulError() { + IllegalArgumentException e = + assertThrows(IllegalArgumentException.class, () -> session.run("anything", emptyNodeValue())); + assertEquals( + "The parameters should be provided as Map type. Unsupported parameters type: NODE", e.getMessage()); } @Test - void shouldNotBePossibleToUseNodeAsParameterInMapValue() - { + void shouldNotBePossibleToUseNodeAsParameterInMapValue() { // GIVEN Value node = emptyNodeValue(); - Map params = new HashMap<>(); - params.put( "a", node ); - MapValue mapValue = new MapValue( params ); + Map params = new HashMap<>(); + params.put("a", node); + MapValue mapValue = new MapValue(params); // WHEN - expectIOExceptionWithMessage( mapValue, "Unknown type: NODE" ); + expectIOExceptionWithMessage(mapValue, "Unknown type: NODE"); } @Test - void shouldNotBePossibleToUseRelationshipAsParameterViaMapValue() - { + void shouldNotBePossibleToUseRelationshipAsParameterViaMapValue() { // GIVEN Value relationship = emptyRelationshipValue(); - Map params = new HashMap<>(); - params.put( "a", relationship ); - MapValue mapValue = new MapValue( params ); + Map params = new HashMap<>(); + params.put("a", relationship); + MapValue mapValue = new MapValue(params); // WHEN - expectIOExceptionWithMessage( mapValue, "Unknown type: RELATIONSHIP" ); + expectIOExceptionWithMessage(mapValue, "Unknown type: RELATIONSHIP"); } @Test - void shouldNotBePossibleToUsePathAsParameterViaMapValue() - { + void shouldNotBePossibleToUsePathAsParameterViaMapValue() { // GIVEN Value path = filledPathValue(); - Map params = new HashMap<>(); - params.put( "a", path ); - MapValue mapValue = new MapValue( params ); + Map params = new HashMap<>(); + params.put("a", path); + MapValue mapValue = new MapValue(params); // WHEN - expectIOExceptionWithMessage( mapValue, "Unknown type: PATH" ); + expectIOExceptionWithMessage(mapValue, "Unknown type: PATH"); } @Test - void shouldSendAndReceiveLongString() - { - String string = TestUtil.randomString( LONG_VALUE_SIZE ); - testSendAndReceiveValue( string ); + void shouldSendAndReceiveLongString() { + String string = TestUtil.randomString(LONG_VALUE_SIZE); + testSendAndReceiveValue(string); } @Test - void shouldSendAndReceiveLongListOfLongs() - { - List longs = ThreadLocalRandom.current() - .longs( LONG_VALUE_SIZE ) - .boxed() - .collect( toList() ); + void shouldSendAndReceiveLongListOfLongs() { + List longs = + ThreadLocalRandom.current().longs(LONG_VALUE_SIZE).boxed().collect(toList()); - testSendAndReceiveValue( longs ); + testSendAndReceiveValue(longs); } @Test - void shouldSendAndReceiveLongArrayOfBytes() - { + void shouldSendAndReceiveLongArrayOfBytes() { byte[] bytes = new byte[LONG_VALUE_SIZE]; - ThreadLocalRandom.current().nextBytes( bytes ); + ThreadLocalRandom.current().nextBytes(bytes); - testSendAndReceiveValue( bytes ); + testSendAndReceiveValue(bytes); } @Test - void shouldAcceptStreamsAsQueryParameters() - { - Stream stream = Stream.of( 1, 2, 3, 4, 5, 42 ); + void shouldAcceptStreamsAsQueryParameters() { + Stream stream = Stream.of(1, 2, 3, 4, 5, 42); - Result result = session.run( "RETURN $value", singletonMap( "value", stream ) ); - Value receivedValue = result.single().get( 0 ); + Result result = session.run("RETURN $value", singletonMap("value", stream)); + Value receivedValue = result.single().get(0); - assertEquals( asList( 1, 2, 3, 4, 5, 42 ), receivedValue.asList( ofInteger() ) ); + assertEquals(asList(1, 2, 3, 4, 5, 42), receivedValue.asList(ofInteger())); } - private static void testBytesProperty( byte[] array ) - { - Result result = session.run( "CREATE (a {value:$value}) RETURN a.value", parameters( "value", array ) ); + private static void testBytesProperty(byte[] array) { + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", array)); - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().BYTES() ), equalTo( true ) ); - assertThat( value.asByteArray(), equalTo( array ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().BYTES()), equalTo(true)); + assertThat(value.asByteArray(), equalTo(array)); } } - private static void testStringProperty( String string ) - { - Result result = session.run( - "CREATE (a {value:$value}) RETURN a.value", parameters( "value", string ) ); + private static void testStringProperty(String string) { + Result result = session.run("CREATE (a {value:$value}) RETURN a.value", parameters("value", string)); - for ( Record record : result.list() ) - { - Value value = record.get( "a.value" ); - assertThat( value.hasType( session.typeSystem().STRING() ), equalTo( true ) ); - assertThat( value.asString(), equalTo( string ) ); + for (Record record : result.list()) { + Value value = record.get("a.value"); + assertThat(value.hasType(session.typeSystem().STRING()), equalTo(true)); + assertThat(value.asString(), equalTo(string)); } } - private static byte[] randomByteArray( int length ) - { + private static byte[] randomByteArray(int length) { byte[] result = new byte[length]; - ThreadLocalRandom.current().nextBytes( result ); + ThreadLocalRandom.current().nextBytes(result); return result; } - private static void expectIOExceptionWithMessage( Value value, String message ) - { - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, () -> session.run( "RETURN {a}", value ).consume() ); + private static void expectIOExceptionWithMessage(Value value, String message) { + ServiceUnavailableException e = + assertThrows(ServiceUnavailableException.class, () -> session.run("RETURN {a}", value) + .consume()); Throwable cause = e.getCause(); - assertThat( cause, instanceOf( IOException.class ) ); - assertThat( cause.getMessage(), equalTo( message ) ); + assertThat(cause, instanceOf(IOException.class)); + assertThat(cause.getMessage(), equalTo(message)); } - private static void testSendAndReceiveValue( Object value ) - { - Result result = session.run( "RETURN $value", singletonMap( "value", value ) ); - Object receivedValue = result.single().get( 0 ).asObject(); - assertArrayEquals( new Object[]{value}, new Object[]{receivedValue} ); + private static void testSendAndReceiveValue(Object value) { + Result result = session.run("RETURN $value", singletonMap("value", value)); + Object receivedValue = result.single().get(0).asObject(); + assertArrayEquals(new Object[] {value}, new Object[] {receivedValue}); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/QueryIT.java b/driver/src/test/java/org/neo4j/driver/integration/QueryIT.java index c696756645..182237faf2 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/QueryIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/QueryIT.java @@ -18,18 +18,19 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.api.function.Executable; +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; -import java.io.PrintWriter; -import java.io.StringWriter; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.Value; @@ -37,166 +38,144 @@ import org.neo4j.driver.util.ParallelizableIT; import org.neo4j.driver.util.SessionExtension; -import static java.util.Arrays.asList; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; - @ParallelizableIT -class QueryIT -{ +class QueryIT { @RegisterExtension static final SessionExtension session = new SessionExtension(); @Test - void shouldRunWithResult() - { + void shouldRunWithResult() { // When I execute a query that yields a result - List result = session.run( "UNWIND [1,2,3] AS k RETURN k" ).list(); + List result = session.run("UNWIND [1,2,3] AS k RETURN k").list(); // Then the result object should contain the returned values - assertThat( result.size(), equalTo( 3 ) ); + assertThat(result.size(), equalTo(3)); // And it should allow random access - assertThat( result.get( 0 ).get( "k" ).asLong(), equalTo( 1L ) ); - assertThat( result.get( 1 ).get( "k" ).asLong(), equalTo( 2L ) ); - assertThat( result.get( 2 ).get( "k" ).asLong(), equalTo( 3L ) ); + assertThat(result.get(0).get("k").asLong(), equalTo(1L)); + assertThat(result.get(1).get("k").asLong(), equalTo(2L)); + assertThat(result.get(2).get("k").asLong(), equalTo(3L)); // And it should allow iteration long expected = 0; - for ( Record value : result ) - { + for (Record value : result) { expected += 1; - assertThat( value.get( "k" ), equalTo( Values.value( expected ) ) ); + assertThat(value.get("k"), equalTo(Values.value(expected))); } - assertThat( expected, equalTo( 3L ) ); + assertThat(expected, equalTo(3L)); } @Test - void shouldRunWithParameters() - { + void shouldRunWithParameters() { // When - session.run( "CREATE (n:FirstNode {name:$name})", parameters( "name", "Steven" ) ); + session.run("CREATE (n:FirstNode {name:$name})", parameters("name", "Steven")); // Then nothing should've failed } - @SuppressWarnings( "ConstantConditions" ) + @SuppressWarnings("ConstantConditions") @Test - void shouldRunWithNullValuesAsParameters() - { + void shouldRunWithNullValuesAsParameters() { // Given Value params = null; // When - session.run( "CREATE (n:FirstNode {name:'Steven'})", params ); + session.run("CREATE (n:FirstNode {name:'Steven'})", params); // Then nothing should've failed } - @SuppressWarnings( "ConstantConditions" ) + @SuppressWarnings("ConstantConditions") @Test - void shouldRunWithNullRecordAsParameters() - { + void shouldRunWithNullRecordAsParameters() { // Given Record params = null; // When - session.run( "CREATE (n:FirstNode {name:'Steven'})", params ); + session.run("CREATE (n:FirstNode {name:'Steven'})", params); // Then nothing should've failed } - @SuppressWarnings( "ConstantConditions" ) + @SuppressWarnings("ConstantConditions") @Test - void shouldRunWithNullMapAsParameters() - { + void shouldRunWithNullMapAsParameters() { // Given Map params = null; // When - session.run( "CREATE (n:FirstNode {name:'Steven'})", params ); + session.run("CREATE (n:FirstNode {name:'Steven'})", params); // Then nothing should've failed } @Test - void shouldRunWithCollectionAsParameter() - { + void shouldRunWithCollectionAsParameter() { // When - session.run( "RETURN $param", parameters( "param", Collections.singleton( "FOO" ) ) ); + session.run("RETURN $param", parameters("param", Collections.singleton("FOO"))); // Then nothing should've failed } @Test - void shouldRunWithIteratorAsParameter() - { - Iterator values = asList( "FOO", "BAR", "BAZ" ).iterator(); + void shouldRunWithIteratorAsParameter() { + Iterator values = asList("FOO", "BAR", "BAZ").iterator(); // When - session.run( "RETURN $param", parameters( "param", values ) ); + session.run("RETURN $param", parameters("param", values)); // Then nothing should've failed } @Test - void shouldRun() - { + void shouldRun() { // When - session.run( "CREATE (n:FirstNode)" ); + session.run("CREATE (n:FirstNode)"); // Then nothing should've failed } @Test - void shouldRunParameterizedWithResult() - { + void shouldRunParameterizedWithResult() { // When - List result = - session.run( "UNWIND $list AS k RETURN k", parameters( "list", asList( 1, 2, 3 ) ) ).list(); + List result = session.run("UNWIND $list AS k RETURN k", parameters("list", asList(1, 2, 3))) + .list(); // Then - assertThat( result.size(), equalTo( 3 ) ); + assertThat(result.size(), equalTo(3)); } @SuppressWarnings({"QueryWithEmptyBody", "ConstantConditions"}) @Test - void shouldRunSimpleQuery() - { + void shouldRunSimpleQuery() { // When I run a simple write query - session.run( "CREATE (a {name:'Adam'})" ); + session.run("CREATE (a {name:'Adam'})"); // And I run a read query - Result result2 = session.run( "MATCH (a) RETURN a.name" ); + Result result2 = session.run("MATCH (a) RETURN a.name"); // Then I expect to get the name back Value name = null; - while ( result2.hasNext() ) - { - name = result2.next().get( "a.name" ); + while (result2.hasNext()) { + name = result2.next().get("a.name"); } - assertThat( name.asString(), equalTo( "Adam" ) ); + assertThat(name.asString(), equalTo("Adam")); } @Test - void shouldFailForIllegalQueries() - { - assertThrows( IllegalArgumentException.class, () -> session.run( (String) null ) ); - assertThrows( IllegalArgumentException.class, () -> session.run( "" ) ); + void shouldFailForIllegalQueries() { + assertThrows(IllegalArgumentException.class, () -> session.run((String) null)); + assertThrows(IllegalArgumentException.class, () -> session.run("")); } @Test void shouldBeAbleToLogSemanticWrongExceptions() { try { // When I run a query with the old syntax - session.writeTransaction(tx -> - tx.run( "MATCH (n:Element) WHERE n.name = {param} RETURN n", - parameters("param", "Luke" )).list()); - } catch ( Exception ex ) { + session.writeTransaction( + tx -> tx.run("MATCH (n:Element) WHERE n.name = {param} RETURN n", parameters("param", "Luke")) + .list()); + } catch (Exception ex) { // And exception happens // Then it should not have circular reference assertNoCircularReferences(ex); diff --git a/driver/src/test/java/org/neo4j/driver/integration/QueryRunnerCloseIT.java b/driver/src/test/java/org/neo4j/driver/integration/QueryRunnerCloseIT.java index 1278464862..cd0221f7e5 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/QueryRunnerCloseIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/QueryRunnerCloseIT.java @@ -18,16 +18,18 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.util.TestUtil.await; import java.util.List; import java.util.concurrent.ExecutorService; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.exceptions.ResultConsumedException; @@ -35,13 +37,8 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.util.TestUtil.await; - @ParallelizableIT -class QueryRunnerCloseIT -{ +class QueryRunnerCloseIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @@ -49,21 +46,17 @@ class QueryRunnerCloseIT private ExecutorService executor; @AfterEach - void tearDown() - { - if ( driver != null ) - { + void tearDown() { + if (driver != null) { driver.close(); } - if ( executor != null ) - { + if (executor != null) { executor.shutdownNow(); } } @Test - void shouldErrorToAccessRecordsAfterConsume() - { + void shouldErrorToAccessRecordsAfterConsume() { // Given Result result = neo4j.driver().session().run("UNWIND [1,2] AS a RETURN a"); @@ -71,19 +64,18 @@ void shouldErrorToAccessRecordsAfterConsume() result.consume(); // Then - assertThrows( ResultConsumedException.class, result::hasNext ); - assertThrows( ResultConsumedException.class, result::next ); - assertThrows( ResultConsumedException.class, result::list ); - assertThrows( ResultConsumedException.class, result::single ); - assertThrows( ResultConsumedException.class, result::peek ); - assertThrows( ResultConsumedException.class, ()-> result.stream().toArray() ); - assertThrows( ResultConsumedException.class, () -> result.forEachRemaining( record -> {} ) ); - assertThrows( ResultConsumedException.class, () -> result.list( record -> record ) ); + assertThrows(ResultConsumedException.class, result::hasNext); + assertThrows(ResultConsumedException.class, result::next); + assertThrows(ResultConsumedException.class, result::list); + assertThrows(ResultConsumedException.class, result::single); + assertThrows(ResultConsumedException.class, result::peek); + assertThrows(ResultConsumedException.class, () -> result.stream().toArray()); + assertThrows(ResultConsumedException.class, () -> result.forEachRemaining(record -> {})); + assertThrows(ResultConsumedException.class, () -> result.list(record -> record)); } @Test - void shouldErrorToAccessRecordsAfterClose() - { + void shouldErrorToAccessRecordsAfterClose() { // Given Session session = neo4j.driver().session(); Result result = session.run("UNWIND [1,2] AS a RETURN a"); @@ -92,19 +84,18 @@ void shouldErrorToAccessRecordsAfterClose() session.close(); // Then - assertThrows( ResultConsumedException.class, result::hasNext ); - assertThrows( ResultConsumedException.class, result::next ); - assertThrows( ResultConsumedException.class, result::list ); - assertThrows( ResultConsumedException.class, result::single ); - assertThrows( ResultConsumedException.class, result::peek ); - assertThrows( ResultConsumedException.class, ()-> result.stream().toArray() ); - assertThrows( ResultConsumedException.class, () -> result.forEachRemaining( record -> {} ) ); - assertThrows( ResultConsumedException.class, () -> result.list( record -> record ) ); + assertThrows(ResultConsumedException.class, result::hasNext); + assertThrows(ResultConsumedException.class, result::next); + assertThrows(ResultConsumedException.class, result::list); + assertThrows(ResultConsumedException.class, result::single); + assertThrows(ResultConsumedException.class, result::peek); + assertThrows(ResultConsumedException.class, () -> result.stream().toArray()); + assertThrows(ResultConsumedException.class, () -> result.forEachRemaining(record -> {})); + assertThrows(ResultConsumedException.class, () -> result.list(record -> record)); } @Test - void shouldAllowConsumeAndKeysAfterConsume() - { + void shouldAllowConsumeAndKeysAfterConsume() { // Given Result result = neo4j.driver().session().run("UNWIND [1,2] AS a RETURN a"); List keys = result.keys(); @@ -116,13 +107,12 @@ void shouldAllowConsumeAndKeysAfterConsume() ResultSummary summary1 = result.consume(); List keys1 = result.keys(); - assertEquals( summary, summary1 ); - assertEquals( keys, keys1 ); + assertEquals(summary, summary1); + assertEquals(keys, keys1); } @Test - void shouldAllowSummaryAndKeysAfterClose() - { + void shouldAllowSummaryAndKeysAfterClose() { // Given Session session = neo4j.driver().session(); Result result = session.run("UNWIND [1,2] AS a RETURN a"); @@ -136,84 +126,81 @@ void shouldAllowSummaryAndKeysAfterClose() ResultSummary summary1 = result.consume(); List keys1 = result.keys(); - assertEquals( summary, summary1 ); - assertEquals( keys, keys1 ); + assertEquals(summary, summary1); + assertEquals(keys, keys1); } @Test - void shouldErrorToAccessRecordsAfterConsumeAsync() - { + void shouldErrorToAccessRecordsAfterConsumeAsync() { // Given AsyncSession session = neo4j.driver().asyncSession(); - ResultCursor result = await( session.runAsync( "UNWIND [1,2] AS a RETURN a" ) ); + ResultCursor result = await(session.runAsync("UNWIND [1,2] AS a RETURN a")); // When - await( result.consumeAsync() ); + await(result.consumeAsync()); // Then - assertThrows( ResultConsumedException.class, () -> await( result.nextAsync() ) ); - assertThrows( ResultConsumedException.class, () -> await( result.peekAsync() ) ); - assertThrows( ResultConsumedException.class, () -> await( result.singleAsync() ) ); - assertThrows( ResultConsumedException.class, () -> await( result.forEachAsync( record -> {} ) ) ); - assertThrows( ResultConsumedException.class, () -> await( result.listAsync() ) ); - assertThrows( ResultConsumedException.class, () -> await( result.listAsync( record -> record ) ) ); + assertThrows(ResultConsumedException.class, () -> await(result.nextAsync())); + assertThrows(ResultConsumedException.class, () -> await(result.peekAsync())); + assertThrows(ResultConsumedException.class, () -> await(result.singleAsync())); + assertThrows(ResultConsumedException.class, () -> await(result.forEachAsync(record -> {}))); + assertThrows(ResultConsumedException.class, () -> await(result.listAsync())); + assertThrows(ResultConsumedException.class, () -> await(result.listAsync(record -> record))); } @Test - void shouldErrorToAccessRecordsAfterCloseAsync() - { + void shouldErrorToAccessRecordsAfterCloseAsync() { // Given AsyncSession session = neo4j.driver().asyncSession(); - ResultCursor result = await( session.runAsync( "UNWIND [1,2] AS a RETURN a" ) ); + ResultCursor result = await(session.runAsync("UNWIND [1,2] AS a RETURN a")); // When - await( session.closeAsync() ); + await(session.closeAsync()); // Then - assertThrows( ResultConsumedException.class, () -> await( result.nextAsync() ) ); - assertThrows( ResultConsumedException.class, () -> await( result.peekAsync() ) ); - assertThrows( ResultConsumedException.class, () -> await( result.singleAsync() ) ); - assertThrows( ResultConsumedException.class, () -> await( result.forEachAsync( record -> {} ) ) ); - assertThrows( ResultConsumedException.class, () -> await( result.listAsync() ) ); - assertThrows( ResultConsumedException.class, () -> await( result.listAsync( record -> record ) ) ); } + assertThrows(ResultConsumedException.class, () -> await(result.nextAsync())); + assertThrows(ResultConsumedException.class, () -> await(result.peekAsync())); + assertThrows(ResultConsumedException.class, () -> await(result.singleAsync())); + assertThrows(ResultConsumedException.class, () -> await(result.forEachAsync(record -> {}))); + assertThrows(ResultConsumedException.class, () -> await(result.listAsync())); + assertThrows(ResultConsumedException.class, () -> await(result.listAsync(record -> record))); + } @Test - void shouldAllowConsumeAndKeysAfterConsumeAsync() - { + void shouldAllowConsumeAndKeysAfterConsumeAsync() { // Given AsyncSession session = neo4j.driver().asyncSession(); - ResultCursor result = await( session.runAsync( "UNWIND [1,2] AS a RETURN a" ) ); + ResultCursor result = await(session.runAsync("UNWIND [1,2] AS a RETURN a")); List keys = result.keys(); // When - ResultSummary summary = await( result.consumeAsync() ); + ResultSummary summary = await(result.consumeAsync()); // Then - ResultSummary summary1 = await( result.consumeAsync() ); + ResultSummary summary1 = await(result.consumeAsync()); List keys1 = result.keys(); - assertEquals( summary, summary1 ); - assertEquals( keys, keys1 ); + assertEquals(summary, summary1); + assertEquals(keys, keys1); } @Test - void shouldAllowConsumeAndKeysAfterCloseAsync() - { + void shouldAllowConsumeAndKeysAfterCloseAsync() { // Given AsyncSession session = neo4j.driver().asyncSession(); - ResultCursor result = await( session.runAsync( "UNWIND [1,2] AS a RETURN a" ) ); + ResultCursor result = await(session.runAsync("UNWIND [1,2] AS a RETURN a")); List keys = result.keys(); - ResultSummary summary = await( result.consumeAsync() ); + ResultSummary summary = await(result.consumeAsync()); // When - await( session.closeAsync() ); + await(session.closeAsync()); // Then List keys1 = result.keys(); - ResultSummary summary1 = await( result.consumeAsync() ); + ResultSummary summary1 = await(result.consumeAsync()); - assertEquals( summary, summary1 ); - assertEquals( keys, keys1 ); + assertEquals(summary, summary1); + assertEquals(keys, keys1); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/ResolverIT.java b/driver/src/test/java/org/neo4j/driver/integration/ResolverIT.java index e1d3b7fcd2..bfa82dea48 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ResolverIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ResolverIT.java @@ -18,14 +18,6 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.Config; -import org.neo4j.driver.Driver; -import org.neo4j.driver.GraphDatabase; -import org.neo4j.driver.net.ServerAddress; -import org.neo4j.driver.net.ServerAddressResolver; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -34,23 +26,28 @@ import static org.mockito.Mockito.when; import static org.neo4j.driver.Logging.none; -class ResolverIT -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Config; +import org.neo4j.driver.Driver; +import org.neo4j.driver.GraphDatabase; +import org.neo4j.driver.net.ServerAddress; +import org.neo4j.driver.net.ServerAddressResolver; + +class ResolverIT { @Test - void shouldFailInitialDiscoveryWhenConfiguredResolverThrows() - { - ServerAddressResolver resolver = mock( ServerAddressResolver.class ); - when( resolver.resolve( any( ServerAddress.class ) ) ).thenThrow( new RuntimeException( "Resolution failure!" ) ); + void shouldFailInitialDiscoveryWhenConfiguredResolverThrows() { + ServerAddressResolver resolver = mock(ServerAddressResolver.class); + when(resolver.resolve(any(ServerAddress.class))).thenThrow(new RuntimeException("Resolution failure!")); Config config = Config.builder() - .withoutEncryption() - .withLogging( none() ) - .withResolver( resolver ) - .build(); - final Driver driver = GraphDatabase.driver( "neo4j://my.server.com:9001", config ); + .withoutEncryption() + .withLogging(none()) + .withResolver(resolver) + .build(); + final Driver driver = GraphDatabase.driver("neo4j://my.server.com:9001", config); - RuntimeException error = assertThrows( RuntimeException.class, driver::verifyConnectivity ); - assertEquals( "Resolution failure!", error.getMessage() ); - verify( resolver ).resolve( ServerAddress.of( "my.server.com", 9001 ) ); + RuntimeException error = assertThrows(RuntimeException.class, driver::verifyConnectivity); + assertEquals("Resolution failure!", error.getMessage()); + verify(resolver).resolve(ServerAddress.of("my.server.com", 9001)); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/ResultStreamIT.java b/driver/src/test/java/org/neo4j/driver/integration/ResultStreamIT.java index 384c454e4b..e591f6b8b6 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ResultStreamIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ResultStreamIT.java @@ -18,15 +18,25 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.toList; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.Values.parameters; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.IntStream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.Transaction; @@ -36,217 +46,177 @@ import org.neo4j.driver.util.ParallelizableIT; import org.neo4j.driver.util.SessionExtension; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.stream.Collectors.toList; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.Values.parameters; - @ParallelizableIT -class ResultStreamIT -{ +class ResultStreamIT { @RegisterExtension static final SessionExtension session = new SessionExtension(); @Test - void shouldAllowIteratingOverResultStream() - { + void shouldAllowIteratingOverResultStream() { // When - Result res = session.run( "UNWIND [1,2,3,4] AS a RETURN a" ); + Result res = session.run("UNWIND [1,2,3,4] AS a RETURN a"); // Then I should be able to iterate over the result int idx = 1; - while ( res.hasNext() ) - { - assertEquals( idx++, res.next().get( "a" ).asLong() ); + while (res.hasNext()) { + assertEquals(idx++, res.next().get("a").asLong()); } } @Test - void shouldHaveFieldNamesInResult() - { + void shouldHaveFieldNamesInResult() { // When - Result res = session.run( "CREATE (n:TestNode {name:'test'}) RETURN n" ); + Result res = session.run("CREATE (n:TestNode {name:'test'}) RETURN n"); // Then - assertEquals( "[n]", res.keys().toString() ); - assertNotNull( res.single() ); - assertEquals( "[n]", res.keys().toString() ); + assertEquals("[n]", res.keys().toString()); + assertNotNull(res.single()); + assertEquals("[n]", res.keys().toString()); } @Test - void shouldGiveHelpfulFailureMessageWhenAccessNonExistingField() - { + void shouldGiveHelpfulFailureMessageWhenAccessNonExistingField() { // Given - Result rs = - session.run( "CREATE (n:Person {name:$name}) RETURN n", parameters( "name", "Tom Hanks" ) ); + Result rs = session.run("CREATE (n:Person {name:$name}) RETURN n", parameters("name", "Tom Hanks")); // When Record single = rs.single(); // Then - assertTrue( single.get( "m" ).isNull() ); + assertTrue(single.get("m").isNull()); } @Test - void shouldGiveHelpfulFailureMessageWhenAccessNonExistingPropertyOnNode() - { + void shouldGiveHelpfulFailureMessageWhenAccessNonExistingPropertyOnNode() { // Given - Result rs = - session.run( "CREATE (n:Person {name:$name}) RETURN n", parameters( "name", "Tom Hanks" ) ); + Result rs = session.run("CREATE (n:Person {name:$name}) RETURN n", parameters("name", "Tom Hanks")); // When Record record = rs.single(); // Then - assertTrue( record.get( "n" ).get( "age" ).isNull() ); + assertTrue(record.get("n").get("age").isNull()); } @Test - void shouldNotReturnNullKeysOnEmptyResult() - { + void shouldNotReturnNullKeysOnEmptyResult() { // Given - Result rs = session.run( "CREATE (n:Person {name:$name})", parameters( "name", "Tom Hanks" ) ); + Result rs = session.run("CREATE (n:Person {name:$name})", parameters("name", "Tom Hanks")); // THEN - assertNotNull( rs.keys() ); + assertNotNull(rs.keys()); } @Test - void shouldBeAbleToReuseSessionAfterFailure() - { + void shouldBeAbleToReuseSessionAfterFailure() { // Given - assertThrows( Exception.class, () -> session.run( "INVALID" ) ); + assertThrows(Exception.class, () -> session.run("INVALID")); // When - Result res2 = session.run( "RETURN 1" ); + Result res2 = session.run("RETURN 1"); // Then - assertTrue( res2.hasNext() ); - assertEquals( res2.next().get( "1" ).asLong(), 1L ); + assertTrue(res2.hasNext()); + assertEquals(res2.next().get("1").asLong(), 1L); } @Test - void shouldBeAbleToAccessSummaryAfterTransactionFailure() - { + void shouldBeAbleToAccessSummaryAfterTransactionFailure() { AtomicReference resultRef = new AtomicReference<>(); - assertThrows( ClientException.class, () -> - { - try ( Transaction tx = session.beginTransaction() ) - { - Result result = tx.run( "UNWIND [1,2,0] AS x RETURN 10/x" ); - resultRef.set( result ); + assertThrows(ClientException.class, () -> { + try (Transaction tx = session.beginTransaction()) { + Result result = tx.run("UNWIND [1,2,0] AS x RETURN 10/x"); + resultRef.set(result); tx.commit(); } - } ); + }); Result result = resultRef.get(); - assertNotNull( result ); - assertEquals( 0, result.consume().counters().nodesCreated() ); + assertNotNull(result); + assertEquals(0, result.consume().counters().nodesCreated()); } @Test - void shouldConvertEmptyResultToStream() - { - long count = session.run( "MATCH (n:WrongLabel) RETURN n" ) - .stream() - .count(); + void shouldConvertEmptyResultToStream() { + long count = session.run("MATCH (n:WrongLabel) RETURN n").stream().count(); - assertEquals( 0, count ); + assertEquals(0, count); - Optional anyRecord = session.run( "MATCH (n:OtherWrongLabel) RETURN n" ) - .stream() - .findAny(); + Optional anyRecord = + session.run("MATCH (n:OtherWrongLabel) RETURN n").stream().findAny(); - assertFalse( anyRecord.isPresent() ); + assertFalse(anyRecord.isPresent()); } @Test - void shouldConvertResultToStream() - { - List receivedList = session.run( "UNWIND range(1, 10) AS x RETURN x" ) - .stream() - .map( record -> record.get( 0 ) ) - .map( Value::asInt ) - .collect( toList() ); - - assertEquals( asList( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ), receivedList ); + void shouldConvertResultToStream() { + List receivedList = session.run("UNWIND range(1, 10) AS x RETURN x").stream() + .map(record -> record.get(0)) + .map(Value::asInt) + .collect(toList()); + + assertEquals(asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), receivedList); } @Test - void shouldConvertImmediatelyFailingResultToStream() - { + void shouldConvertImmediatelyFailingResultToStream() { List seen = new ArrayList<>(); - ClientException e = assertThrows( ClientException.class, - () -> session.run( "RETURN 10 / 0" ) - .stream() - .forEach( record -> seen.add( record.get( 0 ).asInt() ) ) ); + ClientException e = assertThrows(ClientException.class, () -> session.run("RETURN 10 / 0").stream() + .forEach(record -> seen.add(record.get(0).asInt()))); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + assertThat(e.getMessage(), containsString("/ by zero")); - assertEquals( emptyList(), seen ); + assertEquals(emptyList(), seen); } @Test - void shouldConvertEventuallyFailingResultToStream() - { + void shouldConvertEventuallyFailingResultToStream() { List seen = new ArrayList<>(); - ClientException e = assertThrows( ClientException.class, - () -> session.run( "CYPHER runtime=interpreted UNWIND range(5, 0, -1) AS x RETURN x / x" ) - .stream() - .forEach( record -> seen.add( record.get( 0 ).asInt() ) ) ); + ClientException e = assertThrows( + ClientException.class, + () -> session.run("CYPHER runtime=interpreted UNWIND range(5, 0, -1) AS x RETURN x / x").stream() + .forEach(record -> seen.add(record.get(0).asInt()))); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + assertThat(e.getMessage(), containsString("/ by zero")); // stream should manage to summary all elements except the last one, which produces an error - assertEquals( asList( 1, 1, 1, 1, 1 ), seen ); + assertEquals(asList(1, 1, 1, 1, 1), seen); } @Test - void shouldEmptyResultWhenConvertedToStream() - { - Result result = session.run( "UNWIND range(1, 10) AS x RETURN x" ); + void shouldEmptyResultWhenConvertedToStream() { + Result result = session.run("UNWIND range(1, 10) AS x RETURN x"); - assertTrue( result.hasNext() ); - assertEquals( 1, result.next().get( 0 ).asInt() ); + assertTrue(result.hasNext()); + assertEquals(1, result.next().get(0).asInt()); - assertTrue( result.hasNext() ); - assertEquals( 2, result.next().get( 0 ).asInt() ); + assertTrue(result.hasNext()); + assertEquals(2, result.next().get(0).asInt()); - List list = result.stream() - .map( record -> record.get( 0 ).asInt() ) - .collect( toList() ); - assertEquals( asList( 3, 4, 5, 6, 7, 8, 9, 10 ), list ); + List list = + result.stream().map(record -> record.get(0).asInt()).collect(toList()); + assertEquals(asList(3, 4, 5, 6, 7, 8, 9, 10), list); - assertFalse( result.hasNext() ); - assertThrows( NoSuchRecordException.class, result::next ); - assertEquals( emptyList(), result.list() ); - assertEquals( 0, result.stream().count() ); + assertFalse(result.hasNext()); + assertThrows(NoSuchRecordException.class, result::next); + assertEquals(emptyList(), result.list()); + assertEquals(0, result.stream().count()); } @Test - void shouldConsumeLargeResultAsParallelStream() - { - List receivedList = session.run( "UNWIND range(1, 200000) AS x RETURN 'value-' + x" ) - .stream() + void shouldConsumeLargeResultAsParallelStream() { + List receivedList = session.run("UNWIND range(1, 200000) AS x RETURN 'value-' + x").stream() .parallel() - .map( record -> record.get( 0 ) ) - .map( Value::asString ) - .collect( toList() ); + .map(record -> record.get(0)) + .map(Value::asString) + .collect(toList()); - List expectedList = IntStream.range( 1, 200001 ) - .mapToObj( i -> "value-" + i ) - .collect( toList() ); + List expectedList = + IntStream.range(1, 200001).mapToObj(i -> "value-" + i).collect(toList()); - assertEquals( expectedList, receivedList ); + assertEquals(expectedList, receivedList); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/RoutingDriverIT.java b/driver/src/test/java/org/neo4j/driver/integration/RoutingDriverIT.java index 91c8e3f450..b877b5c2ff 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/RoutingDriverIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/RoutingDriverIT.java @@ -18,59 +18,54 @@ */ package org.neo4j.driver.integration; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.neo4j.driver.SessionConfig.forDatabase; +import static org.neo4j.driver.internal.util.Matchers.clusterDriver; + +import java.net.URI; import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.net.URI; - import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; import org.neo4j.driver.internal.util.Neo4jFeature; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.neo4j.driver.SessionConfig.forDatabase; -import static org.neo4j.driver.internal.util.Matchers.clusterDriver; - @ParallelizableIT -@EnabledOnNeo4jWith( Neo4jFeature.BOLT_V4 ) -class RoutingDriverIT -{ +@EnabledOnNeo4jWith(Neo4jFeature.BOLT_V4) +class RoutingDriverIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - void shouldBeAbleToConnectSingleInstanceWithNeo4jScheme() throws Throwable - { - URI uri = URI.create( String.format( "neo4j://%s:%s", neo4j.uri().getHost(), neo4j.uri().getPort() ) ); + void shouldBeAbleToConnectSingleInstanceWithNeo4jScheme() throws Throwable { + URI uri = URI.create(String.format( + "neo4j://%s:%s", neo4j.uri().getHost(), neo4j.uri().getPort())); - try ( Driver driver = GraphDatabase.driver( uri, neo4j.authToken() ); - Session session = driver.session() ) - { - assertThat( driver, is( clusterDriver() ) ); + try (Driver driver = GraphDatabase.driver(uri, neo4j.authToken()); + Session session = driver.session()) { + assertThat(driver, is(clusterDriver())); - Result result = session.run( "RETURN 1" ); - assertThat( result.single().get( 0 ).asInt(), CoreMatchers.equalTo( 1 ) ); + Result result = session.run("RETURN 1"); + assertThat(result.single().get(0).asInt(), CoreMatchers.equalTo(1)); } } @Test - void shouldBeAbleToRunQueryOnNeo4j() throws Throwable - { - URI uri = URI.create( String.format( "neo4j://%s:%s", neo4j.uri().getHost(), neo4j.uri().getPort() ) ); - try ( Driver driver = GraphDatabase.driver( uri, neo4j.authToken() ); - Session session = driver.session( forDatabase( "neo4j" ) ) ) - { - assertThat( driver, is( clusterDriver() ) ); + void shouldBeAbleToRunQueryOnNeo4j() throws Throwable { + URI uri = URI.create(String.format( + "neo4j://%s:%s", neo4j.uri().getHost(), neo4j.uri().getPort())); + try (Driver driver = GraphDatabase.driver(uri, neo4j.authToken()); + Session session = driver.session(forDatabase("neo4j"))) { + assertThat(driver, is(clusterDriver())); - Result result = session.run( "RETURN 1" ); - assertThat( result.single().get( 0 ).asInt(), CoreMatchers.equalTo( 1 ) ); + Result result = session.run("RETURN 1"); + assertThat(result.single().get(0).asInt(), CoreMatchers.equalTo(1)); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/ScalarTypeIT.java b/driver/src/test/java/org/neo4j/driver/integration/ScalarTypeIT.java index 2794075b98..df81c199a0 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ScalarTypeIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ScalarTypeIT.java @@ -18,11 +18,10 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.Values.parameters; import java.util.Arrays; import java.util.Collections; @@ -31,223 +30,199 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.neo4j.driver.Result; +import org.neo4j.driver.Value; +import org.neo4j.driver.Values; import org.neo4j.driver.internal.value.ListValue; import org.neo4j.driver.internal.value.MapValue; import org.neo4j.driver.internal.value.NullValue; import org.neo4j.driver.internal.value.StringValue; -import org.neo4j.driver.Result; -import org.neo4j.driver.Value; -import org.neo4j.driver.Values; import org.neo4j.driver.util.ParallelizableIT; import org.neo4j.driver.util.SessionExtension; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.Values.parameters; - @ParallelizableIT -class ScalarTypeIT -{ +class ScalarTypeIT { @RegisterExtension static final SessionExtension session = new SessionExtension(); - static Stream typesToTest() - { + static Stream typesToTest() { return Stream.of( - Arguments.of( "RETURN 1 as v", Values.value( 1L ) ), - Arguments.of( "RETURN 1.1 as v", Values.value( 1.1d ) ), - Arguments.of( "RETURN 'hello' as v", Values.value( "hello" ) ), - Arguments.of( "RETURN true as v", Values.value( true ) ), - Arguments.of( "RETURN false as v", Values.value( false ) ), - Arguments.of( "RETURN [1,2,3] as v", new ListValue( Values.value( 1 ), Values.value( 2 ), Values.value( 3 ) ) ), - Arguments.of( "RETURN ['hello'] as v", new ListValue( Values.value( "hello" ) ) ), - Arguments.of( "RETURN [] as v", new ListValue() ), - Arguments.of( "RETURN {k:'hello'} as v", parameters( "k", Values.value( "hello" ) ) ), - Arguments.of( "RETURN {} as v", new MapValue( Collections.emptyMap() ) ) - ); + Arguments.of("RETURN 1 as v", Values.value(1L)), + Arguments.of("RETURN 1.1 as v", Values.value(1.1d)), + Arguments.of("RETURN 'hello' as v", Values.value("hello")), + Arguments.of("RETURN true as v", Values.value(true)), + Arguments.of("RETURN false as v", Values.value(false)), + Arguments.of("RETURN [1,2,3] as v", new ListValue(Values.value(1), Values.value(2), Values.value(3))), + Arguments.of("RETURN ['hello'] as v", new ListValue(Values.value("hello"))), + Arguments.of("RETURN [] as v", new ListValue()), + Arguments.of("RETURN {k:'hello'} as v", parameters("k", Values.value("hello"))), + Arguments.of("RETURN {} as v", new MapValue(Collections.emptyMap()))); } @ParameterizedTest - @MethodSource( "typesToTest" ) - void shouldHandleType( String query, Value expectedValue ) - { + @MethodSource("typesToTest") + void shouldHandleType(String query, Value expectedValue) { // When - Result cursor = session.run( query ); + Result cursor = session.run(query); // Then - assertThat( cursor.single().get( "v" ), equalTo( expectedValue ) ); + assertThat(cursor.single().get("v"), equalTo(expectedValue)); } - static Stream collectionItems() - { + static Stream collectionItems() { return Stream.of( - Arguments.of( Values.value( (Object) null ) ), - Arguments.of( Values.value( 1L ) ), - Arguments.of( Values.value( 1.1d ) ), - Arguments.of( Values.value( "hello" ) ), - Arguments.of( Values.value( true ) ) - ); + Arguments.of(Values.value((Object) null)), + Arguments.of(Values.value(1L)), + Arguments.of(Values.value(1.1d)), + Arguments.of(Values.value("hello")), + Arguments.of(Values.value(true))); } @ParameterizedTest - @MethodSource( "collectionItems" ) - void shouldEchoVeryLongMap( Value collectionItem ) - { + @MethodSource("collectionItems") + void shouldEchoVeryLongMap(Value collectionItem) { // Given Map input = new HashMap<>(); - for ( int i = 0; i < 1000; i ++ ) - { - input.put( String.valueOf( i ), collectionItem ); + for (int i = 0; i < 1000; i++) { + input.put(String.valueOf(i), collectionItem); } - MapValue mapValue = new MapValue( input ); + MapValue mapValue = new MapValue(input); // When & Then - verifyCanEncodeAndDecode( mapValue ); + verifyCanEncodeAndDecode(mapValue); } @ParameterizedTest - @MethodSource( "collectionItems" ) - void shouldEchoVeryLongList( Value collectionItem ) - { + @MethodSource("collectionItems") + void shouldEchoVeryLongList(Value collectionItem) { // Given Value[] input = new Value[1000]; - for ( int i = 0; i < 1000; i ++ ) - { + for (int i = 0; i < 1000; i++) { input[i] = collectionItem; } - ListValue listValue = new ListValue( input ); + ListValue listValue = new ListValue(input); // When & Then - verifyCanEncodeAndDecode( listValue ); - + verifyCanEncodeAndDecode(listValue); } @Test - void shouldEchoVeryLongString() - { + void shouldEchoVeryLongString() { // Given char[] chars = new char[10000]; - Arrays.fill( chars, '*' ); - String longText = new String( chars ); - StringValue input = new StringValue( longText ); + Arrays.fill(chars, '*'); + String longText = new String(chars); + StringValue input = new StringValue(longText); // When & Then - verifyCanEncodeAndDecode( input ); + verifyCanEncodeAndDecode(input); } - static Stream scalarTypes() - { + static Stream scalarTypes() { return Stream.of( - Arguments.of( Values.value( (Object) null ) ), - Arguments.of( Values.value( true ) ), - Arguments.of( Values.value( false ) ), - Arguments.of( Values.value( 1L ) ), - Arguments.of( Values.value( -17L ) ), - Arguments.of( Values.value( -129L ) ), - Arguments.of( Values.value( 129L ) ), - Arguments.of( Values.value( 2147483647L ) ), - Arguments.of( Values.value( -2147483648L ) ), - Arguments.of( Values.value( -2147483648L ) ), - Arguments.of( Values.value( 9223372036854775807L ) ), - Arguments.of( Values.value( -9223372036854775808L ) ), - Arguments.of( Values.value( 1.7976931348623157E+308d ) ), - Arguments.of( Values.value( 2.2250738585072014e-308d ) ), - Arguments.of( Values.value( 0.0d ) ), - Arguments.of( Values.value( 1.1d ) ), - Arguments.of( Values.value( "1" ) ), - Arguments.of( Values.value( "-17∂ßå®" ) ), - Arguments.of( Values.value( "String" ) ), - Arguments.of( Values.value( "" ) ) - ); - } + Arguments.of(Values.value((Object) null)), + Arguments.of(Values.value(true)), + Arguments.of(Values.value(false)), + Arguments.of(Values.value(1L)), + Arguments.of(Values.value(-17L)), + Arguments.of(Values.value(-129L)), + Arguments.of(Values.value(129L)), + Arguments.of(Values.value(2147483647L)), + Arguments.of(Values.value(-2147483648L)), + Arguments.of(Values.value(-2147483648L)), + Arguments.of(Values.value(9223372036854775807L)), + Arguments.of(Values.value(-9223372036854775808L)), + Arguments.of(Values.value(1.7976931348623157E+308d)), + Arguments.of(Values.value(2.2250738585072014e-308d)), + Arguments.of(Values.value(0.0d)), + Arguments.of(Values.value(1.1d)), + Arguments.of(Values.value("1")), + Arguments.of(Values.value("-17∂ßå®")), + Arguments.of(Values.value("String")), + Arguments.of(Values.value(""))); + } @ParameterizedTest - @MethodSource( "scalarTypes" ) - void shouldEchoScalarTypes( Value input ) - { + @MethodSource("scalarTypes") + void shouldEchoScalarTypes(Value input) { // When & Then - verifyCanEncodeAndDecode( input ); + verifyCanEncodeAndDecode(input); } - static Stream listToTest() - { + static Stream listToTest() { return Stream.of( - Arguments.of( Values.value( 1, 2, 3, 4 ) ), - Arguments.of( Values.value( true, false ) ), - Arguments.of( Values.value( 1.1, 2.2, 3.3 ) ), - Arguments.of( Values.value( "a", "b", "c", "˚C" ) ), - Arguments.of( Values.value( NullValue.NULL, NullValue.NULL ) ), - Arguments.of( Values.value( Values.values( NullValue.NULL, true, "-17∂ßå®", 1.7976931348623157E+308d, -9223372036854775808d ) ) ), - Arguments.of( new ListValue( parameters( "a", 1, "b", true, "c", 1.1, "d", "˚C", "e", null ) ) ) - ); + Arguments.of(Values.value(1, 2, 3, 4)), + Arguments.of(Values.value(true, false)), + Arguments.of(Values.value(1.1, 2.2, 3.3)), + Arguments.of(Values.value("a", "b", "c", "˚C")), + Arguments.of(Values.value(NullValue.NULL, NullValue.NULL)), + Arguments.of(Values.value(Values.values( + NullValue.NULL, true, "-17∂ßå®", 1.7976931348623157E+308d, -9223372036854775808d))), + Arguments.of(new ListValue(parameters("a", 1, "b", true, "c", 1.1, "d", "˚C", "e", null)))); } @ParameterizedTest - @MethodSource( "listToTest" ) - void shouldEchoList( Value input ) - { + @MethodSource("listToTest") + void shouldEchoList(Value input) { // When & Then - assertTrue( input instanceof ListValue ); - verifyCanEncodeAndDecode( input ); + assertTrue(input instanceof ListValue); + verifyCanEncodeAndDecode(input); } @Test - void shouldEchoNestedList() throws Throwable - { - Value input = Values.value( toValueStream( listToTest() ) ); + void shouldEchoNestedList() throws Throwable { + Value input = Values.value(toValueStream(listToTest())); // When & Then - assertTrue( input instanceof ListValue ); - verifyCanEncodeAndDecode( input ); + assertTrue(input instanceof ListValue); + verifyCanEncodeAndDecode(input); } - static Stream mapToTest() - { - return Stream.of( Arguments.of( parameters( "a", 1, "b", 2, "c", 3, "d", 4 ) ), - Arguments.of( parameters( "a", true, "b", false ) ), - Arguments.of( parameters( "a", 1.1, "b", 2.2, "c", 3.3 ) ), - Arguments.of( parameters( "b", "a", "c", "b", "d", "c", "e", "˚C" ) ), - Arguments.of( parameters( "a", null ) ), - Arguments.of( parameters( "a", 1, "b", true, "c", 1.1, "d", "˚C", "e", null ) ) ); + static Stream mapToTest() { + return Stream.of( + Arguments.of(parameters("a", 1, "b", 2, "c", 3, "d", 4)), + Arguments.of(parameters("a", true, "b", false)), + Arguments.of(parameters("a", 1.1, "b", 2.2, "c", 3.3)), + Arguments.of(parameters("b", "a", "c", "b", "d", "c", "e", "˚C")), + Arguments.of(parameters("a", null)), + Arguments.of(parameters("a", 1, "b", true, "c", 1.1, "d", "˚C", "e", null))); } @ParameterizedTest - @MethodSource( "mapToTest" ) - void shouldEchoMap( Value input ) - { - assertTrue( input instanceof MapValue ); + @MethodSource("mapToTest") + void shouldEchoMap(Value input) { + assertTrue(input instanceof MapValue); // When & Then - verifyCanEncodeAndDecode( input ); + verifyCanEncodeAndDecode(input); } @Test - void shouldEchoNestedMap() throws Throwable - { + void shouldEchoNestedMap() throws Throwable { MapValue input = new MapValue( - toValueStream( mapToTest() ) - .collect( Collectors.toMap( Object::toString, Function.identity() ) ) ); + toValueStream(mapToTest()).collect(Collectors.toMap(Object::toString, Function.identity()))); // When & Then - verifyCanEncodeAndDecode( input ); + verifyCanEncodeAndDecode(input); } - private Stream toValueStream( Stream arguments ) - { - return arguments.map( arg -> { + private Stream toValueStream(Stream arguments) { + return arguments.map(arg -> { Object obj = arg.get()[0]; - assertTrue( obj instanceof Value ); + assertTrue(obj instanceof Value); return (Value) obj; - } ); + }); } - private void verifyCanEncodeAndDecode( Value input ) - { + private void verifyCanEncodeAndDecode(Value input) { // When - Result cursor = session.run( "RETURN $x as y", parameters( "x", input ) ); + Result cursor = session.run("RETURN $x as y", parameters("x", input)); // Then - assertThat( cursor.single().get( "y" ), equalTo( input ) ); + assertThat(cursor.single().get("y"), equalTo(input)); } } 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 92b9b8d705..b57b91a690 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java @@ -18,15 +18,24 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static org.neo4j.driver.Config.TrustStrategy.trustCustomCertificateSignedBy; +import static org.neo4j.driver.util.Neo4jRunner.DEFAULT_AUTH_TOKEN; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; - +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.neo4j.driver.Config; +import org.neo4j.driver.Driver; +import org.neo4j.driver.GraphDatabase; +import org.neo4j.driver.Record; +import org.neo4j.driver.Session; +import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.DriverFactory; import org.neo4j.driver.internal.cluster.RoutingSettings; import org.neo4j.driver.internal.retry.RetrySettings; @@ -34,64 +43,47 @@ 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.Config; -import org.neo4j.driver.Driver; -import org.neo4j.driver.GraphDatabase; -import org.neo4j.driver.Record; -import org.neo4j.driver.Session; -import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; -import static org.neo4j.driver.Config.TrustStrategy.trustCustomCertificateSignedBy; -import static org.neo4j.driver.util.Neo4jRunner.DEFAULT_AUTH_TOKEN; - /** * Mainly concerned about the connection pool - we want to make sure that bad connections are evacuated from the * pool properly if the server dies, or all connections are lost for some other reason. */ @ParallelizableIT -class ServerKilledIT -{ +class ServerKilledIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); - private static Stream data() - { + private static Stream data() { return Stream.of( - Arguments.of( "plaintext", Config.builder().withoutEncryption() ), - Arguments.of( "tls encrypted", Config.builder().withEncryption().withTrustStrategy( trustCustomCertificateSignedBy( neo4j.tlsCertFile() ) ) ) - ); + Arguments.of("plaintext", Config.builder().withoutEncryption()), + Arguments.of( + "tls encrypted", + Config.builder() + .withEncryption() + .withTrustStrategy(trustCustomCertificateSignedBy(neo4j.tlsCertFile())))); } @ParameterizedTest - @MethodSource( "data" ) - void shouldRecoverFromServerRestart( String name, Config.ConfigBuilder configBuilder ) - { + @MethodSource("data") + void shouldRecoverFromServerRestart(String name, Config.ConfigBuilder configBuilder) { // Given config with sessionLivenessCheckTimeout not set, i.e. turned off - try ( Driver driver = GraphDatabase.driver( neo4j.uri(), DEFAULT_AUTH_TOKEN, configBuilder.build() ) ) - { - acquireAndReleaseConnections( 4, driver ); + try (Driver driver = GraphDatabase.driver(neo4j.uri(), DEFAULT_AUTH_TOKEN, configBuilder.build())) { + acquireAndReleaseConnections(4, driver); // When neo4j.forceRestartDb(); // Then we should be able to start using sessions again, at most O(numSessions) session calls later int toleratedFailures = 4; - for ( int i = 0; i < 10; i++ ) - { - try ( Session s = driver.session() ) - { - s.run( "RETURN 'Hello, world!'" ); - } - catch ( ServiceUnavailableException e ) - { - if ( toleratedFailures-- == 0 ) - { - fail( "Expected (for now) at most four failures, one for each old connection, but now I've " + - "gotten " + "five: " + e.getMessage() ); + for (int i = 0; i < 10; i++) { + try (Session s = driver.session()) { + s.run("RETURN 'Hello, world!'"); + } catch (ServiceUnavailableException e) { + if (toleratedFailures-- == 0) { + fail("Expected (for now) at most four failures, one for each old connection, but now I've " + + "gotten " + "five: " + e.getMessage()); } } } @@ -99,51 +91,46 @@ void shouldRecoverFromServerRestart( String name, Config.ConfigBuilder configBui } @ParameterizedTest - @MethodSource( "data" ) - void shouldDropBrokenOldSessions( String name, Config.ConfigBuilder configBuilder ) - { + @MethodSource("data") + void shouldDropBrokenOldSessions(String name, Config.ConfigBuilder configBuilder) { // config with set liveness check timeout int livenessCheckTimeoutMinutes = 10; - configBuilder.withConnectionLivenessCheckTimeout( livenessCheckTimeoutMinutes, TimeUnit.MINUTES ); + configBuilder.withConnectionLivenessCheckTimeout(livenessCheckTimeoutMinutes, TimeUnit.MINUTES); FakeClock clock = new FakeClock(); - try ( Driver driver = createDriver( clock, configBuilder.build() ) ) - { - acquireAndReleaseConnections( 5, driver ); + try (Driver driver = createDriver(clock, configBuilder.build())) { + acquireAndReleaseConnections(5, driver); // restart database to invalidate all idle connections in the pool neo4j.forceRestartDb(); // move clock forward more than configured liveness check timeout - clock.progress( TimeUnit.MINUTES.toMillis( livenessCheckTimeoutMinutes + 1 ) ); + clock.progress(TimeUnit.MINUTES.toMillis(livenessCheckTimeoutMinutes + 1)); // now all idle connections should be considered too old and will be verified during acquisition // they will appear broken because of the database restart and new valid connection will be created - try ( Session session = driver.session() ) - { - List records = session.run( "RETURN 1" ).list(); - assertEquals( 1, records.size() ); - assertEquals( 1, records.get( 0 ).get( 0 ).asInt() ); + try (Session session = driver.session()) { + List records = session.run("RETURN 1").list(); + assertEquals(1, records.size()); + assertEquals(1, records.get(0).get(0).asInt()); } } } - private static void acquireAndReleaseConnections( int count, Driver driver ) - { - if ( count > 0 ) - { + private static void acquireAndReleaseConnections(int count, Driver driver) { + if (count > 0) { Session session = driver.session(); - session.run( "RETURN 1" ); - acquireAndReleaseConnections( count - 1, driver ); + session.run("RETURN 1"); + acquireAndReleaseConnections(count - 1, driver); session.close(); } } - private Driver createDriver( Clock clock, Config config ) - { - DriverFactory factory = new DriverFactoryWithClock( clock ); + private Driver createDriver(Clock clock, Config config) { + DriverFactory factory = new DriverFactoryWithClock(clock); RoutingSettings routingSettings = RoutingSettings.DEFAULT; RetrySettings retrySettings = RetrySettings.DEFAULT; - return factory.newInstance( neo4j.uri(), DEFAULT_AUTH_TOKEN, routingSettings, retrySettings, config, SecurityPlanImpl.insecure() ); + return factory.newInstance( + neo4j.uri(), DEFAULT_AUTH_TOKEN, routingSettings, retrySettings, config, SecurityPlanImpl.insecure()); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/SessionBoltV3IT.java b/driver/src/test/java/org/neo4j/driver/integration/SessionBoltV3IT.java index 2bfc4bcb5a..6388da523d 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/SessionBoltV3IT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/SessionBoltV3IT.java @@ -18,23 +18,37 @@ */ package org.neo4j.driver.integration; -import io.netty.channel.Channel; -import org.hamcrest.MatcherAssert; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.time.Duration.ofMillis; +import static java.util.Arrays.asList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; +import static org.junit.jupiter.api.Assertions.fail; +import static org.neo4j.driver.Config.defaultConfig; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V3; +import static org.neo4j.driver.util.TestUtil.TX_TIMEOUT_TEST_TIMEOUT; +import static org.neo4j.driver.util.TestUtil.await; +import io.netty.channel.Channel; import java.time.LocalDate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletionStage; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.async.AsyncSession; @@ -53,326 +67,291 @@ import org.neo4j.driver.util.DriverExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.time.Duration.ofMillis; -import static java.util.Arrays.asList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; -import static org.junit.jupiter.api.Assertions.fail; -import static org.neo4j.driver.Config.defaultConfig; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V3; -import static org.neo4j.driver.util.TestUtil.TX_TIMEOUT_TEST_TIMEOUT; -import static org.neo4j.driver.util.TestUtil.await; - -@EnabledOnNeo4jWith( BOLT_V3 ) +@EnabledOnNeo4jWith(BOLT_V3) @ParallelizableIT -class SessionBoltV3IT -{ +class SessionBoltV3IT { @RegisterExtension static final DriverExtension driver = new DriverExtension(); @Test - void shouldSetTransactionMetadata() - { - Map metadata = new HashMap<>(); - metadata.put( "a", "hello world" ); - metadata.put( "b", LocalDate.now() ); - metadata.put( "c", asList( true, false, true ) ); + void shouldSetTransactionMetadata() { + Map metadata = new HashMap<>(); + metadata.put("a", "hello world"); + metadata.put("b", LocalDate.now()); + metadata.put("c", asList(true, false, true)); - TransactionConfig config = TransactionConfig.builder() - .withMetadata( metadata ) - .build(); + TransactionConfig config = + TransactionConfig.builder().withMetadata(metadata).build(); // call listTransactions procedure that should list itself with the specified metadata - Result result = driver.session().run( "CALL dbms.listTransactions()", config ); - Map receivedMetadata = result.single().get( "metaData" ).asMap(); + Result result = driver.session().run("CALL dbms.listTransactions()", config); + Map receivedMetadata = result.single().get("metaData").asMap(); - assertEquals( metadata, receivedMetadata ); + assertEquals(metadata, receivedMetadata); } @Test - void shouldSetTransactionMetadataAsync() - { - Map metadata = new HashMap<>(); - metadata.put( "key1", "value1" ); - metadata.put( "key2", 42L ); + void shouldSetTransactionMetadataAsync() { + Map metadata = new HashMap<>(); + metadata.put("key1", "value1"); + metadata.put("key2", 42L); - TransactionConfig config = TransactionConfig.builder() - .withMetadata( metadata ) - .build(); + TransactionConfig config = + TransactionConfig.builder().withMetadata(metadata).build(); // call listTransactions procedure that should list itself with the specified metadata - CompletionStage> metadataFuture = driver.asyncSession() - .runAsync( "CALL dbms.listTransactions()", config ) - .thenCompose( ResultCursor::singleAsync ) - .thenApply( record -> record.get( "metaData" ).asMap() ); + CompletionStage> metadataFuture = driver.asyncSession() + .runAsync("CALL dbms.listTransactions()", config) + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> record.get("metaData").asMap()); - assertEquals( metadata, await( metadataFuture ) ); + assertEquals(metadata, await(metadataFuture)); } @Test - void shouldSetTransactionTimeout() - { + void shouldSetTransactionTimeout() { // create a dummy node Session session = driver.session(); - session.run( "CREATE (:Node)" ).consume(); + session.run("CREATE (:Node)").consume(); - try ( Session otherSession = driver.driver().session() ) - { - try ( Transaction otherTx = otherSession.beginTransaction() ) - { + try (Session otherSession = driver.driver().session()) { + try (Transaction otherTx = otherSession.beginTransaction()) { // lock dummy node but keep the transaction open - otherTx.run( "MATCH (n:Node) SET n.prop = 1" ).consume(); + otherTx.run("MATCH (n:Node) SET n.prop = 1").consume(); - assertTimeoutPreemptively( TX_TIMEOUT_TEST_TIMEOUT, () -> { - TransactionConfig config = TransactionConfig.builder().withTimeout( ofMillis( 1 ) ).build(); + assertTimeoutPreemptively(TX_TIMEOUT_TEST_TIMEOUT, () -> { + TransactionConfig config = + TransactionConfig.builder().withTimeout(ofMillis(1)).build(); // run a query in an auto-commit transaction with timeout and try to update the locked dummy node - Exception error = assertThrows( Exception.class, - () -> session.run( "MATCH (n:Node) SET n.prop = 2", config ).consume() ); - verifyValidException( error ); - } ); + Exception error = + assertThrows(Exception.class, () -> session.run("MATCH (n:Node) SET n.prop = 2", config) + .consume()); + verifyValidException(error); + }); } } } @Test - void shouldSetTransactionTimeoutAsync() - { + void shouldSetTransactionTimeoutAsync() { // create a dummy node AsyncSession asyncSession = driver.asyncSession(); - await( await( asyncSession.runAsync( "CREATE (:Node)" ) ).consumeAsync() ); + await(await(asyncSession.runAsync("CREATE (:Node)")).consumeAsync()); - try ( Session otherSession = driver.driver().session() ) - { - try ( Transaction otherTx = otherSession.beginTransaction() ) - { + try (Session otherSession = driver.driver().session()) { + try (Transaction otherTx = otherSession.beginTransaction()) { // lock dummy node but keep the transaction open - otherTx.run( "MATCH (n:Node) SET n.prop = 1" ).consume(); + otherTx.run("MATCH (n:Node) SET n.prop = 1").consume(); - assertTimeoutPreemptively( TX_TIMEOUT_TEST_TIMEOUT, () -> { - TransactionConfig config = TransactionConfig.builder() - .withTimeout( ofMillis( 1 ) ) - .build(); + assertTimeoutPreemptively(TX_TIMEOUT_TEST_TIMEOUT, () -> { + TransactionConfig config = + TransactionConfig.builder().withTimeout(ofMillis(1)).build(); // run a query in an auto-commit transaction with timeout and try to update the locked dummy node - CompletionStage resultFuture = asyncSession.runAsync( "MATCH (n:Node) SET n.prop = 2", config ) - .thenCompose( ResultCursor::consumeAsync ); + CompletionStage resultFuture = asyncSession + .runAsync("MATCH (n:Node) SET n.prop = 2", config) + .thenCompose(ResultCursor::consumeAsync); - Exception error = assertThrows( Exception.class, () -> await( resultFuture ) ); - verifyValidException( error ); - } ); + Exception error = assertThrows(Exception.class, () -> await(resultFuture)); + verifyValidException(error); + }); } } } @Test - void shouldSetTransactionMetadataWithAsyncReadTransactionFunction() - { - testTransactionMetadataWithAsyncTransactionFunctions( true ); + void shouldSetTransactionMetadataWithAsyncReadTransactionFunction() { + testTransactionMetadataWithAsyncTransactionFunctions(true); } @Test - void shouldSetTransactionMetadataWithAsyncWriteTransactionFunction() - { - testTransactionMetadataWithAsyncTransactionFunctions( false ); + void shouldSetTransactionMetadataWithAsyncWriteTransactionFunction() { + testTransactionMetadataWithAsyncTransactionFunctions(false); } @Test - void shouldSetTransactionMetadataWithReadTransactionFunction() - { - testTransactionMetadataWithTransactionFunctions( true ); + void shouldSetTransactionMetadataWithReadTransactionFunction() { + testTransactionMetadataWithTransactionFunctions(true); } @Test - void shouldSetTransactionMetadataWithWriteTransactionFunction() - { - testTransactionMetadataWithTransactionFunctions( false ); + void shouldSetTransactionMetadataWithWriteTransactionFunction() { + testTransactionMetadataWithTransactionFunctions(false); } @Test - void shouldUseBookmarksForAutoCommitTransactions() - { + void shouldUseBookmarksForAutoCommitTransactions() { Session session = driver.session(); Bookmark initialBookmark = session.lastBookmark(); - session.run( "CREATE ()" ).consume(); + session.run("CREATE ()").consume(); Bookmark bookmark1 = session.lastBookmark(); - assertNotNull( bookmark1 ); - assertNotEquals( initialBookmark, bookmark1 ); + assertNotNull(bookmark1); + assertNotEquals(initialBookmark, bookmark1); - session.run( "CREATE ()" ).consume(); + session.run("CREATE ()").consume(); Bookmark bookmark2 = session.lastBookmark(); - assertNotNull( bookmark2 ); - assertNotEquals( initialBookmark, bookmark2 ); - assertNotEquals( bookmark1, bookmark2 ); + assertNotNull(bookmark2); + assertNotEquals(initialBookmark, bookmark2); + assertNotEquals(bookmark1, bookmark2); - session.run( "CREATE ()" ).consume(); + session.run("CREATE ()").consume(); Bookmark bookmark3 = session.lastBookmark(); - assertNotNull( bookmark3 ); - assertNotEquals( initialBookmark, bookmark3 ); - assertNotEquals( bookmark1, bookmark3 ); - assertNotEquals( bookmark2, bookmark3 ); + assertNotNull(bookmark3); + assertNotEquals(initialBookmark, bookmark3); + assertNotEquals(bookmark1, bookmark3); + assertNotEquals(bookmark2, bookmark3); } @Test - void shouldUseBookmarksForAutoCommitAndUnmanagedTransactions() - { + void shouldUseBookmarksForAutoCommitAndUnmanagedTransactions() { Session session = driver.session(); Bookmark initialBookmark = session.lastBookmark(); - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "CREATE ()" ); + try (Transaction tx = session.beginTransaction()) { + tx.run("CREATE ()"); tx.commit(); } Bookmark bookmark1 = session.lastBookmark(); - assertNotNull( bookmark1 ); - assertNotEquals( initialBookmark, bookmark1 ); + assertNotNull(bookmark1); + assertNotEquals(initialBookmark, bookmark1); - session.run( "CREATE ()" ).consume(); + session.run("CREATE ()").consume(); Bookmark bookmark2 = session.lastBookmark(); - assertNotNull( bookmark2 ); - assertNotEquals( initialBookmark, bookmark2 ); - assertNotEquals( bookmark1, bookmark2 ); + assertNotNull(bookmark2); + assertNotEquals(initialBookmark, bookmark2); + assertNotEquals(bookmark1, bookmark2); - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "CREATE ()" ); + try (Transaction tx = session.beginTransaction()) { + tx.run("CREATE ()"); tx.commit(); } Bookmark bookmark3 = session.lastBookmark(); - assertNotNull( bookmark3 ); - assertNotEquals( initialBookmark, bookmark3 ); - assertNotEquals( bookmark1, bookmark3 ); - assertNotEquals( bookmark2, bookmark3 ); + assertNotNull(bookmark3); + assertNotEquals(initialBookmark, bookmark3); + assertNotEquals(bookmark1, bookmark3); + assertNotEquals(bookmark2, bookmark3); } @Test - void shouldUseBookmarksForAutoCommitTransactionsAndTransactionFunctions() - { + void shouldUseBookmarksForAutoCommitTransactionsAndTransactionFunctions() { Session session = driver.session(); Bookmark initialBookmark = session.lastBookmark(); - session.writeTransaction( tx -> tx.run( "CREATE ()" ) ); + session.writeTransaction(tx -> tx.run("CREATE ()")); Bookmark bookmark1 = session.lastBookmark(); - assertNotNull( bookmark1 ); - assertNotEquals( initialBookmark, bookmark1 ); + assertNotNull(bookmark1); + assertNotEquals(initialBookmark, bookmark1); - session.run( "CREATE ()" ).consume(); + session.run("CREATE ()").consume(); Bookmark bookmark2 = session.lastBookmark(); - assertNotNull( bookmark2 ); - assertNotEquals( initialBookmark, bookmark2 ); - assertNotEquals( bookmark1, bookmark2 ); + assertNotNull(bookmark2); + assertNotEquals(initialBookmark, bookmark2); + assertNotEquals(bookmark1, bookmark2); - session.writeTransaction( tx -> tx.run( "CREATE ()" ) ); + session.writeTransaction(tx -> tx.run("CREATE ()")); Bookmark bookmark3 = session.lastBookmark(); - assertNotNull( bookmark3 ); - assertNotEquals( initialBookmark, bookmark3 ); - assertNotEquals( bookmark1, bookmark3 ); - assertNotEquals( bookmark2, bookmark3 ); + assertNotNull(bookmark3); + assertNotEquals(initialBookmark, bookmark3); + assertNotEquals(bookmark1, bookmark3); + assertNotEquals(bookmark2, bookmark3); } @Test - void shouldSendGoodbyeWhenClosingDriver() - { + void shouldSendGoodbyeWhenClosingDriver() { int txCount = 13; MessageRecordingDriverFactory driverFactory = new MessageRecordingDriverFactory(); - try ( Driver otherDriver = driverFactory.newInstance( driver.uri(), driver.authToken(), RoutingSettings.DEFAULT, RetrySettings.DEFAULT, defaultConfig(), - SecurityPlanImpl.insecure() ) ) - { + try (Driver otherDriver = driverFactory.newInstance( + driver.uri(), + driver.authToken(), + RoutingSettings.DEFAULT, + RetrySettings.DEFAULT, + defaultConfig(), + SecurityPlanImpl.insecure())) { List sessions = new ArrayList<>(); List txs = new ArrayList<>(); - for ( int i = 0; i < txCount; i++ ) - { + for (int i = 0; i < txCount; i++) { Session session = otherDriver.session(); - sessions.add( session ); + sessions.add(session); Transaction tx = session.beginTransaction(); - txs.add( tx ); + txs.add(tx); } - for ( int i = 0; i < txCount; i++ ) - { - Session session = sessions.get( i ); - Transaction tx = txs.get( i ); + for (int i = 0; i < txCount; i++) { + Session session = sessions.get(i); + Transaction tx = txs.get(i); - tx.run( "CREATE ()" ); + tx.run("CREATE ()"); tx.commit(); session.close(); } } - Map> messagesByChannel = driverFactory.getMessagesByChannel(); - assertEquals( txCount, messagesByChannel.size() ); + Map> messagesByChannel = driverFactory.getMessagesByChannel(); + assertEquals(txCount, messagesByChannel.size()); - for ( List messages : messagesByChannel.values() ) - { - assertThat( messages.size(), greaterThan( 2 ) ); - assertThat( messages.get( 0 ), instanceOf( HelloMessage.class ) ); // first message is HELLO - assertThat( messages.get( messages.size() - 1 ), instanceOf( GoodbyeMessage.class ) ); // last message is GOODBYE + for (List messages : messagesByChannel.values()) { + assertThat(messages.size(), greaterThan(2)); + assertThat(messages.get(0), instanceOf(HelloMessage.class)); // first message is HELLO + assertThat(messages.get(messages.size() - 1), instanceOf(GoodbyeMessage.class)); // last message is GOODBYE } } - private static void testTransactionMetadataWithAsyncTransactionFunctions( boolean read ) - { + private static void testTransactionMetadataWithAsyncTransactionFunctions(boolean read) { AsyncSession asyncSession = driver.asyncSession(); - Map metadata = new HashMap<>(); - metadata.put( "foo", "bar" ); - metadata.put( "baz", true ); - metadata.put( "qux", 12345L ); + Map metadata = new HashMap<>(); + metadata.put("foo", "bar"); + metadata.put("baz", true); + metadata.put("qux", 12345L); - TransactionConfig config = TransactionConfig.builder() - .withMetadata( metadata ) - .build(); + TransactionConfig config = + TransactionConfig.builder().withMetadata(metadata).build(); // call listTransactions procedure that should list itself with the specified metadata - CompletionStage singleFuture = - read ? asyncSession.readTransactionAsync( tx -> tx.runAsync( "CALL dbms.listTransactions()" ).thenCompose( ResultCursor::singleAsync ), config ) - : asyncSession.writeTransactionAsync( tx -> tx.runAsync( "CALL dbms.listTransactions()" ).thenCompose( ResultCursor::singleAsync ), config ); - - CompletionStage> metadataFuture = singleFuture.thenApply( record -> record.get( "metaData" ).asMap() ); - - assertEquals( metadata, await( metadataFuture ) ); + CompletionStage singleFuture = read + ? asyncSession.readTransactionAsync( + tx -> tx.runAsync("CALL dbms.listTransactions()").thenCompose(ResultCursor::singleAsync), + config) + : asyncSession.writeTransactionAsync( + tx -> tx.runAsync("CALL dbms.listTransactions()").thenCompose(ResultCursor::singleAsync), + config); + + CompletionStage> metadataFuture = + singleFuture.thenApply(record -> record.get("metaData").asMap()); + + assertEquals(metadata, await(metadataFuture)); } - private static void testTransactionMetadataWithTransactionFunctions( boolean read ) - { + private static void testTransactionMetadataWithTransactionFunctions(boolean read) { Session session = driver.session(); - Map metadata = new HashMap<>(); - metadata.put( "foo", "bar" ); - metadata.put( "baz", true ); - metadata.put( "qux", 12345L ); + Map metadata = new HashMap<>(); + metadata.put("foo", "bar"); + metadata.put("baz", true); + metadata.put("qux", 12345L); - TransactionConfig config = TransactionConfig.builder() - .withMetadata( metadata ) - .build(); + TransactionConfig config = + TransactionConfig.builder().withMetadata(metadata).build(); // call listTransactions procedure that should list itself with the specified metadata - Record single = read ? session.readTransaction( tx -> tx.run( "CALL dbms.listTransactions()" ).single(), config ) - : session.writeTransaction( tx -> tx.run( "CALL dbms.listTransactions()" ).single(), config ); + Record single = read + ? session.readTransaction( + tx -> tx.run("CALL dbms.listTransactions()").single(), config) + : session.writeTransaction( + tx -> tx.run("CALL dbms.listTransactions()").single(), config); - Map receivedMetadata = single.get( "metaData" ).asMap(); + Map receivedMetadata = single.get("metaData").asMap(); - assertEquals( metadata, receivedMetadata ); + assertEquals(metadata, receivedMetadata); } - private static void verifyValidException( Exception error ) - { + private static void verifyValidException(Exception error) { // Server 4.1 corrected this exception to ClientException. Testing either here for compatibility - if ( error instanceof TransientException || error instanceof ClientException ) - { - assertThat( error.getMessage(), containsString( "terminated" ) ); - } - else - { - fail( "Expected either a TransientException or ClientException", error ); + if (error instanceof TransientException || error instanceof ClientException) { + assertThat(error.getMessage(), containsString("terminated")); + } else { + fail("Expected either a TransientException or ClientException", error); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/SessionIT.java b/driver/src/test/java/org/neo4j/driver/integration/SessionIT.java index bf455d4770..709b0407d0 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/SessionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/SessionIT.java @@ -18,10 +18,39 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import reactor.test.StepVerifier; +import static java.util.Collections.emptyList; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.SessionConfig.forDatabase; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkContainsSingleValue; +import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkIsEmpty; +import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkIsNotEmpty; +import static org.neo4j.driver.internal.util.Matchers.arithmeticError; +import static org.neo4j.driver.internal.util.Matchers.connectionAcquisitionTimeoutError; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; +import static org.neo4j.driver.util.DaemonThreadFactory.daemon; +import static org.neo4j.driver.util.Neo4jRunner.DEFAULT_AUTH_TOKEN; import java.util.HashSet; import java.util.List; @@ -35,7 +64,9 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthToken; import org.neo4j.driver.Config; @@ -66,44 +97,10 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; import org.neo4j.driver.util.TestUtil; - -import static java.util.Collections.emptyList; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.emptyArray; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.SessionConfig.forDatabase; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkContainsSingleValue; -import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkIsEmpty; -import static org.neo4j.driver.internal.util.BookmarkUtil.assertBookmarkIsNotEmpty; -import static org.neo4j.driver.internal.util.Matchers.arithmeticError; -import static org.neo4j.driver.internal.util.Matchers.connectionAcquisitionTimeoutError; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; -import static org.neo4j.driver.util.DaemonThreadFactory.daemon; -import static org.neo4j.driver.util.Neo4jRunner.DEFAULT_AUTH_TOKEN; +import reactor.test.StepVerifier; @ParallelizableIT -class SessionIT -{ +class SessionIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @@ -111,21 +108,17 @@ class SessionIT private ExecutorService executor; @AfterEach - void tearDown() - { - if ( driver != null ) - { + void tearDown() { + if (driver != null) { driver.close(); } - if ( executor != null ) - { + if (executor != null) { executor.shutdownNow(); } } @Test - void shouldKnowSessionIsClosed() - { + void shouldKnowSessionIsClosed() { // Given Session session = neo4j.driver().session(); @@ -133,860 +126,754 @@ void shouldKnowSessionIsClosed() session.close(); // Then - assertFalse( session.isOpen() ); + assertFalse(session.isOpen()); } @Test - void shouldHandleNullConfig() - { + void shouldHandleNullConfig() { // Given - driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), null ); + driver = GraphDatabase.driver(neo4j.uri(), neo4j.authToken(), null); Session session = driver.session(); // When session.close(); // Then - assertFalse( session.isOpen() ); + assertFalse(session.isOpen()); } - @SuppressWarnings( "ConstantConditions" ) + @SuppressWarnings("ConstantConditions") @Test - void shouldHandleNullAuthToken() - { + void shouldHandleNullAuthToken() { AuthToken token = null; // null auth token should be interpreted as AuthTokens.none() and fail driver creation // because server expects basic auth - assertThrows( AuthenticationException.class, () -> GraphDatabase.driver( neo4j.uri(), token ).verifyConnectivity() ); + assertThrows(AuthenticationException.class, () -> GraphDatabase.driver(neo4j.uri(), token) + .verifyConnectivity()); } @Test - void executeReadTxInReadSession() - { - testExecuteReadTx( AccessMode.READ ); + void executeReadTxInReadSession() { + testExecuteReadTx(AccessMode.READ); } @Test - void executeReadTxInWriteSession() - { - testExecuteReadTx( AccessMode.WRITE ); + void executeReadTxInWriteSession() { + testExecuteReadTx(AccessMode.WRITE); } @Test - void executeWriteTxInReadSession() - { - testExecuteWriteTx( AccessMode.READ ); + void executeWriteTxInReadSession() { + testExecuteWriteTx(AccessMode.READ); } @Test - void executeWriteTxInWriteSession() - { - testExecuteWriteTx( AccessMode.WRITE ); + void executeWriteTxInWriteSession() { + testExecuteWriteTx(AccessMode.WRITE); } @Test - void rollsBackWriteTxInReadSessionWhenFunctionThrows() - { - testTxRollbackWhenFunctionThrows( AccessMode.READ ); + void rollsBackWriteTxInReadSessionWhenFunctionThrows() { + testTxRollbackWhenFunctionThrows(AccessMode.READ); } @Test - void rollsBackWriteTxInWriteSessionWhenFunctionThrows() - { - testTxRollbackWhenFunctionThrows( AccessMode.WRITE ); + void rollsBackWriteTxInWriteSessionWhenFunctionThrows() { + testTxRollbackWhenFunctionThrows(AccessMode.WRITE); } @Test - void readTxRetriedUntilSuccess() - { + void readTxRetriedUntilSuccess() { int failures = 6; int retries = failures + 1; - try ( Driver driver = newDriverWithFixedRetries( retries ) ) - { - try ( Session session = driver.session() ) - { - session.run( "CREATE (:Person {name: 'Bruce Banner'})" ); + try (Driver driver = newDriverWithFixedRetries(retries)) { + try (Session session = driver.session()) { + session.run("CREATE (:Person {name: 'Bruce Banner'})"); } - ThrowingWork work = newThrowingWorkSpy( "MATCH (n) RETURN n.name", failures ); - try ( Session session = driver.session() ) - { - Record record = session.readTransaction( work ); - assertEquals( "Bruce Banner", record.get( 0 ).asString() ); + ThrowingWork work = newThrowingWorkSpy("MATCH (n) RETURN n.name", failures); + try (Session session = driver.session()) { + Record record = session.readTransaction(work); + assertEquals("Bruce Banner", record.get(0).asString()); } - verify( work, times( retries ) ).execute( any( Transaction.class ) ); + verify(work, times(retries)).execute(any(Transaction.class)); } } @Test - void writeTxRetriedUntilSuccess() - { + void writeTxRetriedUntilSuccess() { int failures = 4; int retries = failures + 1; - try ( Driver driver = newDriverWithFixedRetries( retries ) ) - { - ThrowingWork work = newThrowingWorkSpy( "CREATE (p:Person {name: 'Hulk'}) RETURN p", failures ); - try ( Session session = driver.session() ) - { - Record record = session.writeTransaction( work ); - assertEquals( "Hulk", record.get( 0 ).asNode().get( "name" ).asString() ); + try (Driver driver = newDriverWithFixedRetries(retries)) { + ThrowingWork work = newThrowingWorkSpy("CREATE (p:Person {name: 'Hulk'}) RETURN p", failures); + try (Session session = driver.session()) { + Record record = session.writeTransaction(work); + assertEquals("Hulk", record.get(0).asNode().get("name").asString()); } - try ( Session session = driver.session() ) - { - Record record = session.run( "MATCH (p: Person {name: 'Hulk'}) RETURN count(p)" ).single(); - assertEquals( 1, record.get( 0 ).asInt() ); + try (Session session = driver.session()) { + Record record = session.run("MATCH (p: Person {name: 'Hulk'}) RETURN count(p)") + .single(); + assertEquals(1, record.get(0).asInt()); } - verify( work, times( retries ) ).execute( any( Transaction.class ) ); + verify(work, times(retries)).execute(any(Transaction.class)); } } @Test - void readTxRetriedUntilFailure() - { + void readTxRetriedUntilFailure() { int failures = 3; int retries = failures - 1; - try ( Driver driver = newDriverWithFixedRetries( retries ) ) - { - ThrowingWork work = newThrowingWorkSpy( "MATCH (n) RETURN n.name", failures ); - try ( Session session = driver.session() ) - { - assertThrows( ServiceUnavailableException.class, () -> session.readTransaction( work ) ); + try (Driver driver = newDriverWithFixedRetries(retries)) { + ThrowingWork work = newThrowingWorkSpy("MATCH (n) RETURN n.name", failures); + try (Session session = driver.session()) { + assertThrows(ServiceUnavailableException.class, () -> session.readTransaction(work)); } - verify( work, times( failures ) ).execute( any( Transaction.class ) ); + verify(work, times(failures)).execute(any(Transaction.class)); } } @Test - void writeTxRetriedUntilFailure() - { + void writeTxRetriedUntilFailure() { int failures = 8; int retries = failures - 1; - try ( Driver driver = newDriverWithFixedRetries( retries ) ) - { - ThrowingWork work = newThrowingWorkSpy( "CREATE (:Person {name: 'Ronan'})", failures ); - try ( Session session = driver.session() ) - { - assertThrows( ServiceUnavailableException.class, () -> session.writeTransaction( work ) ); + try (Driver driver = newDriverWithFixedRetries(retries)) { + ThrowingWork work = newThrowingWorkSpy("CREATE (:Person {name: 'Ronan'})", failures); + try (Session session = driver.session()) { + assertThrows(ServiceUnavailableException.class, () -> session.writeTransaction(work)); } - try ( Session session = driver.session() ) - { - Result result = session.run( "MATCH (p:Person {name: 'Ronan'}) RETURN count(p)" ); - assertEquals( 0, result.single().get( 0 ).asInt() ); + try (Session session = driver.session()) { + Result result = session.run("MATCH (p:Person {name: 'Ronan'}) RETURN count(p)"); + assertEquals(0, result.single().get(0).asInt()); } - verify( work, times( failures ) ).execute( any( Transaction.class ) ); + verify(work, times(failures)).execute(any(Transaction.class)); } } @Test - void writeTxRetryErrorsAreCollected() - { - try ( Driver driver = newDriverWithLimitedRetries( 5, TimeUnit.SECONDS ) ) - { - ThrowingWork work = newThrowingWorkSpy( "CREATE (:Person {name: 'Ronan'})", Integer.MAX_VALUE ); + void writeTxRetryErrorsAreCollected() { + try (Driver driver = newDriverWithLimitedRetries(5, TimeUnit.SECONDS)) { + ThrowingWork work = newThrowingWorkSpy("CREATE (:Person {name: 'Ronan'})", Integer.MAX_VALUE); int suppressedErrors; - try ( Session session = driver.session() ) - { - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, () -> session.writeTransaction( work ) ); - assertThat( e.getSuppressed(), not( emptyArray() ) ); + try (Session session = driver.session()) { + ServiceUnavailableException e = + assertThrows(ServiceUnavailableException.class, () -> session.writeTransaction(work)); + assertThat(e.getSuppressed(), not(emptyArray())); suppressedErrors = e.getSuppressed().length; } - try ( Session session = driver.session() ) - { - Result result = session.run( "MATCH (p:Person {name: 'Ronan'}) RETURN count(p)" ); - assertEquals( 0, result.single().get( 0 ).asInt() ); + try (Session session = driver.session()) { + Result result = session.run("MATCH (p:Person {name: 'Ronan'}) RETURN count(p)"); + assertEquals(0, result.single().get(0).asInt()); } - verify( work, times( suppressedErrors + 1 ) ).execute( any( Transaction.class ) ); + verify(work, times(suppressedErrors + 1)).execute(any(Transaction.class)); } } @Test - void readTxRetryErrorsAreCollected() - { - try ( Driver driver = newDriverWithLimitedRetries( 4, TimeUnit.SECONDS ) ) - { - ThrowingWork work = newThrowingWorkSpy( "MATCH (n) RETURN n.name", Integer.MAX_VALUE ); + void readTxRetryErrorsAreCollected() { + try (Driver driver = newDriverWithLimitedRetries(4, TimeUnit.SECONDS)) { + ThrowingWork work = newThrowingWorkSpy("MATCH (n) RETURN n.name", Integer.MAX_VALUE); int suppressedErrors; - try ( Session session = driver.session() ) - { - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, () -> session.readTransaction( work ) ); - assertThat( e.getSuppressed(), not( emptyArray() ) ); + try (Session session = driver.session()) { + ServiceUnavailableException e = + assertThrows(ServiceUnavailableException.class, () -> session.readTransaction(work)); + assertThat(e.getSuppressed(), not(emptyArray())); suppressedErrors = e.getSuppressed().length; } - verify( work, times( suppressedErrors + 1 ) ).execute( any( Transaction.class ) ); + verify(work, times(suppressedErrors + 1)).execute(any(Transaction.class)); } } @Test - void readTxCommittedWithoutTxSuccess() - { - try ( Driver driver = newDriverWithoutRetries(); - Session session = driver.session() ) - { - assertBookmarkIsEmpty( session.lastBookmark() ); + void readTxCommittedWithoutTxSuccess() { + try (Driver driver = newDriverWithoutRetries(); + Session session = driver.session()) { + assertBookmarkIsEmpty(session.lastBookmark()); - long answer = session.readTransaction( tx -> tx.run( "RETURN 42" ).single().get( 0 ).asLong() ); - assertEquals( 42, answer ); + long answer = session.readTransaction( + tx -> tx.run("RETURN 42").single().get(0).asLong()); + assertEquals(42, answer); // bookmark should be not-null after commit - assertBookmarkContainsSingleValue( session.lastBookmark() ); + assertBookmarkContainsSingleValue(session.lastBookmark()); } } @Test - void writeTxCommittedWithoutTxSuccess() - { - try ( Driver driver = newDriverWithoutRetries() ) - { - try ( Session session = driver.session() ) - { - long answer = session.writeTransaction( tx -> - tx.run( "CREATE (:Person {name: 'Thor Odinson'}) RETURN 42" ).single().get( 0 ).asLong() ); - assertEquals( 42, answer ); + void writeTxCommittedWithoutTxSuccess() { + try (Driver driver = newDriverWithoutRetries()) { + try (Session session = driver.session()) { + long answer = session.writeTransaction(tx -> tx.run("CREATE (:Person {name: 'Thor Odinson'}) RETURN 42") + .single() + .get(0) + .asLong()); + assertEquals(42, answer); } - try ( Session session = driver.session() ) - { - Result result = session.run( "MATCH (p:Person {name: 'Thor Odinson'}) RETURN count(p)" ); - assertEquals( 1, result.single().get( 0 ).asInt() ); + try (Session session = driver.session()) { + Result result = session.run("MATCH (p:Person {name: 'Thor Odinson'}) RETURN count(p)"); + assertEquals(1, result.single().get(0).asInt()); } } } @Test - void readTxRolledBackWithTxFailure() - { - try ( Driver driver = newDriverWithoutRetries(); - Session session = driver.session() ) - { - assertBookmarkIsEmpty( session.lastBookmark() ); - - long answer = session.readTransaction( tx -> - { - Result result = tx.run( "RETURN 42" ); - long single = result.single().get( 0 ).asLong(); + void readTxRolledBackWithTxFailure() { + try (Driver driver = newDriverWithoutRetries(); + Session session = driver.session()) { + assertBookmarkIsEmpty(session.lastBookmark()); + + long answer = session.readTransaction(tx -> { + Result result = tx.run("RETURN 42"); + long single = result.single().get(0).asLong(); tx.rollback(); return single; - } ); - assertEquals( 42, answer ); + }); + assertEquals(42, answer); // bookmark should remain null after rollback - assertBookmarkIsEmpty( session.lastBookmark() ); + assertBookmarkIsEmpty(session.lastBookmark()); } } @Test - void writeTxRolledBackWithTxFailure() - { - try ( Driver driver = newDriverWithoutRetries() ) - { - try ( Session session = driver.session() ) - { - int answer = session.writeTransaction( tx -> - { - tx.run( "CREATE (:Person {name: 'Natasha Romanoff'})" ); + void writeTxRolledBackWithTxFailure() { + try (Driver driver = newDriverWithoutRetries()) { + try (Session session = driver.session()) { + int answer = session.writeTransaction(tx -> { + tx.run("CREATE (:Person {name: 'Natasha Romanoff'})"); tx.rollback(); return 42; - } ); + }); - assertEquals( 42, answer ); + assertEquals(42, answer); } - try ( Session session = driver.session() ) - { - Result result = session.run( "MATCH (p:Person {name: 'Natasha Romanoff'}) RETURN count(p)" ); - assertEquals( 0, result.single().get( 0 ).asInt() ); + try (Session session = driver.session()) { + Result result = session.run("MATCH (p:Person {name: 'Natasha Romanoff'}) RETURN count(p)"); + assertEquals(0, result.single().get(0).asInt()); } } } @Test - void readTxRolledBackWhenExceptionIsThrown() - { - try ( Driver driver = newDriverWithoutRetries(); - Session session = driver.session() ) - { - assertBookmarkIsEmpty( session.lastBookmark() ); - - assertThrows( IllegalStateException.class, () -> - session.readTransaction( tx -> - { - Result result = tx.run( "RETURN 42" ); - if ( result.single().get( 0 ).asLong() == 42 ) - { + void readTxRolledBackWhenExceptionIsThrown() { + try (Driver driver = newDriverWithoutRetries(); + Session session = driver.session()) { + assertBookmarkIsEmpty(session.lastBookmark()); + + assertThrows( + IllegalStateException.class, + () -> session.readTransaction(tx -> { + Result result = tx.run("RETURN 42"); + if (result.single().get(0).asLong() == 42) { throw new IllegalStateException(); } return 1L; - } ) ); + })); // bookmark should remain null after rollback - assertBookmarkIsEmpty( session.lastBookmark() ); + assertBookmarkIsEmpty(session.lastBookmark()); } } @Test - void writeTxRolledBackWhenExceptionIsThrown() - { - try ( Driver driver = newDriverWithoutRetries() ) - { - try ( Session session = driver.session() ) - { - assertThrows( IllegalStateException.class, () -> - session.writeTransaction( tx -> - { - tx.run( "CREATE (:Person {name: 'Loki Odinson'})" ); + void writeTxRolledBackWhenExceptionIsThrown() { + try (Driver driver = newDriverWithoutRetries()) { + try (Session session = driver.session()) { + assertThrows( + IllegalStateException.class, + () -> session.writeTransaction(tx -> { + tx.run("CREATE (:Person {name: 'Loki Odinson'})"); throw new IllegalStateException(); - } ) ); + })); } - try ( Session session = driver.session() ) - { - Result result = session.run( "MATCH (p:Person {name: 'Natasha Romanoff'}) RETURN count(p)" ); - assertEquals( 0, result.single().get( 0 ).asInt() ); + try (Session session = driver.session()) { + Result result = session.run("MATCH (p:Person {name: 'Natasha Romanoff'}) RETURN count(p)"); + assertEquals(0, result.single().get(0).asInt()); } } } @Test - void readTxRolledBackWhenMarkedBothSuccessAndFailure() - { - try ( Driver driver = newDriverWithoutRetries(); - Session session = driver.session() ) - { - ClientException error = assertThrows( ClientException.class, () -> session.readTransaction( tx -> { - Result result = tx.run( "RETURN 42" ); - tx.commit(); - tx.rollback(); - return result.single().get( 0 ).asLong(); - } ) ); - assertThat( error.getMessage(), startsWith( "Can't rollback, transaction has been committed" ) ); + void readTxRolledBackWhenMarkedBothSuccessAndFailure() { + try (Driver driver = newDriverWithoutRetries(); + Session session = driver.session()) { + ClientException error = assertThrows( + ClientException.class, + () -> session.readTransaction(tx -> { + Result result = tx.run("RETURN 42"); + tx.commit(); + tx.rollback(); + return result.single().get(0).asLong(); + })); + assertThat(error.getMessage(), startsWith("Can't rollback, transaction has been committed")); } } @Test - void writeTxFailWhenBothCommitAndRollback() - { - try ( Driver driver = newDriverWithoutRetries() ) - { - try ( Session session = driver.session() ) - { - ClientException error = assertThrows( ClientException.class, () -> session.writeTransaction( tx -> { - tx.run( "CREATE (:Person {name: 'Natasha Romanoff'})" ); - tx.commit(); - tx.rollback(); - return 42; - } ) ); + void writeTxFailWhenBothCommitAndRollback() { + try (Driver driver = newDriverWithoutRetries()) { + try (Session session = driver.session()) { + ClientException error = assertThrows( + ClientException.class, + () -> session.writeTransaction(tx -> { + tx.run("CREATE (:Person {name: 'Natasha Romanoff'})"); + tx.commit(); + tx.rollback(); + return 42; + })); - assertThat( error.getMessage(), startsWith( "Can't rollback, transaction has been committed" ) ); + assertThat(error.getMessage(), startsWith("Can't rollback, transaction has been committed")); } } } @Test - void readTxCommittedWhenCommitAndThrowsException() - { - try ( Driver driver = newDriverWithoutRetries(); - Session session = driver.session() ) - { - assertBookmarkIsEmpty( session.lastBookmark() ); - - assertThrows( IllegalStateException.class, () -> - session.readTransaction( tx -> - { - tx.run( "RETURN 42" ); + void readTxCommittedWhenCommitAndThrowsException() { + try (Driver driver = newDriverWithoutRetries(); + Session session = driver.session()) { + assertBookmarkIsEmpty(session.lastBookmark()); + + assertThrows( + IllegalStateException.class, + () -> session.readTransaction(tx -> { + tx.run("RETURN 42"); tx.commit(); throw new IllegalStateException(); - } ) ); + })); // We successfully committed - assertBookmarkIsNotEmpty( session.lastBookmark() ); + assertBookmarkIsNotEmpty(session.lastBookmark()); } } @Test - void writeTxCommittedWhenCommitAndThrowsException() - { - try ( Driver driver = newDriverWithoutRetries() ) - { - try ( Session session = driver.session() ) - { - assertThrows( IllegalStateException.class, () -> - session.writeTransaction( tx -> - { - tx.run( "CREATE (:Person {name: 'Natasha Romanoff'})" ); + void writeTxCommittedWhenCommitAndThrowsException() { + try (Driver driver = newDriverWithoutRetries()) { + try (Session session = driver.session()) { + assertThrows( + IllegalStateException.class, + () -> session.writeTransaction(tx -> { + tx.run("CREATE (:Person {name: 'Natasha Romanoff'})"); tx.commit(); throw new IllegalStateException(); - } ) ); + })); } - try ( Session session = driver.session() ) - { - Result result = session.run( "MATCH (p:Person {name: 'Natasha Romanoff'}) RETURN count(p)" ); - assertEquals( 1, result.single().get( 0 ).asInt() ); + try (Session session = driver.session()) { + Result result = session.run("MATCH (p:Person {name: 'Natasha Romanoff'}) RETURN count(p)"); + assertEquals(1, result.single().get(0).asInt()); } } } @Test - void readRolledBackWhenRollbackAndThrowsException() - { - try ( Driver driver = newDriverWithoutRetries(); - Session session = driver.session() ) - { - assertBookmarkIsEmpty( session.lastBookmark() ); - - assertThrows( IllegalStateException.class, () -> - session.readTransaction( tx -> - { - tx.run( "RETURN 42" ); + void readRolledBackWhenRollbackAndThrowsException() { + try (Driver driver = newDriverWithoutRetries(); + Session session = driver.session()) { + assertBookmarkIsEmpty(session.lastBookmark()); + + assertThrows( + IllegalStateException.class, + () -> session.readTransaction(tx -> { + tx.run("RETURN 42"); tx.rollback(); throw new IllegalStateException(); - } ) ); + })); // bookmark should remain null after rollback - assertBookmarkIsEmpty( session.lastBookmark() ); + assertBookmarkIsEmpty(session.lastBookmark()); } } @Test - void writeTxRolledBackWhenRollbackAndThrowsException() - { - try ( Driver driver = newDriverWithoutRetries() ) - { - try ( Session session = driver.session() ) - { - assertThrows( IllegalStateException.class, () -> - session.writeTransaction( tx -> - { - tx.run( "CREATE (:Person {name: 'Natasha Romanoff'})" ); + void writeTxRolledBackWhenRollbackAndThrowsException() { + try (Driver driver = newDriverWithoutRetries()) { + try (Session session = driver.session()) { + assertThrows( + IllegalStateException.class, + () -> session.writeTransaction(tx -> { + tx.run("CREATE (:Person {name: 'Natasha Romanoff'})"); tx.rollback(); throw new IllegalStateException(); - } ) ); + })); } - try ( Session session = driver.session() ) - { - Result result = session.run( "MATCH (p:Person {name: 'Natasha Romanoff'}) RETURN count(p)" ); - assertEquals( 0, result.single().get( 0 ).asInt() ); + try (Session session = driver.session()) { + Result result = session.run("MATCH (p:Person {name: 'Natasha Romanoff'}) RETURN count(p)"); + assertEquals(0, result.single().get(0).asInt()); } } } @Test - void transactionRunShouldFailOnDeadlocks() throws Exception - { + void transactionRunShouldFailOnDeadlocks() throws Exception { final int nodeId1 = 42; final int nodeId2 = 4242; final int newNodeId1 = 1; final int newNodeId2 = 2; - createNodeWithId( nodeId1 ); - createNodeWithId( nodeId2 ); + createNodeWithId(nodeId1); + createNodeWithId(nodeId2); - final CountDownLatch latch1 = new CountDownLatch( 1 ); - final CountDownLatch latch2 = new CountDownLatch( 1 ); + final CountDownLatch latch1 = new CountDownLatch(1); + final CountDownLatch latch2 = new CountDownLatch(1); - Future result1 = executeInDifferentThread( () -> - { - try ( Session session = neo4j.driver().session(); - Transaction tx = session.beginTransaction() ) - { + Future result1 = executeInDifferentThread(() -> { + try (Session session = neo4j.driver().session(); + Transaction tx = session.beginTransaction()) { // lock first node - updateNodeId( tx, nodeId1, newNodeId1 ).consume(); + updateNodeId(tx, nodeId1, newNodeId1).consume(); latch1.await(); latch2.countDown(); // lock second node - updateNodeId( tx, nodeId2, newNodeId1 ).consume(); + updateNodeId(tx, nodeId2, newNodeId1).consume(); tx.commit(); } return null; - } ); + }); - Future result2 = executeInDifferentThread( () -> - { - try ( Session session = neo4j.driver().session(); - Transaction tx = session.beginTransaction() ) - { + Future result2 = executeInDifferentThread(() -> { + try (Session session = neo4j.driver().session(); + Transaction tx = session.beginTransaction()) { // lock second node - updateNodeId( tx, nodeId2, newNodeId2 ).consume(); + updateNodeId(tx, nodeId2, newNodeId2).consume(); latch1.countDown(); latch2.await(); // lock first node - updateNodeId( tx, nodeId1, newNodeId2 ).consume(); + updateNodeId(tx, nodeId1, newNodeId2).consume(); tx.commit(); } return null; - } ); + }); - boolean firstResultFailed = assertOneOfTwoFuturesFailWithDeadlock( result1, result2 ); - if ( firstResultFailed ) - { - assertEquals( 0, countNodesWithId( newNodeId1 ) ); - assertEquals( 2, countNodesWithId( newNodeId2 ) ); - } - else - { - assertEquals( 2, countNodesWithId( newNodeId1 ) ); - assertEquals( 0, countNodesWithId( newNodeId2 ) ); + boolean firstResultFailed = assertOneOfTwoFuturesFailWithDeadlock(result1, result2); + if (firstResultFailed) { + assertEquals(0, countNodesWithId(newNodeId1)); + assertEquals(2, countNodesWithId(newNodeId2)); + } else { + assertEquals(2, countNodesWithId(newNodeId1)); + assertEquals(0, countNodesWithId(newNodeId2)); } } @Test - void writeTransactionFunctionShouldRetryDeadlocks() throws Exception - { + void writeTransactionFunctionShouldRetryDeadlocks() throws Exception { final int nodeId1 = 42; final int nodeId2 = 4242; final int nodeId3 = 424242; final int newNodeId1 = 1; final int newNodeId2 = 2; - createNodeWithId( nodeId1 ); - createNodeWithId( nodeId2 ); + createNodeWithId(nodeId1); + createNodeWithId(nodeId2); - final CountDownLatch latch1 = new CountDownLatch( 1 ); - final CountDownLatch latch2 = new CountDownLatch( 1 ); + final CountDownLatch latch1 = new CountDownLatch(1); + final CountDownLatch latch2 = new CountDownLatch(1); - Future result1 = executeInDifferentThread( () -> - { - try ( Session session = neo4j.driver().session(); - Transaction tx = session.beginTransaction() ) - { + Future result1 = executeInDifferentThread(() -> { + try (Session session = neo4j.driver().session(); + Transaction tx = session.beginTransaction()) { // lock first node - updateNodeId( tx, nodeId1, newNodeId1 ).consume(); + updateNodeId(tx, nodeId1, newNodeId1).consume(); latch1.await(); latch2.countDown(); // lock second node - updateNodeId( tx, nodeId2, newNodeId1 ).consume(); + updateNodeId(tx, nodeId2, newNodeId1).consume(); tx.commit(); } return null; - } ); - - Future result2 = executeInDifferentThread( () -> - { - try ( Session session = neo4j.driver().session() ) - { - session.writeTransaction( tx -> - { + }); + + Future result2 = executeInDifferentThread(() -> { + try (Session session = neo4j.driver().session()) { + session.writeTransaction(tx -> { // lock second node - updateNodeId( tx, nodeId2, newNodeId2 ).consume(); + updateNodeId(tx, nodeId2, newNodeId2).consume(); latch1.countDown(); - await( latch2 ); + await(latch2); // lock first node - updateNodeId( tx, nodeId1, newNodeId2 ).consume(); + updateNodeId(tx, nodeId1, newNodeId2).consume(); - createNodeWithId( nodeId3 ); + createNodeWithId(nodeId3); return null; - } ); + }); } return null; - } ); + }); boolean firstResultFailed = false; - try - { + try { // first future may: // 1) succeed, when it's tx was able to grab both locks and tx in other future was // terminated because of a deadlock // 2) fail, when it's tx was terminated because of a deadlock - assertNull( result1.get( 20, TimeUnit.SECONDS ) ); - } - catch ( ExecutionException e ) - { + assertNull(result1.get(20, TimeUnit.SECONDS)); + } catch (ExecutionException e) { firstResultFailed = true; } // second future can't fail because deadlocks are retried - assertNull( result2.get( 20, TimeUnit.SECONDS ) ); + assertNull(result2.get(20, TimeUnit.SECONDS)); - if ( firstResultFailed ) - { + if (firstResultFailed) { // tx with retries was successful and updated ids - assertEquals( 0, countNodesWithId( newNodeId1 ) ); - assertEquals( 2, countNodesWithId( newNodeId2 ) ); - } - else - { + assertEquals(0, countNodesWithId(newNodeId1)); + assertEquals(2, countNodesWithId(newNodeId2)); + } else { // tx without retries was successful and updated ids // tx with retries did not manage to find nodes because their ids were updated - assertEquals( 2, countNodesWithId( newNodeId1 ) ); - assertEquals( 0, countNodesWithId( newNodeId2 ) ); + assertEquals(2, countNodesWithId(newNodeId1)); + assertEquals(0, countNodesWithId(newNodeId2)); } // tx with retries was successful and created an additional node - assertEquals( 1, countNodesWithId( nodeId3 ) ); + assertEquals(1, countNodesWithId(nodeId3)); } @Test - void shouldExecuteTransactionWorkInCallerThread() - { + void shouldExecuteTransactionWorkInCallerThread() { int maxFailures = 3; Thread callerThread = Thread.currentThread(); - try ( Session session = neo4j.driver().session() ) - { - String result = session.readTransaction( new TransactionWork() - { + try (Session session = neo4j.driver().session()) { + String result = session.readTransaction(new TransactionWork() { int failures; @Override - public String execute( Transaction tx ) - { - assertSame( callerThread, Thread.currentThread() ); - if ( failures++ < maxFailures ) - { - throw new ServiceUnavailableException( "Oh no" ); + public String execute(Transaction tx) { + assertSame(callerThread, Thread.currentThread()); + if (failures++ < maxFailures) { + throw new ServiceUnavailableException("Oh no"); } return "Hello"; } - } ); + }); - assertEquals( "Hello", result ); + assertEquals("Hello", result); } } @Test - void shouldThrowRunFailureImmediatelyAndCloseSuccessfully() - { - try ( Session session = neo4j.driver().session() ) - { - ClientException e = assertThrows( ClientException.class, () -> session.run( "RETURN 10 / 0" ) ); + void shouldThrowRunFailureImmediatelyAndCloseSuccessfully() { + try (Session session = neo4j.driver().session()) { + ClientException e = assertThrows(ClientException.class, () -> session.run("RETURN 10 / 0")); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + assertThat(e.getMessage(), containsString("/ by zero")); } } - @EnabledOnNeo4jWith( BOLT_V4 ) + @EnabledOnNeo4jWith(BOLT_V4) @Test - void shouldNotPropagateFailureWhenStreamingIsCancelled() - { + void shouldNotPropagateFailureWhenStreamingIsCancelled() { Session session = neo4j.driver().session(); - session.run( "UNWIND range(20000, 0, -1) AS x RETURN 10 / x" ); + session.run("UNWIND range(20000, 0, -1) AS x RETURN 10 / x"); session.close(); } @Test - void shouldNotBePossibleToConsumeResultAfterSessionIsClosed() - { + void shouldNotBePossibleToConsumeResultAfterSessionIsClosed() { Result result; - try ( Session session = neo4j.driver().session() ) - { - result = session.run( "UNWIND range(1, 20000) AS x RETURN x" ); + try (Session session = neo4j.driver().session()) { + result = session.run("UNWIND range(1, 20000) AS x RETURN x"); } - assertThrows( ResultConsumedException.class, () -> result.list( record -> record.get( 0 ).asInt() ) ); + assertThrows( + ResultConsumedException.class, + () -> result.list(record -> record.get(0).asInt())); } @Test - void shouldThrowRunFailureImmediatelyAfterMultipleSuccessfulRunsAndCloseSuccessfully() - { - try ( Session session = neo4j.driver().session() ) - { - session.run( "CREATE ()" ); - session.run( "CREATE ()" ); - ClientException e = assertThrows( ClientException.class, () -> session.run( "RETURN 10 / 0" ) ); - - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + void shouldThrowRunFailureImmediatelyAfterMultipleSuccessfulRunsAndCloseSuccessfully() { + try (Session session = neo4j.driver().session()) { + session.run("CREATE ()"); + session.run("CREATE ()"); + ClientException e = assertThrows(ClientException.class, () -> session.run("RETURN 10 / 0")); + + assertThat(e.getMessage(), containsString("/ by zero")); } } @Test - void shouldThrowRunFailureImmediatelyAndAcceptSubsequentRun() - { - try ( Session session = neo4j.driver().session() ) - { - session.run( "CREATE ()" ); - session.run( "CREATE ()" ); - ClientException e = assertThrows( ClientException.class, () -> session.run( "RETURN 10 / 0" ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); - session.run( "CREATE ()" ); + void shouldThrowRunFailureImmediatelyAndAcceptSubsequentRun() { + try (Session session = neo4j.driver().session()) { + session.run("CREATE ()"); + session.run("CREATE ()"); + ClientException e = assertThrows(ClientException.class, () -> session.run("RETURN 10 / 0")); + assertThat(e.getMessage(), containsString("/ by zero")); + session.run("CREATE ()"); } } @Test - void shouldCloseCleanlyWhenRunErrorConsumed() - { + void shouldCloseCleanlyWhenRunErrorConsumed() { Session session = neo4j.driver().session(); - session.run( "CREATE ()" ); + session.run("CREATE ()"); - ClientException e = assertThrows( ClientException.class, () -> session.run( "RETURN 10 / 0" ).consume() ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + ClientException e = assertThrows( + ClientException.class, () -> session.run("RETURN 10 / 0").consume()); + assertThat(e.getMessage(), containsString("/ by zero")); - session.run( "CREATE ()" ); + session.run("CREATE ()"); session.close(); - assertFalse( session.isOpen() ); + assertFalse(session.isOpen()); } @Test - void shouldConsumePreviousResultBeforeRunningNewQuery() - { - try ( Session session = neo4j.driver().session() ) - { - session.run( "UNWIND range(1000, 0, -1) AS x RETURN 42 / x" ); - - ClientException e = assertThrows( ClientException.class, () -> session.run( "RETURN 1" ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + void shouldConsumePreviousResultBeforeRunningNewQuery() { + try (Session session = neo4j.driver().session()) { + session.run("UNWIND range(1000, 0, -1) AS x RETURN 42 / x"); + + ClientException e = assertThrows(ClientException.class, () -> session.run("RETURN 1")); + assertThat(e.getMessage(), containsString("/ by zero")); } } @Test - void shouldNotRetryOnConnectionAcquisitionTimeout() - { + void shouldNotRetryOnConnectionAcquisitionTimeout() { int maxPoolSize = 3; Config config = Config.builder() - .withMaxConnectionPoolSize( maxPoolSize ) - .withConnectionAcquisitionTimeout( 0, TimeUnit.SECONDS ) - .withMaxTransactionRetryTime( 42, TimeUnit.DAYS ) // retry for a really long time - .withEventLoopThreads( 1 ) + .withMaxConnectionPoolSize(maxPoolSize) + .withConnectionAcquisitionTimeout(0, TimeUnit.SECONDS) + .withMaxTransactionRetryTime(42, TimeUnit.DAYS) // retry for a really long time + .withEventLoopThreads(1) .build(); - driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), config ); + driver = GraphDatabase.driver(neo4j.uri(), neo4j.authToken(), config); - for ( int i = 0; i < maxPoolSize; i++ ) - { + for (int i = 0; i < maxPoolSize; i++) { driver.session().beginTransaction(); } AtomicInteger invocations = new AtomicInteger(); - ClientException e = assertThrows( ClientException.class, - () -> driver.session().writeTransaction( tx -> invocations.incrementAndGet() ) ); - assertThat( e, is( connectionAcquisitionTimeoutError( 0 ) ) ); + ClientException e = assertThrows( + ClientException.class, () -> driver.session().writeTransaction(tx -> invocations.incrementAndGet())); + assertThat(e, is(connectionAcquisitionTimeoutError(0))); // work should never be invoked - assertEquals( 0, invocations.get() ); + assertEquals(0, invocations.get()); } @Test - void shouldReportFailureInClose() - { + void shouldReportFailureInClose() { Session session = neo4j.driver().session(); - Result result = session.run( "CYPHER runtime=interpreted UNWIND [2, 4, 8, 0] AS x RETURN 32 / x" ); + Result result = session.run("CYPHER runtime=interpreted UNWIND [2, 4, 8, 0] AS x RETURN 32 / x"); - ClientException e = assertThrows( ClientException.class, session::close ); - assertThat( e, is( arithmeticError() ) ); + ClientException e = assertThrows(ClientException.class, session::close); + assertThat(e, is(arithmeticError())); } @Test - void shouldNotAllowAccessingRecordsAfterSummary() - { + void shouldNotAllowAccessingRecordsAfterSummary() { int recordCount = 10_000; String query = "UNWIND range(1, " + recordCount + ") AS x RETURN x"; - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( query ); + try (Session session = neo4j.driver().session()) { + Result result = session.run(query); ResultSummary summary = result.consume(); - assertEquals( query, summary.query().text() ); - assertEquals( QueryType.READ_ONLY, summary.queryType() ); + assertEquals(query, summary.query().text()); + assertEquals(QueryType.READ_ONLY, summary.queryType()); - assertThrows( ResultConsumedException.class, result::list ); + assertThrows(ResultConsumedException.class, result::list); } } @Test - void shouldNotAllowAccessingRecordsAfterSessionClosed() - { + void shouldNotAllowAccessingRecordsAfterSessionClosed() { int recordCount = 11_333; String query = "UNWIND range(1, " + recordCount + ") AS x RETURN 'Result-' + x"; Result result; - try ( Session session = neo4j.driver().session() ) - { - result = session.run( query ); + try (Session session = neo4j.driver().session()) { + result = session.run(query); } - assertThrows( ResultConsumedException.class, result::list ); + assertThrows(ResultConsumedException.class, result::list); } @Test - @DisabledOnNeo4jWith( BOLT_V4 ) - void shouldAllowToConsumeRecordsSlowlyAndCloseSession() throws InterruptedException - { + @DisabledOnNeo4jWith(BOLT_V4) + void shouldAllowToConsumeRecordsSlowlyAndCloseSession() throws InterruptedException { Session session = neo4j.driver().session(); - Result result = session.run( "UNWIND range(10000, 0, -1) AS x RETURN 10 / x" ); + Result result = session.run("UNWIND range(10000, 0, -1) AS x RETURN 10 / x"); // summary couple records slowly with a sleep in-between - for ( int i = 0; i < 10; i++ ) - { - assertTrue( result.hasNext() ); - assertNotNull( result.next() ); - Thread.sleep( 50 ); + for (int i = 0; i < 10; i++) { + assertTrue(result.hasNext()); + assertNotNull(result.next()); + Thread.sleep(50); } - ClientException e = assertThrows( ClientException.class, session::close ); - assertThat( e, is( arithmeticError() ) ); + ClientException e = assertThrows(ClientException.class, session::close); + assertThat(e, is(arithmeticError())); } @Test - void shouldAllowToConsumeRecordsSlowlyAndRetrieveSummary() throws InterruptedException - { - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "UNWIND range(8000, 1, -1) AS x RETURN 42 / x" ); + void shouldAllowToConsumeRecordsSlowlyAndRetrieveSummary() throws InterruptedException { + try (Session session = neo4j.driver().session()) { + Result result = session.run("UNWIND range(8000, 1, -1) AS x RETURN 42 / x"); // summary couple records slowly with a sleep in-between - for ( int i = 0; i < 12; i++ ) - { - assertTrue( result.hasNext() ); - assertNotNull( result.next() ); - Thread.sleep( 50 ); + for (int i = 0; i < 12; i++) { + assertTrue(result.hasNext()); + assertNotNull(result.next()); + Thread.sleep(50); } ResultSummary summary = result.consume(); - assertNotNull( summary ); + assertNotNull(summary); } } @Test - void shouldBeResponsiveToThreadInterruptWhenWaitingForResult() - { - try ( Session session1 = neo4j.driver().session(); - Session session2 = neo4j.driver().session() ) - { - session1.run( "CREATE (:Person {name: 'Beta Ray Bill'})" ).consume(); + void shouldBeResponsiveToThreadInterruptWhenWaitingForResult() { + try (Session session1 = neo4j.driver().session(); + Session session2 = neo4j.driver().session()) { + session1.run("CREATE (:Person {name: 'Beta Ray Bill'})").consume(); Transaction tx = session1.beginTransaction(); - tx.run( "MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Mjolnir'" ).consume(); + tx.run("MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Mjolnir'") + .consume(); // now 'Beta Ray Bill' node is locked // setup other thread to interrupt current thread when it blocks - TestUtil.interruptWhenInWaitingState( Thread.currentThread() ); - - try - { - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, - () -> session2.run( "MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Stormbreaker'" ).consume() ); - assertThat( e.getMessage(), containsString( "Connection to the database terminated" ) ); - assertThat( e.getMessage(), containsString( "Thread interrupted" ) ); - } - finally - { + TestUtil.interruptWhenInWaitingState(Thread.currentThread()); + + try { + ServiceUnavailableException e = assertThrows(ServiceUnavailableException.class, () -> session2.run( + "MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Stormbreaker'") + .consume()); + assertThat(e.getMessage(), containsString("Connection to the database terminated")); + assertThat(e.getMessage(), containsString("Thread interrupted")); + } finally { // clear interrupted flag Thread.interrupted(); } @@ -994,526 +881,472 @@ void shouldBeResponsiveToThreadInterruptWhenWaitingForResult() } @Test - void shouldAllowLongRunningQueryWithConnectTimeout() throws Exception - { + void shouldAllowLongRunningQueryWithConnectTimeout() throws Exception { int connectionTimeoutMs = 3_000; Config config = Config.builder() - .withLogging( DEV_NULL_LOGGING ) - .withConnectionTimeout( connectionTimeoutMs, TimeUnit.MILLISECONDS ) + .withLogging(DEV_NULL_LOGGING) + .withConnectionTimeout(connectionTimeoutMs, TimeUnit.MILLISECONDS) .build(); - try ( Driver driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), config ) ) - { + try (Driver driver = GraphDatabase.driver(neo4j.uri(), neo4j.authToken(), config)) { Session session1 = driver.session(); Session session2 = driver.session(); - session1.run( "CREATE (:Avenger {name: 'Hulk'})" ).consume(); + session1.run("CREATE (:Avenger {name: 'Hulk'})").consume(); Transaction tx = session1.beginTransaction(); - tx.run( "MATCH (a:Avenger {name: 'Hulk'}) SET a.power = 100 RETURN a" ).consume(); + tx.run("MATCH (a:Avenger {name: 'Hulk'}) SET a.power = 100 RETURN a") + .consume(); // Hulk node is now locked - CountDownLatch latch = new CountDownLatch( 1 ); - Future updateFuture = executeInDifferentThread( () -> - { + CountDownLatch latch = new CountDownLatch(1); + Future updateFuture = executeInDifferentThread(() -> { latch.countDown(); - return session2.run( "MATCH (a:Avenger {name: 'Hulk'}) SET a.weight = 1000 RETURN a.power" ) - .single().get( 0 ).asLong(); - } ); + return session2.run("MATCH (a:Avenger {name: 'Hulk'}) SET a.weight = 1000 RETURN a.power") + .single() + .get(0) + .asLong(); + }); latch.await(); // sleep more than connection timeout - Thread.sleep( connectionTimeoutMs + 1_000 ); + Thread.sleep(connectionTimeoutMs + 1_000); // verify that query is still executing and has not failed because of the read timeout - assertFalse( updateFuture.isDone() ); + assertFalse(updateFuture.isDone()); tx.commit(); - long hulkPower = updateFuture.get( 10, TimeUnit.SECONDS ); - assertEquals( 100, hulkPower ); + long hulkPower = updateFuture.get(10, TimeUnit.SECONDS); + assertEquals(100, hulkPower); } } @Test - void shouldAllowReturningNullFromTransactionFunction() - { - try ( Session session = neo4j.driver().session() ) - { - assertNull( session.readTransaction( tx -> null ) ); - assertNull( session.writeTransaction( tx -> null ) ); + void shouldAllowReturningNullFromTransactionFunction() { + try (Session session = neo4j.driver().session()) { + assertNull(session.readTransaction(tx -> null)); + assertNull(session.writeTransaction(tx -> null)); } } @Test - void shouldAllowIteratingOverEmptyResult() - { - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "UNWIND [] AS x RETURN x" ); - assertFalse( result.hasNext() ); - - assertThrows( NoSuchElementException.class, result::next ); + void shouldAllowIteratingOverEmptyResult() { + try (Session session = neo4j.driver().session()) { + Result result = session.run("UNWIND [] AS x RETURN x"); + assertFalse(result.hasNext()); + + assertThrows(NoSuchElementException.class, result::next); } } @Test - void shouldAllowConsumingEmptyResult() - { - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "UNWIND [] AS x RETURN x" ); + void shouldAllowConsumingEmptyResult() { + try (Session session = neo4j.driver().session()) { + Result result = session.run("UNWIND [] AS x RETURN x"); ResultSummary summary = result.consume(); - assertNotNull( summary ); - assertEquals( QueryType.READ_ONLY, summary.queryType() ); + assertNotNull(summary); + assertEquals(QueryType.READ_ONLY, summary.queryType()); } } @Test - void shouldAllowListEmptyResult() - { - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "UNWIND [] AS x RETURN x" ); - assertEquals( emptyList(), result.list() ); + void shouldAllowListEmptyResult() { + try (Session session = neo4j.driver().session()) { + Result result = session.run("UNWIND [] AS x RETURN x"); + assertEquals(emptyList(), result.list()); } } @Test - void shouldReportFailureInSummary() - { - try ( Session session = neo4j.driver().session() ) - { + void shouldReportFailureInSummary() { + try (Session session = neo4j.driver().session()) { String query = "UNWIND [1, 2, 3, 4, 0] AS x RETURN 10 / x"; - Result result = session.run( query ); + Result result = session.run(query); - ClientException e = assertThrows( ClientException.class, result::consume ); - assertThat( e, is( arithmeticError() ) ); + ClientException e = assertThrows(ClientException.class, result::consume); + assertThat(e, is(arithmeticError())); ResultSummary summary = result.consume(); - assertEquals( query, summary.query().text() ); + assertEquals(query, summary.query().text()); } } @Test - void shouldNotAllowStartingMultipleTransactions() - { - try ( Session session = neo4j.driver().session() ) - { + void shouldNotAllowStartingMultipleTransactions() { + try (Session session = neo4j.driver().session()) { Transaction tx = session.beginTransaction(); - assertNotNull( tx ); + assertNotNull(tx); - for ( int i = 0; i < 3; i++ ) - { - ClientException e = assertThrows( ClientException.class, session::beginTransaction ); - assertThat( e.getMessage(), - containsString( "You cannot begin a transaction on a session with an open transaction" ) ); + for (int i = 0; i < 3; i++) { + ClientException e = assertThrows(ClientException.class, session::beginTransaction); + assertThat( + e.getMessage(), + containsString("You cannot begin a transaction on a session with an open transaction")); } tx.close(); - assertNotNull( session.beginTransaction() ); + assertNotNull(session.beginTransaction()); } } @Test - void shouldCloseOpenTransactionWhenClosed() - { - try ( Session session = neo4j.driver().session() ) - { + void shouldCloseOpenTransactionWhenClosed() { + try (Session session = neo4j.driver().session()) { Transaction tx = session.beginTransaction(); - tx.run( "CREATE (:Node {id: 123})" ); - tx.run( "CREATE (:Node {id: 456})" ); + tx.run("CREATE (:Node {id: 123})"); + tx.run("CREATE (:Node {id: 456})"); tx.commit(); } - assertEquals( 1, countNodesWithId( 123 ) ); - assertEquals( 1, countNodesWithId( 456 ) ); + assertEquals(1, countNodesWithId(123)); + assertEquals(1, countNodesWithId(456)); } @Test - void shouldRollbackOpenTransactionWhenClosed() - { - try ( Session session = neo4j.driver().session() ) - { + void shouldRollbackOpenTransactionWhenClosed() { + try (Session session = neo4j.driver().session()) { Transaction tx = session.beginTransaction(); - tx.run( "CREATE (:Node {id: 123})" ); - tx.run( "CREATE (:Node {id: 456})" ); + tx.run("CREATE (:Node {id: 123})"); + tx.run("CREATE (:Node {id: 456})"); tx.rollback(); } - assertEquals( 0, countNodesWithId( 123 ) ); - assertEquals( 0, countNodesWithId( 456 ) ); + assertEquals(0, countNodesWithId(123)); + assertEquals(0, countNodesWithId(456)); } @Test - void shouldSupportNestedQueries() - { - try ( Session session = neo4j.driver().session() ) - { + void shouldSupportNestedQueries() { + try (Session session = neo4j.driver().session()) { // populate db with test data - session.run( "UNWIND range(1, 100) AS x CREATE (:Property {id: x})" ).consume(); - session.run( "UNWIND range(1, 10) AS x CREATE (:Resource {id: x})" ).consume(); + session.run("UNWIND range(1, 100) AS x CREATE (:Property {id: x})").consume(); + session.run("UNWIND range(1, 10) AS x CREATE (:Resource {id: x})").consume(); int seenProperties = 0; int seenResources = 0; // read properties and resources using a single session - Result properties = session.run( "MATCH (p:Property) RETURN p" ); - while ( properties.hasNext() ) - { - assertNotNull( properties.next() ); + Result properties = session.run("MATCH (p:Property) RETURN p"); + while (properties.hasNext()) { + assertNotNull(properties.next()); seenProperties++; - Result resources = session.run( "MATCH (r:Resource) RETURN r" ); - while ( resources.hasNext() ) - { - assertNotNull( resources.next() ); + Result resources = session.run("MATCH (r:Resource) RETURN r"); + while (resources.hasNext()) { + assertNotNull(resources.next()); seenResources++; } } - assertEquals( 100, seenProperties ); - assertEquals( 1000, seenResources ); + assertEquals(100, seenProperties); + assertEquals(1000, seenResources); } } @Test - @DisabledOnNeo4jWith( BOLT_V4 ) - void shouldErrorWhenTryingToUseRxAPIWithoutBoltV4() throws Throwable - { + @DisabledOnNeo4jWith(BOLT_V4) + void shouldErrorWhenTryingToUseRxAPIWithoutBoltV4() throws Throwable { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "RETURN 1" ); + RxResult result = session.run("RETURN 1"); // When trying to run the query on a server that is using a protocol that is lower than V4 - StepVerifier.create( result.records() ).expectErrorSatisfies( error -> { - // Then - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), containsString( "Driver is connected to the database that does not support driver reactive API" ) ); - } ).verify(); + StepVerifier.create(result.records()) + .expectErrorSatisfies(error -> { + // Then + assertThat(error, instanceOf(ClientException.class)); + assertThat( + error.getMessage(), + containsString( + "Driver is connected to the database that does not support driver reactive API")); + }) + .verify(); } @Test - @DisabledOnNeo4jWith( BOLT_V4 ) - void shouldErrorWhenTryingToUseDatabaseNameWithoutBoltV4() throws Throwable - { + @DisabledOnNeo4jWith(BOLT_V4) + void shouldErrorWhenTryingToUseDatabaseNameWithoutBoltV4() throws Throwable { // Given - Session session = neo4j.driver().session( forDatabase( "foo" ) ); + Session session = neo4j.driver().session(forDatabase("foo")); // When trying to run the query on a server that is using a protocol that is lower than V4 - ClientException error = assertThrows( ClientException.class, () -> session.run( "RETURN 1" ) ); - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), containsString( "Database name parameter for selecting database is not supported" ) ); + ClientException error = assertThrows(ClientException.class, () -> session.run("RETURN 1")); + assertThat(error, instanceOf(ClientException.class)); + assertThat( + error.getMessage(), containsString("Database name parameter for selecting database is not supported")); } @Test - @DisabledOnNeo4jWith( BOLT_V4 ) - void shouldErrorWhenTryingToUseDatabaseNameWithoutBoltV4UsingTx() throws Throwable - { + @DisabledOnNeo4jWith(BOLT_V4) + void shouldErrorWhenTryingToUseDatabaseNameWithoutBoltV4UsingTx() throws Throwable { // Given - Session session = neo4j.driver().session( forDatabase( "foo" ) ); + Session session = neo4j.driver().session(forDatabase("foo")); // When trying to run the query on a server that is using a protocol that is lower than V4 - ClientException error = assertThrows( ClientException.class, session::beginTransaction ); - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), containsString( "Database name parameter for selecting database is not supported" ) ); + ClientException error = assertThrows(ClientException.class, session::beginTransaction); + assertThat(error, instanceOf(ClientException.class)); + assertThat( + error.getMessage(), containsString("Database name parameter for selecting database is not supported")); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void shouldAllowDatabaseName() throws Throwable - { + @EnabledOnNeo4jWith(BOLT_V4) + void shouldAllowDatabaseName() throws Throwable { // Given - try( Session session = neo4j.driver().session( forDatabase( "neo4j" ) ) ) - { - Result result = session.run( "RETURN 1" ); - assertThat( result.single().get( 0 ).asInt(), equalTo( 1 ) ); + try (Session session = neo4j.driver().session(forDatabase("neo4j"))) { + Result result = session.run("RETURN 1"); + assertThat(result.single().get(0).asInt(), equalTo(1)); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void shouldAllowDatabaseNameUsingTx() throws Throwable - { - try ( Session session = neo4j.driver().session( forDatabase( "neo4j" ) ); - Transaction transaction = session.beginTransaction() ) - { - Result result = transaction.run( "RETURN 1" ); - assertThat( result.single().get( 0 ).asInt(), equalTo( 1 ) ); + @EnabledOnNeo4jWith(BOLT_V4) + void shouldAllowDatabaseNameUsingTx() throws Throwable { + try (Session session = neo4j.driver().session(forDatabase("neo4j")); + Transaction transaction = session.beginTransaction()) { + Result result = transaction.run("RETURN 1"); + assertThat(result.single().get(0).asInt(), equalTo(1)); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void shouldAllowDatabaseNameUsingTxWithRetries() throws Throwable - { - try ( Session session = neo4j.driver().session( forDatabase( "neo4j" ) ) ) - { - int num = session.readTransaction( tx -> tx.run( "RETURN 1" ).single().get( 0 ).asInt() ); - assertThat( num, equalTo( 1 ) ); + @EnabledOnNeo4jWith(BOLT_V4) + void shouldAllowDatabaseNameUsingTxWithRetries() throws Throwable { + try (Session session = neo4j.driver().session(forDatabase("neo4j"))) { + int num = session.readTransaction( + tx -> tx.run("RETURN 1").single().get(0).asInt()); + assertThat(num, equalTo(1)); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void shouldErrorDatabaseWhenDatabaseIsAbsent() throws Throwable - { - Session session = neo4j.driver().session( forDatabase( "foo" ) ); + @EnabledOnNeo4jWith(BOLT_V4) + void shouldErrorDatabaseWhenDatabaseIsAbsent() throws Throwable { + Session session = neo4j.driver().session(forDatabase("foo")); - ClientException error = assertThrows( ClientException.class, () -> { - Result result = session.run( "RETURN 1" ); + ClientException error = assertThrows(ClientException.class, () -> { + Result result = session.run("RETURN 1"); result.consume(); - } ); + }); - assertThat( error.getMessage(), containsString( "Database does not exist. Database name: 'foo'" ) ); + assertThat(error.getMessage(), containsString("Database does not exist. Database name: 'foo'")); session.close(); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void shouldErrorDatabaseNameUsingTxWhenDatabaseIsAbsent() throws Throwable - { + @EnabledOnNeo4jWith(BOLT_V4) + void shouldErrorDatabaseNameUsingTxWhenDatabaseIsAbsent() throws Throwable { // Given - Session session = neo4j.driver().session( forDatabase( "foo" ) ); + Session session = neo4j.driver().session(forDatabase("foo")); // When trying to run the query on a server that is using a protocol that is lower than V4 - ClientException error = assertThrows( ClientException.class, () -> { + ClientException error = assertThrows(ClientException.class, () -> { Transaction transaction = session.beginTransaction(); - Result result = transaction.run( "RETURN 1" ); + Result result = transaction.run("RETURN 1"); result.consume(); }); - assertThat( error.getMessage(), containsString( "Database does not exist. Database name: 'foo'" ) ); + assertThat(error.getMessage(), containsString("Database does not exist. Database name: 'foo'")); session.close(); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void shouldErrorDatabaseNameUsingTxWithRetriesWhenDatabaseIsAbsent() throws Throwable - { + @EnabledOnNeo4jWith(BOLT_V4) + void shouldErrorDatabaseNameUsingTxWithRetriesWhenDatabaseIsAbsent() throws Throwable { // Given - Session session = neo4j.driver().session( forDatabase( "foo" ) ); + Session session = neo4j.driver().session(forDatabase("foo")); // When trying to run the query on a database that does not exist - ClientException error = assertThrows( ClientException.class, () -> { - session.readTransaction( tx -> tx.run( "RETURN 1" ).consume() ); + ClientException error = assertThrows(ClientException.class, () -> { + session.readTransaction(tx -> tx.run("RETURN 1").consume()); }); - assertThat( error.getMessage(), containsString( "Database does not exist. Database name: 'foo'" ) ); + assertThat(error.getMessage(), containsString("Database does not exist. Database name: 'foo'")); session.close(); } - private void testExecuteReadTx( AccessMode sessionMode ) - { + private void testExecuteReadTx(AccessMode sessionMode) { Driver driver = neo4j.driver(); // write some test data - try ( Session session = driver.session() ) - { - session.run( "CREATE (:Person {name: 'Tony Stark'})" ); - session.run( "CREATE (:Person {name: 'Steve Rogers'})" ); + try (Session session = driver.session()) { + session.run("CREATE (:Person {name: 'Tony Stark'})"); + session.run("CREATE (:Person {name: 'Steve Rogers'})"); } // read previously committed data - try ( Session session = driver.session( builder().withDefaultAccessMode( sessionMode ).build() ) ) - { - Set names = session.readTransaction( tx -> - { - List records = tx.run( "MATCH (p:Person) RETURN p.name AS name" ).list(); - Set names1 = new HashSet<>( records.size() ); - for ( Record record : records ) - { - names1.add( record.get( "name" ).asString() ); + try (Session session = + driver.session(builder().withDefaultAccessMode(sessionMode).build())) { + Set names = session.readTransaction(tx -> { + List records = + tx.run("MATCH (p:Person) RETURN p.name AS name").list(); + Set names1 = new HashSet<>(records.size()); + for (Record record : records) { + names1.add(record.get("name").asString()); } return names1; - } ); + }); - assertThat( names, containsInAnyOrder( "Tony Stark", "Steve Rogers" ) ); + assertThat(names, containsInAnyOrder("Tony Stark", "Steve Rogers")); } } - private void testExecuteWriteTx( AccessMode sessionMode ) - { + private void testExecuteWriteTx(AccessMode sessionMode) { Driver driver = neo4j.driver(); // write some test data - try ( Session session = driver.session( builder().withDefaultAccessMode( sessionMode ).build() ) ) - { - String material = session.writeTransaction( tx -> - { - Result result = tx.run( "CREATE (s:Shield {material: 'Vibranium'}) RETURN s" ); + try (Session session = + driver.session(builder().withDefaultAccessMode(sessionMode).build())) { + String material = session.writeTransaction(tx -> { + Result result = tx.run("CREATE (s:Shield {material: 'Vibranium'}) RETURN s"); Record record = result.single(); tx.commit(); - return record.get( 0 ).asNode().get( "material" ).asString(); - } ); + return record.get(0).asNode().get("material").asString(); + }); - assertEquals( "Vibranium", material ); + assertEquals("Vibranium", material); } // read previously committed data - try ( Session session = driver.session() ) - { - Record record = session.run( "MATCH (s:Shield) RETURN s.material" ).single(); - assertEquals( "Vibranium", record.get( 0 ).asString() ); + try (Session session = driver.session()) { + Record record = session.run("MATCH (s:Shield) RETURN s.material").single(); + assertEquals("Vibranium", record.get(0).asString()); } } - private void testTxRollbackWhenFunctionThrows( AccessMode sessionMode ) - { + private void testTxRollbackWhenFunctionThrows(AccessMode sessionMode) { Driver driver = neo4j.driver(); - try ( Session session = driver.session( builder().withDefaultAccessMode( sessionMode ).build() ) ) - { - assertThrows( ClientException.class, () -> - session.writeTransaction( tx -> - { - tx.run( "CREATE (:Person {name: 'Thanos'})" ); + try (Session session = + driver.session(builder().withDefaultAccessMode(sessionMode).build())) { + assertThrows( + ClientException.class, + () -> session.writeTransaction(tx -> { + tx.run("CREATE (:Person {name: 'Thanos'})"); // trigger division by zero error: - tx.run( "UNWIND range(0, 1) AS i RETURN 10/i" ); + tx.run("UNWIND range(0, 1) AS i RETURN 10/i"); tx.commit(); return null; - } ) ); + })); } // no data should have been committed - try ( Session session = driver.session() ) - { - Record record = session.run( "MATCH (p:Person {name: 'Thanos'}) RETURN count(p)" ).single(); - assertEquals( 0, record.get( 0 ).asInt() ); + try (Session session = driver.session()) { + Record record = session.run("MATCH (p:Person {name: 'Thanos'}) RETURN count(p)") + .single(); + assertEquals(0, record.get(0).asInt()); } - } - private Driver newDriverWithoutRetries() - { - return newDriverWithFixedRetries( 0 ); + private Driver newDriverWithoutRetries() { + return newDriverWithFixedRetries(0); } - private Driver newDriverWithFixedRetries( int maxRetriesCount ) - { - DriverFactory driverFactory = new DriverFactoryWithFixedRetryLogic( maxRetriesCount ); + private Driver newDriverWithFixedRetries(int maxRetriesCount) { + DriverFactory driverFactory = new DriverFactoryWithFixedRetryLogic(maxRetriesCount); AuthToken auth = DEFAULT_AUTH_TOKEN; - return driverFactory.newInstance( neo4j.uri(), auth, RoutingSettings.DEFAULT, RetrySettings.DEFAULT, noLoggingConfig(), SecurityPlanImpl.insecure() ); + return driverFactory.newInstance( + neo4j.uri(), + auth, + RoutingSettings.DEFAULT, + RetrySettings.DEFAULT, + noLoggingConfig(), + SecurityPlanImpl.insecure()); } - private Driver newDriverWithLimitedRetries( int maxTxRetryTime, TimeUnit unit ) - { + private Driver newDriverWithLimitedRetries(int maxTxRetryTime, TimeUnit unit) { Config config = Config.builder() - .withLogging( DEV_NULL_LOGGING ) - .withMaxTransactionRetryTime( maxTxRetryTime, unit ) + .withLogging(DEV_NULL_LOGGING) + .withMaxTransactionRetryTime(maxTxRetryTime, unit) .build(); - return GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), config ); + return GraphDatabase.driver(neo4j.uri(), neo4j.authToken(), config); } - private static Config noLoggingConfig() - { - return Config.builder().withLogging( DEV_NULL_LOGGING ).build(); + private static Config noLoggingConfig() { + return Config.builder().withLogging(DEV_NULL_LOGGING).build(); } - private static ThrowingWork newThrowingWorkSpy( String query, int failures ) - { - return spy( new ThrowingWork( query, failures ) ); + private static ThrowingWork newThrowingWorkSpy(String query, int failures) { + return spy(new ThrowingWork(query, failures)); } - private int countNodesWithId( int id ) - { - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "MATCH (n {id: $id}) RETURN count(n)", parameters( "id", id ) ); - return result.single().get( 0 ).asInt(); + private int countNodesWithId(int id) { + try (Session session = neo4j.driver().session()) { + Result result = session.run("MATCH (n {id: $id}) RETURN count(n)", parameters("id", id)); + return result.single().get(0).asInt(); } } - private void createNodeWithId( int id ) - { - try ( Session session = neo4j.driver().session() ) - { - session.run( "CREATE (n {id: $id})", parameters( "id", id ) ); + private void createNodeWithId(int id) { + try (Session session = neo4j.driver().session()) { + session.run("CREATE (n {id: $id})", parameters("id", id)); } } - private static Result updateNodeId(QueryRunner queryRunner, int currentId, int newId ) - { - return queryRunner.run( "MATCH (n {id: $currentId}) SET n.id = $newId", - parameters( "currentId", currentId, "newId", newId ) ); + private static Result updateNodeId(QueryRunner queryRunner, int currentId, int newId) { + return queryRunner.run( + "MATCH (n {id: $currentId}) SET n.id = $newId", parameters("currentId", currentId, "newId", newId)); } - private static boolean assertOneOfTwoFuturesFailWithDeadlock( Future future1, Future future2 ) - throws Exception - { + private static boolean assertOneOfTwoFuturesFailWithDeadlock(Future future1, Future future2) + throws Exception { boolean firstFailed = false; - try - { - assertNull( future1.get( 20, TimeUnit.SECONDS ) ); - } - catch ( ExecutionException e ) - { - assertDeadlockDetectedError( e ); + try { + assertNull(future1.get(20, TimeUnit.SECONDS)); + } catch (ExecutionException e) { + assertDeadlockDetectedError(e); firstFailed = true; } - try - { - assertNull( future2.get( 20, TimeUnit.SECONDS ) ); - } - catch ( ExecutionException e ) - { - assertFalse( firstFailed, "Both futures failed" ); - assertDeadlockDetectedError( e ); + try { + assertNull(future2.get(20, TimeUnit.SECONDS)); + } catch (ExecutionException e) { + assertFalse(firstFailed, "Both futures failed"); + assertDeadlockDetectedError(e); } return firstFailed; } - private static void assertDeadlockDetectedError( ExecutionException e ) - { - assertThat( e.getCause(), instanceOf( TransientException.class ) ); + private static void assertDeadlockDetectedError(ExecutionException e) { + assertThat(e.getCause(), instanceOf(TransientException.class)); String errorCode = ((TransientException) e.getCause()).code(); - assertEquals( "Neo.TransientError.Transaction.DeadlockDetected", errorCode ); + assertEquals("Neo.TransientError.Transaction.DeadlockDetected", errorCode); } - private Future executeInDifferentThread( Callable callable ) - { - if ( executor == null ) - { - executor = Executors.newCachedThreadPool( daemon( getClass().getSimpleName() + "-thread-" ) ); + private Future executeInDifferentThread(Callable callable) { + if (executor == null) { + executor = Executors.newCachedThreadPool(daemon(getClass().getSimpleName() + "-thread-")); } - return executor.submit( callable ); + return executor.submit(callable); } - private static void await( CountDownLatch latch ) - { - try - { + private static void await(CountDownLatch latch) { + try { latch.await(); - } - catch ( InterruptedException e ) - { + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException( e ); + throw new RuntimeException(e); } } - private static class ThrowingWork implements TransactionWork - { + private static class ThrowingWork implements TransactionWork { final String query; final int failures; int invoked; - ThrowingWork( String query, int failures ) - { + ThrowingWork(String query, int failures) { this.query = query; this.failures = failures; } @Override - public Record execute( Transaction tx ) - { - Result result = tx.run( query ); - if ( invoked++ < failures ) - { - throw new ServiceUnavailableException( "" ); + public Record execute(Transaction tx) { + Result result = tx.run(query); + if (invoked++ < failures) { + throw new ServiceUnavailableException(""); } Record single = result.single(); tx.commit(); diff --git a/driver/src/test/java/org/neo4j/driver/integration/SessionMixIT.java b/driver/src/test/java/org/neo4j/driver/integration/SessionMixIT.java index 2f60cce11c..761d9911d9 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/SessionMixIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/SessionMixIT.java @@ -18,19 +18,27 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.util.Matchers.blockingOperationInEventLoopError; +import static org.neo4j.driver.util.TestUtil.await; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - -import org.neo4j.driver.Record; -import org.neo4j.driver.Session; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Query; +import org.neo4j.driver.Record; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.AsyncTransaction; @@ -42,19 +50,8 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.util.Matchers.blockingOperationInEventLoopError; -import static org.neo4j.driver.util.TestUtil.await; - @ParallelizableIT -class SessionMixIT -{ +class SessionMixIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @@ -62,175 +59,166 @@ class SessionMixIT private Session session; @BeforeEach - void setUp() - { + void setUp() { asyncSession = newAsyncSession(); session = newSession(); } @AfterEach - void tearDown() - { - await( asyncSession.closeAsync() ); + void tearDown() { + await(asyncSession.closeAsync()); session.close(); } - private AsyncSession newAsyncSession() - { + private AsyncSession newAsyncSession() { return neo4j.driver().asyncSession(); } - private Session newSession() - { + private Session newSession() { return neo4j.driver().session(); } @Test - void shouldFailToExecuteBlockingRunChainedWithAsyncTransaction() - { - CompletionStage result = asyncSession.beginTransactionAsync( TransactionConfig.empty() ) - .thenApply( tx -> - { - if ( EventLoopGroupFactory.isEventLoopThread( Thread.currentThread() ) ) - { - IllegalStateException e = assertThrows( IllegalStateException.class, () -> session.run( "CREATE ()" ) ); - assertThat( e, is( blockingOperationInEventLoopError() ) ); + void shouldFailToExecuteBlockingRunChainedWithAsyncTransaction() { + CompletionStage result = asyncSession + .beginTransactionAsync(TransactionConfig.empty()) + .thenApply(tx -> { + if (EventLoopGroupFactory.isEventLoopThread(Thread.currentThread())) { + IllegalStateException e = + assertThrows(IllegalStateException.class, () -> session.run("CREATE ()")); + assertThat(e, is(blockingOperationInEventLoopError())); } return null; - } ); + }); - assertNull( await( result ) ); + assertNull(await(result)); } @Test - void shouldAllowUsingBlockingApiInCommonPoolWhenChaining() - { - CompletionStage txStage = asyncSession.beginTransactionAsync() + void shouldAllowUsingBlockingApiInCommonPoolWhenChaining() { + CompletionStage txStage = asyncSession + .beginTransactionAsync() // move execution to ForkJoinPool.commonPool() - .thenApplyAsync( tx -> - { - session.run( "UNWIND [1,1,2] AS x CREATE (:Node {id: x})" ).consume(); - session.run( "CREATE (:Node {id: 42})" ).consume(); + .thenApplyAsync(tx -> { + session.run("UNWIND [1,1,2] AS x CREATE (:Node {id: x})").consume(); + session.run("CREATE (:Node {id: 42})").consume(); tx.commitAsync(); return tx; - } ); + }); - await( txStage ); + await(txStage); - assertEquals( 2, countNodes( 1 ) ); - assertEquals( 1, countNodes( 2 ) ); - assertEquals( 1, countNodes( 42 ) ); + assertEquals(2, countNodes(1)); + assertEquals(1, countNodes(2)); + assertEquals(1, countNodes(42)); } - @Test - void shouldFailToExecuteBlockingRunInAsyncTransactionFunction() - { + void shouldFailToExecuteBlockingRunInAsyncTransactionFunction() { AsyncTransactionWork> completionStageTransactionWork = tx -> { - if ( EventLoopGroupFactory.isEventLoopThread( Thread.currentThread() ) ) - { - IllegalStateException e = assertThrows( IllegalStateException.class, - () -> session.run( "UNWIND range(1, 10000) AS x CREATE (n:AsyncNode {x: x}) RETURN n" ) ); + if (EventLoopGroupFactory.isEventLoopThread(Thread.currentThread())) { + IllegalStateException e = assertThrows( + IllegalStateException.class, + () -> session.run("UNWIND range(1, 10000) AS x CREATE (n:AsyncNode {x: x}) RETURN n")); - assertThat( e, is( blockingOperationInEventLoopError() ) ); + assertThat(e, is(blockingOperationInEventLoopError())); } - return completedFuture( null ); + return completedFuture(null); }; - CompletionStage result = asyncSession.readTransactionAsync( completionStageTransactionWork ); - assertNull( await( result ) ); + CompletionStage result = asyncSession.readTransactionAsync(completionStageTransactionWork); + assertNull(await(result)); } @Test - void shouldFailToExecuteBlockingRunChainedWithAsyncRun() - { - CompletionStage result = asyncSession.runAsync( "RETURN 1" ).thenCompose( ResultCursor::singleAsync ).thenApply(record -> { - if ( EventLoopGroupFactory.isEventLoopThread( Thread.currentThread() ) ) - { - IllegalStateException e = - assertThrows( IllegalStateException.class, () -> session.run( "RETURN $x", parameters( "x", record.get( 0 ).asInt() ) ) ); - - assertThat( e, is( blockingOperationInEventLoopError() ) ); - } - return null; - } ); + void shouldFailToExecuteBlockingRunChainedWithAsyncRun() { + CompletionStage result = asyncSession + .runAsync("RETURN 1") + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> { + if (EventLoopGroupFactory.isEventLoopThread(Thread.currentThread())) { + IllegalStateException e = assertThrows( + IllegalStateException.class, + () -> session.run( + "RETURN $x", + parameters("x", record.get(0).asInt()))); + + assertThat(e, is(blockingOperationInEventLoopError())); + } + return null; + }); - assertNull( await( result ) ); + assertNull(await(result)); } @Test - void shouldAllowBlockingOperationInCommonPoolWhenChaining() - { - CompletionStage nodeStage = asyncSession.runAsync( "RETURN 42 AS value" ).thenCompose( ResultCursor::singleAsync ) + void shouldAllowBlockingOperationInCommonPoolWhenChaining() { + CompletionStage nodeStage = asyncSession + .runAsync("RETURN 42 AS value") + .thenCompose(ResultCursor::singleAsync) // move execution to ForkJoinPool.commonPool() - .thenApplyAsync( record -> session.run( "CREATE (n:Node {value: $value}) RETURN n", record ) ) - .thenApply( Result::single ) - .thenApply( record -> record.get( 0 ).asNode() ); + .thenApplyAsync(record -> session.run("CREATE (n:Node {value: $value}) RETURN n", record)) + .thenApply(Result::single) + .thenApply(record -> record.get(0).asNode()); - Node node = await( nodeStage ); + Node node = await(nodeStage); - assertEquals( 42, node.get( "value" ).asInt() ); - assertEquals( 1, countNodesByLabel( "Node" ) ); + assertEquals(42, node.get("value").asInt()); + assertEquals(1, countNodesByLabel("Node")); } - private void runNestedQueries(ResultCursor inputCursor, List> stages, - CompletableFuture>> resultFuture ) - { + private void runNestedQueries( + ResultCursor inputCursor, + List> stages, + CompletableFuture>> resultFuture) { final CompletionStage recordResponse = inputCursor.nextAsync(); - stages.add( recordResponse ); - - recordResponse.whenComplete( ( record, error ) -> { - if ( error != null ) - { - resultFuture.completeExceptionally( error ); - } - else if ( record != null ) - { - runNestedQuery( inputCursor, record, stages, resultFuture ); + stages.add(recordResponse); + + recordResponse.whenComplete((record, error) -> { + if (error != null) { + resultFuture.completeExceptionally(error); + } else if (record != null) { + runNestedQuery(inputCursor, record, stages, resultFuture); + } else { + resultFuture.complete(stages); } - else - { - resultFuture.complete( stages ); - } - } ); + }); } - private void runNestedQuery(ResultCursor inputCursor, Record record, List> stages, - CompletableFuture>> resultFuture ) - { - Node node = record.get( 0 ).asNode(); - long id = node.get( "id" ).asLong(); + private void runNestedQuery( + ResultCursor inputCursor, + Record record, + List> stages, + CompletableFuture>> resultFuture) { + Node node = record.get(0).asNode(); + long id = node.get("id").asLong(); long age = id * 10; - CompletionStage response = - asyncSession.runAsync( "MATCH (p:Person {id: $id}) SET p.age = $age RETURN p", parameters( "id", id, "age", age ) ); + CompletionStage response = asyncSession.runAsync( + "MATCH (p:Person {id: $id}) SET p.age = $age RETURN p", parameters("id", id, "age", age)); - response.whenComplete( ( cursor, error ) -> { - if ( error != null ) - { - resultFuture.completeExceptionally( Futures.completionExceptionCause( error ) ); - } - else - { - stages.add( cursor.nextAsync() ); - runNestedQueries( inputCursor, stages, resultFuture ); + response.whenComplete((cursor, error) -> { + if (error != null) { + resultFuture.completeExceptionally(Futures.completionExceptionCause(error)); + } else { + stages.add(cursor.nextAsync()); + runNestedQueries(inputCursor, stages, resultFuture); } - } ); + }); } - private long countNodesByLabel( String label ) - { - CompletionStage countStage = - asyncSession.runAsync( "MATCH (n:" + label + ") RETURN count(n)" ).thenCompose( ResultCursor::singleAsync ).thenApply( - record -> record.get( 0 ).asLong() ); + private long countNodesByLabel(String label) { + CompletionStage countStage = asyncSession + .runAsync("MATCH (n:" + label + ") RETURN count(n)") + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> record.get(0).asLong()); - return await( countStage ); + return await(countStage); } - private int countNodes( Object id ) - { - Query query = new Query( "MATCH (n:Node {id: $id}) RETURN count(n)", parameters( "id", id ) ); + private int countNodes(Object id) { + Query query = new Query("MATCH (n:Node {id: $id}) RETURN count(n)", parameters("id", id)); Record record = session.run(query).single(); - return record.get( 0 ).asInt(); + return record.get(0).asInt(); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/SessionResetIT.java b/driver/src/test/java/org/neo4j/driver/integration/SessionResetIT.java index 2c30159185..14e4f63e85 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/SessionResetIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/SessionResetIT.java @@ -18,12 +18,33 @@ */ package org.neo4j.driver.integration; -import org.hamcrest.CoreMatchers; -import org.hamcrest.MatcherAssert; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Collections.newSetFromMap; +import static java.util.concurrent.CompletableFuture.runAsync; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; +import static java.util.stream.IntStream.range; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.util.DaemonThreadFactory.daemon; +import static org.neo4j.driver.util.Neo4jRunner.HOME_DIR; +import static org.neo4j.driver.util.Neo4jSettings.IMPORT_DIR; +import static org.neo4j.driver.util.Neo4jSettings.TEST_SETTINGS; +import static org.neo4j.driver.util.TestUtil.activeQueryCount; +import static org.neo4j.driver.util.TestUtil.activeQueryNames; +import static org.neo4j.driver.util.TestUtil.await; +import static org.neo4j.driver.util.TestUtil.awaitAllFutures; +import static org.neo4j.driver.util.TestUtil.awaitCondition; import java.io.IOException; import java.io.UncheckedIOException; @@ -49,7 +70,12 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; - +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Driver; import org.neo4j.driver.QueryRunner; import org.neo4j.driver.Result; @@ -62,52 +88,22 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.util.Collections.newSetFromMap; -import static java.util.concurrent.CompletableFuture.runAsync; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.MINUTES; -import static java.util.concurrent.TimeUnit.SECONDS; -import static java.util.stream.IntStream.range; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.lessThanOrEqualTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.util.DaemonThreadFactory.daemon; -import static org.neo4j.driver.util.Neo4jRunner.HOME_DIR; -import static org.neo4j.driver.util.Neo4jSettings.IMPORT_DIR; -import static org.neo4j.driver.util.Neo4jSettings.TEST_SETTINGS; -import static org.neo4j.driver.util.TestUtil.activeQueryCount; -import static org.neo4j.driver.util.TestUtil.activeQueryNames; -import static org.neo4j.driver.util.TestUtil.await; -import static org.neo4j.driver.util.TestUtil.awaitAllFutures; -import static org.neo4j.driver.util.TestUtil.awaitCondition; - -@SuppressWarnings( "deprecation" ) +@SuppressWarnings("deprecation") @ParallelizableIT -class SessionResetIT -{ +class SessionResetIT { private static final int CSV_FILE_SIZE = 10_000; private static final int LOAD_CSV_BATCH_SIZE = 10; private static final String SHORT_QUERY_1 = "CREATE (n:Node {name: 'foo', occupation: 'bar'})"; private static final String SHORT_QUERY_2 = "MATCH (n:Node {name: 'foo'}) RETURN count(n)"; private static final String LONG_QUERY = "UNWIND range(0, 10000000) AS i CREATE (n:Node {idx: i}) DELETE n"; - private static final String LONG_PERIODIC_COMMIT_QUERY_TEMPLATE = - "USING PERIODIC COMMIT 1 " + - "LOAD CSV FROM '%s' AS line " + - "UNWIND range(1, " + LOAD_CSV_BATCH_SIZE + ") AS index " + - "CREATE (n:Node {id: index, name: line[0], occupation: line[1]})"; + private static final String LONG_PERIODIC_COMMIT_QUERY_TEMPLATE = "USING PERIODIC COMMIT 1 " + + "LOAD CSV FROM '%s' AS line " + + "UNWIND range(1, " + + LOAD_CSV_BATCH_SIZE + ") AS index " + "CREATE (n:Node {id: index, name: line[0], occupation: line[1]})"; private static final int STRESS_TEST_THREAD_COUNT = Runtime.getRuntime().availableProcessors() * 2; - private static final long STRESS_TEST_DURATION_MS = SECONDS.toMillis( 5 ); + private static final long STRESS_TEST_DURATION_MS = SECONDS.toMillis(5); private static final String[] STRESS_TEST_QUERIES = {SHORT_QUERY_1, SHORT_QUERY_2, LONG_QUERY}; @RegisterExtension @@ -116,30 +112,25 @@ class SessionResetIT private ExecutorService executor; @BeforeEach - void setUp() - { - executor = Executors.newCachedThreadPool( daemon( getClass().getSimpleName() + "-thread" ) ); + void setUp() { + executor = Executors.newCachedThreadPool(daemon(getClass().getSimpleName() + "-thread")); } @AfterEach - void tearDown() - { - if ( executor != null ) - { + void tearDown() { + if (executor != null) { executor.shutdownNow(); } } @Test - void shouldTerminateAutoCommitQuery() - { - testQueryTermination( LONG_QUERY, true ); + void shouldTerminateAutoCommitQuery() { + testQueryTermination(LONG_QUERY, true); } @Test - void shouldTerminateQueryInUnmanagedTransaction() - { - testQueryTermination( LONG_QUERY, false ); + void shouldTerminateQueryInUnmanagedTransaction() { + testQueryTermination(LONG_QUERY, false); } /** @@ -148,217 +139,190 @@ void shouldTerminateQueryInUnmanagedTransaction() * For a user who want to terminate a periodic commit, he or she should use kill query by id. */ @Test - void shouldTerminatePeriodicCommitQueryRandomly() - { - Future queryResult = runQueryInDifferentThreadAndResetSession( longPeriodicCommitQuery(), true ); + void shouldTerminatePeriodicCommitQueryRandomly() { + Future queryResult = runQueryInDifferentThreadAndResetSession(longPeriodicCommitQuery(), true); - ExecutionException e = assertThrows( ExecutionException.class, () -> queryResult.get( 1, MINUTES ) ); - assertThat( e.getCause(), instanceOf( Neo4jException.class ) ); + ExecutionException e = assertThrows(ExecutionException.class, () -> queryResult.get(1, MINUTES)); + assertThat(e.getCause(), instanceOf(Neo4jException.class)); awaitNoActiveQueries(); - assertThat( countNodes(), lessThanOrEqualTo( ((long) CSV_FILE_SIZE) * LOAD_CSV_BATCH_SIZE ) ); + assertThat(countNodes(), lessThanOrEqualTo(((long) CSV_FILE_SIZE) * LOAD_CSV_BATCH_SIZE)); } @Test - void shouldTerminateAutoCommitQueriesRandomly() throws Exception - { - testRandomQueryTermination( true ); + void shouldTerminateAutoCommitQueriesRandomly() throws Exception { + testRandomQueryTermination(true); } @Test - void shouldTerminateQueriesInUnmanagedTransactionsRandomly() throws Exception - { - testRandomQueryTermination( false ); + void shouldTerminateQueriesInUnmanagedTransactionsRandomly() throws Exception { + testRandomQueryTermination(false); } @Test - void shouldRejectNewTransactionWhenOpenTransactionExistsAndShouldFailRunResultOnSessionReset() throws Throwable - { - neo4j.ensureProcedures( "longRunningStatement.jar" ); + void shouldRejectNewTransactionWhenOpenTransactionExistsAndShouldFailRunResultOnSessionReset() throws Throwable { + neo4j.ensureProcedures("longRunningStatement.jar"); - try ( Session session = neo4j.driver().session() ) - { + try (Session session = neo4j.driver().session()) { Transaction tx1 = session.beginTransaction(); CompletableFuture txRunFuture = CompletableFuture.runAsync( - () -> tx1.run( "CALL test.driver.longRunningStatement({seconds})", parameters( "seconds", 10 ) ) ); + () -> tx1.run("CALL test.driver.longRunningStatement({seconds})", parameters("seconds", 10))); - awaitActiveQueriesToContain( "CALL test.driver.longRunningStatement" ); + awaitActiveQueriesToContain("CALL test.driver.longRunningStatement"); session.reset(); - ClientException e1 = assertThrows( ClientException.class, session::beginTransaction ); - assertThat( e1.getMessage(), containsString( "You cannot begin a transaction on a session with an open transaction" ) ); + ClientException e1 = assertThrows(ClientException.class, session::beginTransaction); + assertThat( + e1.getMessage(), + containsString("You cannot begin a transaction on a session with an open transaction")); - ClientException e2 = assertThrows( ClientException.class, () -> tx1.run( "RETURN 1" ) ); - assertThat( e2.getMessage(), containsString( "Cannot run more queries in this transaction" ) ); + ClientException e2 = assertThrows(ClientException.class, () -> tx1.run("RETURN 1")); + assertThat(e2.getMessage(), containsString("Cannot run more queries in this transaction")); // Make sure failure from the terminated long running query is propagated - Neo4jException e3 = assertThrows( Neo4jException.class, () -> await( txRunFuture ) ); - assertThat( e3.getMessage(), containsString( "The transaction has been terminated" ) ); + Neo4jException e3 = assertThrows(Neo4jException.class, () -> await(txRunFuture)); + assertThat(e3.getMessage(), containsString("The transaction has been terminated")); } } @Test - void shouldSuccessfullyCloseAfterSessionReset() throws Throwable - { - neo4j.ensureProcedures( "longRunningStatement.jar" ); + void shouldSuccessfullyCloseAfterSessionReset() throws Throwable { + neo4j.ensureProcedures("longRunningStatement.jar"); - try ( Session session = neo4j.driver().session() ) - { + try (Session session = neo4j.driver().session()) { CompletableFuture.runAsync( - () -> session.run( "CALL test.driver.longRunningStatement({seconds})", parameters( "seconds", 10 ) ) ); + () -> session.run("CALL test.driver.longRunningStatement({seconds})", parameters("seconds", 10))); - awaitActiveQueriesToContain( "CALL test.driver.longRunningStatement" ); + awaitActiveQueriesToContain("CALL test.driver.longRunningStatement"); session.reset(); } } @Test - void shouldBeAbleToBeginNewTransactionAfterFirstTransactionInterruptedBySessionResetIsClosed() throws Throwable - { - neo4j.ensureProcedures( "longRunningStatement.jar" ); + void shouldBeAbleToBeginNewTransactionAfterFirstTransactionInterruptedBySessionResetIsClosed() throws Throwable { + neo4j.ensureProcedures("longRunningStatement.jar"); - try ( Session session = neo4j.driver().session() ) - { + try (Session session = neo4j.driver().session()) { Transaction tx1 = session.beginTransaction(); CompletableFuture txRunFuture = runAsync( - () -> tx1.run( "CALL test.driver.longRunningStatement({seconds})", parameters( "seconds", 10 ) ) ); + () -> tx1.run("CALL test.driver.longRunningStatement({seconds})", parameters("seconds", 10))); - awaitActiveQueriesToContain( "CALL test.driver.longRunningStatement" ); + awaitActiveQueriesToContain("CALL test.driver.longRunningStatement"); session.reset(); - Neo4jException e = assertThrows( Neo4jException.class, () -> await( txRunFuture ) ); - assertThat( e.getMessage(), containsString( "The transaction has been terminated" ) ); + Neo4jException e = assertThrows(Neo4jException.class, () -> await(txRunFuture)); + assertThat(e.getMessage(), containsString("The transaction has been terminated")); tx1.close(); - try ( Transaction tx2 = session.beginTransaction() ) - { - tx2.run( "CREATE (n:FirstNode)" ); + try (Transaction tx2 = session.beginTransaction()) { + tx2.run("CREATE (n:FirstNode)"); tx2.commit(); } - Result result = session.run( "MATCH (n) RETURN count(n)" ); - long nodes = result.single().get( "count(n)" ).asLong(); - MatcherAssert.assertThat( nodes, equalTo( 1L ) ); + Result result = session.run("MATCH (n) RETURN count(n)"); + long nodes = result.single().get("count(n)").asLong(); + MatcherAssert.assertThat(nodes, equalTo(1L)); } } @Test - void shouldKillLongRunningQuery() throws Throwable - { - neo4j.ensureProcedures( "longRunningStatement.jar" ); + void shouldKillLongRunningQuery() throws Throwable { + neo4j.ensureProcedures("longRunningStatement.jar"); final int executionTimeout = 10; // 10s final int killTimeout = 1; // 1s - final AtomicLong startTime = new AtomicLong( -1 ); + final AtomicLong startTime = new AtomicLong(-1); long endTime; - try ( Session session = neo4j.driver().session() ) - { - CompletableFuture sessionRunFuture = CompletableFuture.runAsync( - () -> - { - // When - startTime.set( System.currentTimeMillis() ); - session.run( "CALL test.driver.longRunningStatement({seconds})", parameters( "seconds", executionTimeout ) ); - } ); + try (Session session = neo4j.driver().session()) { + CompletableFuture sessionRunFuture = CompletableFuture.runAsync(() -> { + // When + startTime.set(System.currentTimeMillis()); + session.run( + "CALL test.driver.longRunningStatement({seconds})", parameters("seconds", executionTimeout)); + }); - resetSessionAfterTimeout( session, killTimeout ); + resetSessionAfterTimeout(session, killTimeout); - assertThrows( Neo4jException.class, () -> await( sessionRunFuture ) ); + assertThrows(Neo4jException.class, () -> await(sessionRunFuture)); } endTime = System.currentTimeMillis(); - assertTrue( startTime.get() > 0 ); - assertTrue( endTime - startTime.get() > killTimeout * 1000 ); // get reset by session.reset - assertTrue( endTime - startTime.get() < executionTimeout * 1000 / 2 ); // finished before execution finished + assertTrue(startTime.get() > 0); + assertTrue(endTime - startTime.get() > killTimeout * 1000); // get reset by session.reset + assertTrue(endTime - startTime.get() < executionTimeout * 1000 / 2); // finished before execution finished } @Test - void shouldKillLongStreamingResult() throws Throwable - { - neo4j.ensureProcedures( "longRunningStatement.jar" ); + void shouldKillLongStreamingResult() throws Throwable { + neo4j.ensureProcedures("longRunningStatement.jar"); // Given final int executionTimeout = 10; // 10s final int killTimeout = 1; // 1s final AtomicInteger recordCount = new AtomicInteger(); - final AtomicLong startTime = new AtomicLong( -1 ); + final AtomicLong startTime = new AtomicLong(-1); long endTime; - Neo4jException e = assertThrows( Neo4jException.class, () -> - { - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "CALL test.driver.longStreamingResult({seconds})", - parameters( "seconds", executionTimeout ) ); + Neo4jException e = assertThrows(Neo4jException.class, () -> { + try (Session session = neo4j.driver().session()) { + Result result = session.run( + "CALL test.driver.longStreamingResult({seconds})", parameters("seconds", executionTimeout)); - resetSessionAfterTimeout( session, killTimeout ); + resetSessionAfterTimeout(session, killTimeout); // When - startTime.set( System.currentTimeMillis() ); - while ( result.hasNext() ) - { + startTime.set(System.currentTimeMillis()); + while (result.hasNext()) { result.next(); recordCount.incrementAndGet(); } } - } ); + }); endTime = System.currentTimeMillis(); - assertThat( e.getMessage(), containsString( "The transaction has been terminated" ) ); - assertThat( recordCount.get(), greaterThan( 1 ) ); + assertThat(e.getMessage(), containsString("The transaction has been terminated")); + assertThat(recordCount.get(), greaterThan(1)); - assertTrue( startTime.get() > 0 ); - assertTrue( endTime - startTime.get() > killTimeout * 1000 ); // get reset by session.reset - assertTrue( endTime - startTime.get() < executionTimeout * 1000 / 2 ); // finished before execution finished + assertTrue(startTime.get() > 0); + assertTrue(endTime - startTime.get() > killTimeout * 1000); // get reset by session.reset + assertTrue(endTime - startTime.get() < executionTimeout * 1000 / 2); // finished before execution finished } - private void resetSessionAfterTimeout( Session session, int timeout ) - { - executor.submit( () -> - { - try - { - Thread.sleep( timeout * 1000 ); // let the query execute for timeout seconds - } - catch ( InterruptedException ignore ) - { - } - finally - { + private void resetSessionAfterTimeout(Session session, int timeout) { + executor.submit(() -> { + try { + Thread.sleep(timeout * 1000); // let the query execute for timeout seconds + } catch (InterruptedException ignore) { + } finally { session.reset(); // reset the session after timeout } - } ); + }); } @Test - void shouldAllowMoreQueriesAfterSessionReset() - { + void shouldAllowMoreQueriesAfterSessionReset() { // Given - try ( Session session = neo4j.driver().session() ) - { + try (Session session = neo4j.driver().session()) { - session.run( "RETURN 1" ).consume(); + session.run("RETURN 1").consume(); // When reset the state of this session session.reset(); // Then can run successfully more queries without any error - session.run( "RETURN 2" ).consume(); + session.run("RETURN 2").consume(); } } @Test - void shouldAllowMoreTxAfterSessionReset() - { + void shouldAllowMoreTxAfterSessionReset() { // Given - try ( Session session = neo4j.driver().session() ) - { - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "RETURN 1" ); + try (Session session = neo4j.driver().session()) { + try (Transaction tx = session.beginTransaction()) { + tx.run("RETURN 1"); tx.commit(); } @@ -366,324 +330,286 @@ void shouldAllowMoreTxAfterSessionReset() session.reset(); // Then can run more Tx - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "RETURN 2" ); + try (Transaction tx = session.beginTransaction()) { + tx.run("RETURN 2"); tx.commit(); } } } @Test - void shouldMarkTxAsFailedAndDisallowRunAfterSessionReset() - { + void shouldMarkTxAsFailedAndDisallowRunAfterSessionReset() { // Given - try ( Session session = neo4j.driver().session() ) - { + try (Session session = neo4j.driver().session()) { Transaction tx = session.beginTransaction(); // When reset the state of this session session.reset(); // Then - Exception e = assertThrows( Exception.class, () -> - { - tx.run( "RETURN 1" ); + Exception e = assertThrows(Exception.class, () -> { + tx.run("RETURN 1"); tx.commit(); - } ); - assertThat( e.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); + }); + assertThat(e.getMessage(), startsWith("Cannot run more queries in this transaction")); } } @Test - void shouldAllowMoreTxAfterSessionResetInTx() - { + void shouldAllowMoreTxAfterSessionResetInTx() { // Given - try ( Session session = neo4j.driver().session() ) - { - try ( Transaction ignore = session.beginTransaction() ) - { + try (Session session = neo4j.driver().session()) { + try (Transaction ignore = session.beginTransaction()) { // When reset the state of this session session.reset(); } // Then can run more Tx - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "RETURN 2" ); + try (Transaction tx = session.beginTransaction()) { + tx.run("RETURN 2"); tx.commit(); } } } @Test - void resetShouldStopQueryWaitingForALock() throws Exception - { - testResetOfQueryWaitingForLock( new NodeIdUpdater() - { + void resetShouldStopQueryWaitingForALock() throws Exception { + testResetOfQueryWaitingForLock(new NodeIdUpdater() { @Override - void performUpdate( Driver driver, int nodeId, int newNodeId, - AtomicReference usedSessionRef, CountDownLatch latchToWait ) throws Exception - { - try ( Session session = driver.session() ) - { - usedSessionRef.set( session ); + void performUpdate( + Driver driver, + int nodeId, + int newNodeId, + AtomicReference usedSessionRef, + CountDownLatch latchToWait) + throws Exception { + try (Session session = driver.session()) { + usedSessionRef.set(session); latchToWait.await(); - Result result = updateNodeId( session, nodeId, newNodeId ); + Result result = updateNodeId(session, nodeId, newNodeId); result.consume(); } } - } ); + }); } @Test - void resetShouldStopTransactionWaitingForALock() throws Exception - { - testResetOfQueryWaitingForLock( new NodeIdUpdater() - { + void resetShouldStopTransactionWaitingForALock() throws Exception { + testResetOfQueryWaitingForLock(new NodeIdUpdater() { @Override - public void performUpdate( Driver driver, int nodeId, int newNodeId, - AtomicReference usedSessionRef, CountDownLatch latchToWait ) throws Exception - { - try ( Session session = neo4j.driver().session(); - Transaction tx = session.beginTransaction() ) - { - usedSessionRef.set( session ); + public void performUpdate( + Driver driver, + int nodeId, + int newNodeId, + AtomicReference usedSessionRef, + CountDownLatch latchToWait) + throws Exception { + try (Session session = neo4j.driver().session(); + Transaction tx = session.beginTransaction()) { + usedSessionRef.set(session); latchToWait.await(); - Result result = updateNodeId( tx, nodeId, newNodeId ); + Result result = updateNodeId(tx, nodeId, newNodeId); result.consume(); } } - } ); + }); } @Test - void resetShouldStopWriteTransactionWaitingForALock() throws Exception - { + void resetShouldStopWriteTransactionWaitingForALock() throws Exception { AtomicInteger invocationsOfWork = new AtomicInteger(); - testResetOfQueryWaitingForLock( new NodeIdUpdater() - { + testResetOfQueryWaitingForLock(new NodeIdUpdater() { @Override - public void performUpdate( Driver driver, int nodeId, int newNodeId, - AtomicReference usedSessionRef, CountDownLatch latchToWait ) throws Exception - { - try ( Session session = driver.session() ) - { - usedSessionRef.set( session ); + public void performUpdate( + Driver driver, + int nodeId, + int newNodeId, + AtomicReference usedSessionRef, + CountDownLatch latchToWait) + throws Exception { + try (Session session = driver.session()) { + usedSessionRef.set(session); latchToWait.await(); - session.writeTransaction( tx -> - { + session.writeTransaction(tx -> { invocationsOfWork.incrementAndGet(); - Result result = updateNodeId( tx, nodeId, newNodeId ); + Result result = updateNodeId(tx, nodeId, newNodeId); result.consume(); return null; - } ); + }); } } - } ); + }); - assertEquals( 1, invocationsOfWork.get() ); + assertEquals(1, invocationsOfWork.get()); } @Test - void shouldBeAbleToRunMoreQueriesAfterResetOnNoErrorState() - { - try ( Session session = neo4j.driver().session() ) - { + void shouldBeAbleToRunMoreQueriesAfterResetOnNoErrorState() { + try (Session session = neo4j.driver().session()) { // Given session.reset(); // When Transaction tx = session.beginTransaction(); - tx.run( "CREATE (n:FirstNode)" ); + tx.run("CREATE (n:FirstNode)"); tx.commit(); // Then the outcome of both queries should be visible - Result result = session.run( "MATCH (n) RETURN count(n)" ); - long nodes = result.single().get( "count(n)" ).asLong(); - assertThat( nodes, equalTo( 1L ) ); + Result result = session.run("MATCH (n) RETURN count(n)"); + long nodes = result.single().get("count(n)").asLong(); + assertThat(nodes, equalTo(1L)); } } @Test - void shouldHandleResetBeforeRun() - { - try ( Session session = neo4j.driver().session(); - Transaction tx = session.beginTransaction() ) - { + void shouldHandleResetBeforeRun() { + try (Session session = neo4j.driver().session(); + Transaction tx = session.beginTransaction()) { session.reset(); - ClientException e = assertThrows( ClientException.class, () -> tx.run( "CREATE (n:FirstNode)" ) ); - assertThat( e.getMessage(), containsString( "Cannot run more queries in this transaction" ) ); + ClientException e = assertThrows(ClientException.class, () -> tx.run("CREATE (n:FirstNode)")); + assertThat(e.getMessage(), containsString("Cannot run more queries in this transaction")); } } @Test - void shouldHandleResetFromMultipleThreads() throws Throwable - { + void shouldHandleResetFromMultipleThreads() throws Throwable { Session session = neo4j.driver().session(); - CountDownLatch beforeCommit = new CountDownLatch( 1 ); - CountDownLatch afterReset = new CountDownLatch( 1 ); + CountDownLatch beforeCommit = new CountDownLatch(1); + CountDownLatch afterReset = new CountDownLatch(1); - Future txFuture = executor.submit( () -> - { + Future txFuture = executor.submit(() -> { Transaction tx1 = session.beginTransaction(); - tx1.run( "CREATE (n:FirstNode)" ); + tx1.run("CREATE (n:FirstNode)"); beforeCommit.countDown(); afterReset.await(); // session has been reset, it should not be possible to commit the transaction - try - { + try { tx1.commit(); - } - catch ( Neo4jException ignore ) - { + } catch (Neo4jException ignore) { } - try ( Transaction tx2 = session.beginTransaction() ) - { - tx2.run( "CREATE (n:SecondNode)" ); + try (Transaction tx2 = session.beginTransaction()) { + tx2.run("CREATE (n:SecondNode)"); tx2.commit(); } return null; - } ); + }); - Future resetFuture = executor.submit( () -> - { + Future resetFuture = executor.submit(() -> { beforeCommit.await(); session.reset(); afterReset.countDown(); return null; - } ); + }); executor.shutdown(); - executor.awaitTermination( 20, SECONDS ); + executor.awaitTermination(20, SECONDS); - txFuture.get( 20, SECONDS ); - resetFuture.get( 20, SECONDS ); + txFuture.get(20, SECONDS); + resetFuture.get(20, SECONDS); - assertEquals( 0, countNodes( "FirstNode" ) ); - assertEquals( 1, countNodes( "SecondNode" ) ); + assertEquals(0, countNodes("FirstNode")); + assertEquals(1, countNodes("SecondNode")); } - private void testResetOfQueryWaitingForLock( NodeIdUpdater nodeIdUpdater ) throws Exception - { + private void testResetOfQueryWaitingForLock(NodeIdUpdater nodeIdUpdater) throws Exception { int nodeId = 42; int newNodeId1 = 4242; int newNodeId2 = 424242; - createNodeWithId( nodeId ); + createNodeWithId(nodeId); - CountDownLatch nodeLocked = new CountDownLatch( 1 ); + CountDownLatch nodeLocked = new CountDownLatch(1); AtomicReference otherSessionRef = new AtomicReference<>(); - try ( Session session = neo4j.driver().session(); - Transaction tx = session.beginTransaction() ) - { - Future txResult = nodeIdUpdater.update( nodeId, newNodeId1, otherSessionRef, nodeLocked ); + try (Session session = neo4j.driver().session(); + Transaction tx = session.beginTransaction()) { + Future txResult = nodeIdUpdater.update(nodeId, newNodeId1, otherSessionRef, nodeLocked); - Result result = updateNodeId( tx, nodeId, newNodeId2 ); + Result result = updateNodeId(tx, nodeId, newNodeId2); result.consume(); nodeLocked.countDown(); // give separate thread some time to block on a lock - Thread.sleep( 2_000 ); + Thread.sleep(2_000); otherSessionRef.get().reset(); - assertTransactionTerminated( txResult ); + assertTransactionTerminated(txResult); tx.commit(); } - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "MATCH (n) RETURN n.id AS id" ); - int value = result.single().get( "id" ).asInt(); - assertEquals( newNodeId2, value ); + try (Session session = neo4j.driver().session()) { + Result result = session.run("MATCH (n) RETURN n.id AS id"); + int value = result.single().get("id").asInt(); + assertEquals(newNodeId2, value); } } - private void createNodeWithId( int id ) - { - try ( Session session = neo4j.driver().session() ) - { - session.run( "CREATE (n {id: $id})", parameters( "id", id ) ); + private void createNodeWithId(int id) { + try (Session session = neo4j.driver().session()) { + session.run("CREATE (n {id: $id})", parameters("id", id)); } } - private static Result updateNodeId(QueryRunner queryRunner, int currentId, int newId ) - { - return queryRunner.run( "MATCH (n {id: $currentId}) SET n.id = $newId", - parameters( "currentId", currentId, "newId", newId ) ); + private static Result updateNodeId(QueryRunner queryRunner, int currentId, int newId) { + return queryRunner.run( + "MATCH (n {id: $currentId}) SET n.id = $newId", parameters("currentId", currentId, "newId", newId)); } - private static void assertTransactionTerminated( Future work ) - { - ExecutionException e = assertThrows( ExecutionException.class, () -> work.get( 20, TimeUnit.SECONDS ) ); - assertThat( e.getCause(), CoreMatchers.instanceOf( TransientException.class ) ); - assertThat( e.getCause().getMessage(), startsWith( "The transaction has been terminated" ) ); + private static void assertTransactionTerminated(Future work) { + ExecutionException e = assertThrows(ExecutionException.class, () -> work.get(20, TimeUnit.SECONDS)); + assertThat(e.getCause(), CoreMatchers.instanceOf(TransientException.class)); + assertThat(e.getCause().getMessage(), startsWith("The transaction has been terminated")); } - private void testRandomQueryTermination( boolean autoCommit ) throws Exception - { - Set runningSessions = newSetFromMap( new ConcurrentHashMap<>() ); + private void testRandomQueryTermination(boolean autoCommit) throws Exception { + Set runningSessions = newSetFromMap(new ConcurrentHashMap<>()); AtomicBoolean stop = new AtomicBoolean(); List> futures = new ArrayList<>(); - for ( int i = 0; i < STRESS_TEST_THREAD_COUNT; i++ ) - { - futures.add( executor.submit( () -> - { + for (int i = 0; i < STRESS_TEST_THREAD_COUNT; i++) { + futures.add(executor.submit(() -> { ThreadLocalRandom random = ThreadLocalRandom.current(); - while ( !stop.get() ) - { - runRandomQuery( autoCommit, random, runningSessions, stop ); + while (!stop.get()) { + runRandomQuery(autoCommit, random, runningSessions, stop); } - } ) ); + })); } long deadline = System.currentTimeMillis() + STRESS_TEST_DURATION_MS; - while ( !stop.get() ) - { - if ( System.currentTimeMillis() > deadline ) - { - stop.set( true ); + while (!stop.get()) { + if (System.currentTimeMillis() > deadline) { + stop.set(true); } - resetAny( runningSessions ); + resetAny(runningSessions); - MILLISECONDS.sleep( 30 ); + MILLISECONDS.sleep(30); } - awaitAllFutures( futures ); + awaitAllFutures(futures); awaitNoActiveQueries(); } - private void runRandomQuery( boolean autoCommit, Random random, Set runningSessions, AtomicBoolean stop ) - { - try - { + private void runRandomQuery(boolean autoCommit, Random random, Set runningSessions, AtomicBoolean stop) { + try { Session session = neo4j.driver().session(); - runningSessions.add( session ); - try - { - String query = STRESS_TEST_QUERIES[random.nextInt( STRESS_TEST_QUERIES.length - 1 )]; - runQuery( session, query, autoCommit ); - } - finally - { - runningSessions.remove( session ); + runningSessions.add(session); + try { + String query = STRESS_TEST_QUERIES[random.nextInt(STRESS_TEST_QUERIES.length - 1)]; + runQuery(session, query, autoCommit); + } finally { + runningSessions.remove(session); session.close(); } - } - catch ( Throwable error ) - { - if ( !stop.get() && !isAcceptable( error ) ) - { - stop.set( true ); + } catch (Throwable error) { + if (!stop.get() && !isAcceptable(error)) { + stop.set(true); throw error; } // else it is fine to receive some errors from the driver because @@ -691,160 +617,132 @@ private void runRandomQuery( boolean autoCommit, Random random, Set run } } - private void testQueryTermination( String query, boolean autoCommit ) - { - Future queryResult = runQueryInDifferentThreadAndResetSession( query, autoCommit ); - ExecutionException e = assertThrows( ExecutionException.class, () -> queryResult.get( 10, SECONDS ) ); - assertThat( e.getCause(), instanceOf( Neo4jException.class ) ); + private void testQueryTermination(String query, boolean autoCommit) { + Future queryResult = runQueryInDifferentThreadAndResetSession(query, autoCommit); + ExecutionException e = assertThrows(ExecutionException.class, () -> queryResult.get(10, SECONDS)); + assertThat(e.getCause(), instanceOf(Neo4jException.class)); awaitNoActiveQueries(); } - private Future runQueryInDifferentThreadAndResetSession( String query, boolean autoCommit ) - { + private Future runQueryInDifferentThreadAndResetSession(String query, boolean autoCommit) { AtomicReference sessionRef = new AtomicReference<>(); - Future queryResult = runAsync( () -> - { + Future queryResult = runAsync(() -> { Session session = neo4j.driver().session(); - sessionRef.set( session ); - runQuery( session, query, autoCommit ); - } ); + sessionRef.set(session); + runQuery(session, query, autoCommit); + }); - awaitActiveQueriesToContain( query ); + awaitActiveQueriesToContain(query); Session session = sessionRef.get(); - assertNotNull( session ); + assertNotNull(session); session.reset(); return queryResult; } - private static void runQuery( Session session, String query, boolean autoCommit ) - { - if ( autoCommit ) - { - session.run( query ).consume(); - } - else - { - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( query ); + private static void runQuery(Session session, String query, boolean autoCommit) { + if (autoCommit) { + session.run(query).consume(); + } else { + try (Transaction tx = session.beginTransaction()) { + tx.run(query); tx.commit(); } } } - private void awaitNoActiveQueries() - { - awaitCondition( () -> activeQueryCount( neo4j.driver() ) == 0 ); + private void awaitNoActiveQueries() { + awaitCondition(() -> activeQueryCount(neo4j.driver()) == 0); } - private void awaitActiveQueriesToContain( String value ) - { - awaitCondition( () -> - activeQueryNames( neo4j.driver() ).stream().anyMatch( query -> query.contains( value ) ) ); + private void awaitActiveQueriesToContain(String value) { + awaitCondition(() -> activeQueryNames(neo4j.driver()).stream().anyMatch(query -> query.contains(value))); } - private long countNodes() - { - return countNodes( null ); + private long countNodes() { + return countNodes(null); } - private long countNodes( String label ) - { - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "MATCH (n" + (label == null ? "" : ":" + label) + ") RETURN count(n) AS result" ); - return result.single().get( 0 ).asLong(); + private long countNodes(String label) { + try (Session session = neo4j.driver().session()) { + Result result = + session.run("MATCH (n" + (label == null ? "" : ":" + label) + ") RETURN count(n) AS result"); + return result.single().get(0).asLong(); } } - private static void resetAny( Set sessions ) - { - sessions.stream().findAny().ifPresent( session -> - { - if ( sessions.remove( session ) ) - { - resetSafely( session ); + private static void resetAny(Set sessions) { + sessions.stream().findAny().ifPresent(session -> { + if (sessions.remove(session)) { + resetSafely(session); } - } ); + }); } - private static void resetSafely( Session session ) - { - try - { - if ( session.isOpen() ) - { + private static void resetSafely(Session session) { + try { + if (session.isOpen()) { session.reset(); } - } - catch ( ClientException e ) - { - if ( session.isOpen() ) - { + } catch (ClientException e) { + if (session.isOpen()) { throw e; } // else this thread lost race with close and it's fine } } - private static boolean isAcceptable( Throwable error ) - { + private static boolean isAcceptable(Throwable error) { // get the root cause - while ( error.getCause() != null ) - { + while (error.getCause() != null) { error = error.getCause(); } - return isTransactionTerminatedException( error ) || - error instanceof ServiceUnavailableException || - error instanceof ClientException || - error instanceof ClosedChannelException; + return isTransactionTerminatedException(error) + || error instanceof ServiceUnavailableException + || error instanceof ClientException + || error instanceof ClosedChannelException; } - private static boolean isTransactionTerminatedException( Throwable error ) - { - return error instanceof TransientException && - error.getMessage().startsWith( "The transaction has been terminated" ) || - error.getMessage().startsWith( "Trying to execute query in a terminated transaction" ); + private static boolean isTransactionTerminatedException(Throwable error) { + return error instanceof TransientException + && error.getMessage().startsWith("The transaction has been terminated") + || error.getMessage().startsWith("Trying to execute query in a terminated transaction"); } - private static String longPeriodicCommitQuery() - { + private static String longPeriodicCommitQuery() { URI fileUri = createTmpCsvFile(); - return String.format( LONG_PERIODIC_COMMIT_QUERY_TEMPLATE, fileUri ); + return String.format(LONG_PERIODIC_COMMIT_QUERY_TEMPLATE, fileUri); } - private static URI createTmpCsvFile() - { - try - { - Path importDir = Paths.get( HOME_DIR, TEST_SETTINGS.propertiesMap().get( IMPORT_DIR ) ); - Path csvFile = Files.createTempFile( importDir, "test", ".csv" ); - Iterable lines = range( 0, CSV_FILE_SIZE ).mapToObj( i -> "Foo-" + i + ", Bar-" + i )::iterator; - return URI.create( "file:///" + Files.write( csvFile, lines ).getFileName() ); - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); + private static URI createTmpCsvFile() { + try { + Path importDir = Paths.get(HOME_DIR, TEST_SETTINGS.propertiesMap().get(IMPORT_DIR)); + Path csvFile = Files.createTempFile(importDir, "test", ".csv"); + Iterable lines = range(0, CSV_FILE_SIZE).mapToObj(i -> "Foo-" + i + ", Bar-" + i)::iterator; + return URI.create("file:///" + Files.write(csvFile, lines).getFileName()); + } catch (IOException e) { + throw new UncheckedIOException(e); } } - private abstract class NodeIdUpdater - { - final Future update( int nodeId, int newNodeId, AtomicReference usedSessionRef, - CountDownLatch latchToWait ) - { - return executor.submit( () -> - { - performUpdate( neo4j.driver(), nodeId, newNodeId, usedSessionRef, latchToWait ); + private abstract class NodeIdUpdater { + final Future update( + int nodeId, int newNodeId, AtomicReference usedSessionRef, CountDownLatch latchToWait) { + return executor.submit(() -> { + performUpdate(neo4j.driver(), nodeId, newNodeId, usedSessionRef, latchToWait); return null; - } ); + }); } - abstract void performUpdate( Driver driver, int nodeId, int newNodeId, - AtomicReference usedSessionRef, CountDownLatch latchToWait ) throws Exception; + abstract void performUpdate( + Driver driver, + int nodeId, + int newNodeId, + AtomicReference usedSessionRef, + CountDownLatch latchToWait) + throws Exception; } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/SharedEventLoopIT.java b/driver/src/test/java/org/neo4j/driver/integration/SharedEventLoopIT.java index d45a6bc251..faa3a9b6e0 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/SharedEventLoopIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/SharedEventLoopIT.java @@ -18,13 +18,13 @@ */ package org.neo4j.driver.integration; +import static org.junit.jupiter.api.Assertions.fail; + import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.concurrent.TimeUnit; - import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.Session; @@ -35,74 +35,66 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.junit.jupiter.api.Assertions.fail; - @ParallelizableIT -class SharedEventLoopIT -{ +class SharedEventLoopIT { private final DriverFactory driverFactory = new DriverFactory(); @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - void testDriverShouldNotCloseSharedEventLoop() - { - NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup( 1 ); + void testDriverShouldNotCloseSharedEventLoop() { + NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(1); - try - { - Driver driver1 = createDriver( eventLoopGroup ); - Driver driver2 = createDriver( eventLoopGroup ); + try { + Driver driver1 = createDriver(eventLoopGroup); + Driver driver2 = createDriver(eventLoopGroup); - testConnection( driver1 ); - testConnection( driver2 ); + testConnection(driver1); + testConnection(driver2); driver1.close(); - testConnection( driver2 ); + testConnection(driver2); driver2.close(); - } - finally - { - eventLoopGroup.shutdownGracefully( 100, 100, TimeUnit.MILLISECONDS ); + } finally { + eventLoopGroup.shutdownGracefully(100, 100, TimeUnit.MILLISECONDS); } } @Test - void testDriverShouldUseSharedEventLoop() - { - NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup( 1 ); + void testDriverShouldUseSharedEventLoop() { + NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(1); - Driver driver = createDriver( eventLoopGroup ); - testConnection( driver ); + Driver driver = createDriver(eventLoopGroup); + testConnection(driver); - eventLoopGroup.shutdownGracefully( 100, 100, TimeUnit.MILLISECONDS ); + eventLoopGroup.shutdownGracefully(100, 100, TimeUnit.MILLISECONDS); // the driver should fail if it really uses the provided event loop // if the call succeeds, it meas that the driver created its own event loop - try - { - testConnection( driver ); - fail( "Exception expected" ); - } - catch ( Exception e ) - { + try { + testConnection(driver); + fail("Exception expected"); + } catch (Exception e) { // ignored } } - private Driver createDriver( EventLoopGroup eventLoopGroup ) - { - return driverFactory.newInstance( neo4j.uri(), neo4j.authToken(), RoutingSettings.DEFAULT, RetrySettings.DEFAULT, Config.defaultConfig(), - eventLoopGroup, SecurityPlanImpl.insecure() ); + private Driver createDriver(EventLoopGroup eventLoopGroup) { + return driverFactory.newInstance( + neo4j.uri(), + neo4j.authToken(), + RoutingSettings.DEFAULT, + RetrySettings.DEFAULT, + Config.defaultConfig(), + eventLoopGroup, + SecurityPlanImpl.insecure()); } - private void testConnection( Driver driver ) - { - try ( Session session = driver.session() ) - { - session.run( "RETURN 1" ); + private void testConnection(Driver driver) { + try (Session session = driver.session()) { + session.run("RETURN 1"); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/SpatialTypesIT.java b/driver/src/test/java/org/neo4j/driver/integration/SpatialTypesIT.java index ec0458eb97..ff143ddda9 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/SpatialTypesIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/SpatialTypesIT.java @@ -18,32 +18,29 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Collections.singletonMap; +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.neo4j.driver.Values.ofPoint; +import static org.neo4j.driver.Values.point; +import static org.neo4j.driver.internal.util.Neo4jFeature.SPATIAL_TYPES; import java.util.List; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.IntStream; import java.util.stream.Stream; - -import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Record; import org.neo4j.driver.Value; +import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; import org.neo4j.driver.types.Point; import org.neo4j.driver.util.ParallelizableIT; import org.neo4j.driver.util.SessionExtension; -import static java.util.Collections.singletonMap; -import static java.util.stream.Collectors.toList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.neo4j.driver.internal.util.Neo4jFeature.SPATIAL_TYPES; -import static org.neo4j.driver.Values.ofPoint; -import static org.neo4j.driver.Values.point; - -@EnabledOnNeo4jWith( SPATIAL_TYPES ) +@EnabledOnNeo4jWith(SPATIAL_TYPES) @ParallelizableIT -class SpatialTypesIT -{ +class SpatialTypesIT { private static final int WGS_84_CRS_CODE = 4326; private static final int CARTESIAN_CRS_CODE = 7203; private static final double DELTA = 0.00001; @@ -52,110 +49,98 @@ class SpatialTypesIT static final SessionExtension session = new SessionExtension(); @Test - void shouldReceivePoint() - { - Record record = session.run( "RETURN point({x: 39.111748, y:-76.775635})" ).single(); + void shouldReceivePoint() { + Record record = + session.run("RETURN point({x: 39.111748, y:-76.775635})").single(); - Point point = record.get( 0 ).asPoint(); + Point point = record.get(0).asPoint(); - assertEquals( CARTESIAN_CRS_CODE, point.srid() ); - assertEquals( 39.111748, point.x(), DELTA ); - assertEquals( -76.775635, point.y(), DELTA ); + assertEquals(CARTESIAN_CRS_CODE, point.srid()); + assertEquals(39.111748, point.x(), DELTA); + assertEquals(-76.775635, point.y(), DELTA); } @Test - void shouldSendPoint() - { - Value pointValue = point( WGS_84_CRS_CODE, 38.8719, 77.0563 ); - Record record1 = session.run( "CREATE (n:Node {location: $point}) RETURN 42", singletonMap( "point", pointValue ) ).single(); + void shouldSendPoint() { + Value pointValue = point(WGS_84_CRS_CODE, 38.8719, 77.0563); + Record record1 = session.run("CREATE (n:Node {location: $point}) RETURN 42", singletonMap("point", pointValue)) + .single(); - assertEquals( 42, record1.get( 0 ).asInt() ); + assertEquals(42, record1.get(0).asInt()); - Record record2 = session.run( "MATCH (n:Node) RETURN n.location" ).single(); - Point point = record2.get( 0 ).asPoint(); + Record record2 = session.run("MATCH (n:Node) RETURN n.location").single(); + Point point = record2.get(0).asPoint(); - assertEquals( WGS_84_CRS_CODE, point.srid() ); - assertEquals( 38.8719, point.x(), DELTA ); - assertEquals( 77.0563, point.y(), DELTA ); + assertEquals(WGS_84_CRS_CODE, point.srid()); + assertEquals(38.8719, point.x(), DELTA); + assertEquals(77.0563, point.y(), DELTA); } @Test - void shouldSendAndReceivePoint() - { - testPointSendAndReceive( point( CARTESIAN_CRS_CODE, 40.7624, 73.9738 ) ); + void shouldSendAndReceivePoint() { + testPointSendAndReceive(point(CARTESIAN_CRS_CODE, 40.7624, 73.9738)); } @Test - void shouldSendAndReceiveRandom2DPoints() - { - Stream randomPoints = ThreadLocalRandom.current() - .ints( 1_000, 0, 2 ) - .mapToObj( SpatialTypesIT::createPoint ); + void shouldSendAndReceiveRandom2DPoints() { + Stream randomPoints = + ThreadLocalRandom.current().ints(1_000, 0, 2).mapToObj(SpatialTypesIT::createPoint); - randomPoints.forEach( this::testPointSendAndReceive ); + randomPoints.forEach(this::testPointSendAndReceive); } @Test - void shouldSendAndReceiveRandom2DPointArrays() - { - Stream> randomPointLists = ThreadLocalRandom.current() - .ints( 1_000, 0, 2 ) - .mapToObj( SpatialTypesIT::randomPointList ); + void shouldSendAndReceiveRandom2DPointArrays() { + Stream> randomPointLists = + ThreadLocalRandom.current().ints(1_000, 0, 2).mapToObj(SpatialTypesIT::randomPointList); - randomPointLists.forEach( this::testPointListSendAndReceive ); + randomPointLists.forEach(this::testPointListSendAndReceive); } - private void testPointSendAndReceive( Value pointValue ) - { + private void testPointSendAndReceive(Value pointValue) { Point originalPoint = pointValue.asPoint(); - Record record = session.run( "CREATE (n {point: $point}) return n.point", singletonMap( "point", pointValue ) ).single(); - Point receivedPoint = record.get( 0 ).asPoint(); + Record record = session.run("CREATE (n {point: $point}) return n.point", singletonMap("point", pointValue)) + .single(); + Point receivedPoint = record.get(0).asPoint(); - assertPoints2DEqual( originalPoint, receivedPoint ); + assertPoints2DEqual(originalPoint, receivedPoint); } - private void testPointListSendAndReceive( List points ) - { - Record record = session.run( "CREATE (n {points: $points}) return n.points", singletonMap( "points", points ) ).single(); - List receivedPoints = record.get( 0 ).asList( ofPoint() ); + private void testPointListSendAndReceive(List points) { + Record record = session.run("CREATE (n {points: $points}) return n.points", singletonMap("points", points)) + .single(); + List receivedPoints = record.get(0).asList(ofPoint()); - assertEquals( points.size(), receivedPoints.size() ); - for ( int i = 0; i < points.size(); i++ ) - { - assertPoints2DEqual( points.get( i ).asPoint(), receivedPoints.get( i ) ); + assertEquals(points.size(), receivedPoints.size()); + for (int i = 0; i < points.size(); i++) { + assertPoints2DEqual(points.get(i).asPoint(), receivedPoints.get(i)); } } - private static List randomPointList( int index ) - { - int size = ThreadLocalRandom.current().nextInt( 1, 100 ); - return IntStream.range( 0, size ) - .mapToObj( ignored -> createPoint( index ) ) - .collect( toList() ); + private static List randomPointList(int index) { + int size = ThreadLocalRandom.current().nextInt(1, 100); + return IntStream.range(0, size).mapToObj(ignored -> createPoint(index)).collect(toList()); } - private static Value createPoint( int idx ) - { + private static Value createPoint(int idx) { return idx % 2 == 0 - ? point( CARTESIAN_CRS_CODE, randomDouble(), randomDouble() ) - : point( WGS_84_CRS_CODE, randomDouble(), randomDoubleWGS_84_Y() ); + ? point(CARTESIAN_CRS_CODE, randomDouble(), randomDouble()) + : point(WGS_84_CRS_CODE, randomDouble(), randomDoubleWGS_84_Y()); } - private static double randomDouble() - { - return ThreadLocalRandom.current().nextDouble( -180.0, 180 ); + private static double randomDouble() { + return ThreadLocalRandom.current().nextDouble(-180.0, 180); } - private static double randomDoubleWGS_84_Y() - { - return ThreadLocalRandom.current().nextDouble( -90.0, 90 ); + + private static double randomDoubleWGS_84_Y() { + return ThreadLocalRandom.current().nextDouble(-90.0, 90); } - private static void assertPoints2DEqual( Point expected, Point actual ) - { + private static void assertPoints2DEqual(Point expected, Point actual) { String message = "Expected: " + expected + " but was: " + actual; - assertEquals( expected.srid(), actual.srid(), message ); - assertEquals( expected.x(), actual.x(), DELTA, message ); - assertEquals( expected.y(), actual.y(), DELTA, message ); + assertEquals(expected.srid(), actual.srid(), message); + assertEquals(expected.x(), actual.x(), DELTA, message); + assertEquals(expected.y(), actual.y(), DELTA, message); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/SummaryIT.java b/driver/src/test/java/org/neo4j/driver/integration/SummaryIT.java index 6850ad223e..6aa0c63216 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/SummaryIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/SummaryIT.java @@ -18,16 +18,25 @@ */ package org.neo4j.driver.integration; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.SessionConfig.forDatabase; + +import java.util.List; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; @@ -35,185 +44,188 @@ import org.neo4j.driver.summary.Notification; import org.neo4j.driver.summary.Plan; import org.neo4j.driver.summary.ProfiledPlan; -import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.summary.QueryType; +import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.SessionConfig.forDatabase; - @ParallelizableIT -class SummaryIT -{ +class SummaryIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); + private Session session; @BeforeEach - void setup() - { + void setup() { session = neo4j.driver().session(); } @AfterEach - void tearDown() - { - if ( session != null && session.isOpen() ) - { + void tearDown() { + if (session != null && session.isOpen()) { session.close(); } session = null; } @Test - void shouldContainBasicMetadata() - { + void shouldContainBasicMetadata() { // Given - Value parameters = Values.parameters( "limit", 10 ); + Value parameters = Values.parameters("limit", 10); String query = "UNWIND [1, 2, 3, 4] AS n RETURN n AS number LIMIT $limit"; // When - Result result = session.run( query, parameters ); + Result result = session.run(query, parameters); // Then - assertTrue( result.hasNext() ); + assertTrue(result.hasNext()); // When ResultSummary summary = result.consume(); // Then - assertThat( summary.queryType(), equalTo( QueryType.READ_ONLY ) ); - assertThat( summary.query().text(), equalTo( query ) ); - assertThat( summary.query().parameters(), equalTo( parameters ) ); - assertFalse( summary.hasPlan() ); - assertFalse( summary.hasProfile() ); - assertThat( summary, equalTo( result.consume() ) ); - + assertThat(summary.queryType(), equalTo(QueryType.READ_ONLY)); + assertThat(summary.query().text(), equalTo(query)); + assertThat(summary.query().parameters(), equalTo(parameters)); + assertFalse(summary.hasPlan()); + assertFalse(summary.hasProfile()); + assertThat(summary, equalTo(result.consume())); } @Test - void shouldContainTimeInformation() - { + void shouldContainTimeInformation() { // Given - ResultSummary summary = session.run( "UNWIND range(1,1000) AS n RETURN n AS number" ).consume(); + ResultSummary summary = + session.run("UNWIND range(1,1000) AS n RETURN n AS number").consume(); // Then - assertThat( summary.resultAvailableAfter( TimeUnit.MILLISECONDS ), greaterThanOrEqualTo( 0L ) ); - assertThat( summary.resultConsumedAfter( TimeUnit.MILLISECONDS ), greaterThanOrEqualTo( 0L ) ); + assertThat(summary.resultAvailableAfter(TimeUnit.MILLISECONDS), greaterThanOrEqualTo(0L)); + assertThat(summary.resultConsumedAfter(TimeUnit.MILLISECONDS), greaterThanOrEqualTo(0L)); } @Test - void shouldContainCorrectStatistics() - { - assertThat( session.run( "CREATE (n)" ).consume().counters().nodesCreated(), equalTo( 1 ) ); - assertThat( session.run( "MATCH (n) DELETE (n)" ).consume().counters().nodesDeleted(), equalTo( 1 ) ); - - assertThat( session.run( "CREATE ()-[:KNOWS]->()" ).consume().counters().relationshipsCreated(), equalTo( 1 ) ); - assertThat( session.run( "MATCH ()-[r:KNOWS]->() DELETE r" ).consume().counters().relationshipsDeleted(), equalTo( 1 ) ); - - assertThat( session.run( "CREATE (n:ALabel)" ).consume().counters().labelsAdded(), equalTo( 1 ) ); - assertThat( session.run( "CREATE (n {magic: 42})" ).consume().counters().propertiesSet(), equalTo( 1 ) ); - assertTrue( session.run( "CREATE (n {magic: 42})" ).consume().counters().containsUpdates() ); - assertThat( session.run( "MATCH (n:ALabel) REMOVE n:ALabel " ).consume().counters().labelsRemoved(), equalTo( 1 ) ); - - assertThat( session.run( "CREATE INDEX ON :ALabel(prop)" ).consume().counters().indexesAdded(), equalTo( 1 ) ); - assertThat( session.run( "DROP INDEX ON :ALabel(prop)" ).consume().counters().indexesRemoved(), equalTo( 1 ) ); - - assertThat( session.run( "CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE" ) - .consume().counters().constraintsAdded(), equalTo( 1 ) ); - assertThat( session.run( "DROP CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE" ) - .consume().counters().constraintsRemoved(), equalTo( 1 ) ); + void shouldContainCorrectStatistics() { + assertThat(session.run("CREATE (n)").consume().counters().nodesCreated(), equalTo(1)); + assertThat(session.run("MATCH (n) DELETE (n)").consume().counters().nodesDeleted(), equalTo(1)); + + assertThat(session.run("CREATE ()-[:KNOWS]->()").consume().counters().relationshipsCreated(), equalTo(1)); + assertThat( + session.run("MATCH ()-[r:KNOWS]->() DELETE r") + .consume() + .counters() + .relationshipsDeleted(), + equalTo(1)); + + assertThat(session.run("CREATE (n:ALabel)").consume().counters().labelsAdded(), equalTo(1)); + assertThat(session.run("CREATE (n {magic: 42})").consume().counters().propertiesSet(), equalTo(1)); + assertTrue(session.run("CREATE (n {magic: 42})").consume().counters().containsUpdates()); + assertThat( + session.run("MATCH (n:ALabel) REMOVE n:ALabel ") + .consume() + .counters() + .labelsRemoved(), + equalTo(1)); + + assertThat( + session.run("CREATE INDEX ON :ALabel(prop)") + .consume() + .counters() + .indexesAdded(), + equalTo(1)); + assertThat( + session.run("DROP INDEX ON :ALabel(prop)").consume().counters().indexesRemoved(), equalTo(1)); + + assertThat( + session.run("CREATE CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE") + .consume() + .counters() + .constraintsAdded(), + equalTo(1)); + assertThat( + session.run("DROP CONSTRAINT ON (book:Book) ASSERT book.isbn IS UNIQUE") + .consume() + .counters() + .constraintsRemoved(), + equalTo(1)); } @Test - @EnabledOnNeo4jWith( Neo4jFeature.BOLT_V4 ) - void shouldGetSystemUpdates() throws Throwable - { - try ( Session session = neo4j.driver().session( forDatabase( "system" ) ) ) - { - Result result = session.run( "CREATE USER foo SET PASSWORD 'bar'" ); - assertThat( result.consume().counters().containsUpdates(), equalTo( false ) ); - assertThat( result.consume().counters().containsSystemUpdates(), equalTo( true ) ); + @EnabledOnNeo4jWith(Neo4jFeature.BOLT_V4) + void shouldGetSystemUpdates() throws Throwable { + try (Session session = neo4j.driver().session(forDatabase("system"))) { + Result result = session.run("CREATE USER foo SET PASSWORD 'bar'"); + assertThat(result.consume().counters().containsUpdates(), equalTo(false)); + assertThat(result.consume().counters().containsSystemUpdates(), equalTo(true)); } } @Test - void shouldContainCorrectQueryType() - { - assertThat( session.run("MATCH (n) RETURN 1").consume().queryType(), equalTo( QueryType.READ_ONLY )); - assertThat( session.run("CREATE (n)").consume().queryType(), equalTo( QueryType.WRITE_ONLY )); - assertThat( session.run("CREATE (n) RETURN (n)").consume().queryType(), equalTo( QueryType.READ_WRITE )); - assertThat( session.run("CREATE INDEX ON :User(p)").consume().queryType(), equalTo( QueryType.SCHEMA_WRITE )); + void shouldContainCorrectQueryType() { + assertThat(session.run("MATCH (n) RETURN 1").consume().queryType(), equalTo(QueryType.READ_ONLY)); + assertThat(session.run("CREATE (n)").consume().queryType(), equalTo(QueryType.WRITE_ONLY)); + assertThat(session.run("CREATE (n) RETURN (n)").consume().queryType(), equalTo(QueryType.READ_WRITE)); + assertThat(session.run("CREATE INDEX ON :User(p)").consume().queryType(), equalTo(QueryType.SCHEMA_WRITE)); } @Test - void shouldContainCorrectPlan() - { + void shouldContainCorrectPlan() { // When - ResultSummary summary = session.run( "EXPLAIN MATCH (n) RETURN 1" ).consume(); + ResultSummary summary = session.run("EXPLAIN MATCH (n) RETURN 1").consume(); // Then - assertTrue( summary.hasPlan() ); + assertTrue(summary.hasPlan()); Plan plan = summary.plan(); - assertThat( plan.operatorType(), notNullValue() ); - assertThat( plan.identifiers().size(), greaterThan( 0 ) ); - assertThat( plan.arguments().size(), greaterThan( 0 ) ); - assertThat( plan.children().size(), greaterThan( 0 ) ); + assertThat(plan.operatorType(), notNullValue()); + assertThat(plan.identifiers().size(), greaterThan(0)); + assertThat(plan.arguments().size(), greaterThan(0)); + assertThat(plan.children().size(), greaterThan(0)); } @Test - void shouldContainProfile() - { + void shouldContainProfile() { // When - ResultSummary summary = session.run( "PROFILE RETURN 1" ).consume(); + ResultSummary summary = session.run("PROFILE RETURN 1").consume(); // Then - assertTrue( summary.hasProfile() ); - assertTrue( summary.hasPlan() ); // Profile is a superset of plan, so plan should be available as well if profile is available - assertEquals( summary.plan(), summary.profile() ); + assertTrue(summary.hasProfile()); + assertTrue( + summary.hasPlan()); // Profile is a superset of plan, so plan should be available as well if profile is + // available + assertEquals(summary.plan(), summary.profile()); ProfiledPlan profile = summary.profile(); - assertEquals( 0, profile.time() ); - assertEquals( 0, profile.dbHits() ); - assertEquals( 1, profile.records() ); + assertEquals(0, profile.time()); + assertEquals(0, profile.dbHits()); + assertEquals(1, profile.records()); } @Test - void shouldContainNotifications() - { + void shouldContainNotifications() { // When - ResultSummary summary = session.run( "EXPLAIN MATCH (n:ThisLabelDoesNotExist) RETURN n" ).consume(); + ResultSummary summary = + session.run("EXPLAIN MATCH (n:ThisLabelDoesNotExist) RETURN n").consume(); // Then List notifications = summary.notifications(); - assertNotNull( notifications ); - assertThat( notifications.size(), equalTo( 1 ) ); - Notification notification = notifications.get( 0 ); - assertThat( notification.code(), notNullValue() ); - assertThat( notification.title(), notNullValue() ); - assertThat( notification.description(), notNullValue() ); - assertThat( notification.severity(), notNullValue() ); - assertThat( notification.position(), notNullValue() ); + assertNotNull(notifications); + assertThat(notifications.size(), equalTo(1)); + Notification notification = notifications.get(0); + assertThat(notification.code(), notNullValue()); + assertThat(notification.title(), notNullValue()); + assertThat(notification.description(), notNullValue()); + assertThat(notification.severity(), notNullValue()); + assertThat(notification.position(), notNullValue()); } @Test - void shouldContainNoNotifications() throws Throwable - { + void shouldContainNoNotifications() throws Throwable { // When - ResultSummary summary = session.run( "RETURN 1" ).consume(); + ResultSummary summary = session.run("RETURN 1").consume(); // Then - assertThat( summary.notifications().size(), equalTo( 0 ) ); + assertThat(summary.notifications().size(), equalTo(0)); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/TemporalTypesIT.java b/driver/src/test/java/org/neo4j/driver/integration/TemporalTypesIT.java index 82204ef275..91568fa47b 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/TemporalTypesIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/TemporalTypesIT.java @@ -18,8 +18,14 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.time.Month.MARCH; +import static java.util.Collections.singletonMap; +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.neo4j.driver.Values.isoDuration; +import static org.neo4j.driver.Values.ofOffsetDateTime; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.util.Neo4jFeature.TEMPORAL_TYPES; import java.time.LocalDate; import java.time.LocalDateTime; @@ -34,7 +40,8 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.Value; @@ -44,19 +51,9 @@ import org.neo4j.driver.util.SessionExtension; import org.neo4j.driver.util.TemporalUtil; -import static java.time.Month.MARCH; -import static java.util.Collections.singletonMap; -import static java.util.stream.Collectors.toList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.neo4j.driver.Values.isoDuration; -import static org.neo4j.driver.Values.ofOffsetDateTime; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.util.Neo4jFeature.TEMPORAL_TYPES; - -@EnabledOnNeo4jWith( TEMPORAL_TYPES ) +@EnabledOnNeo4jWith(TEMPORAL_TYPES) @ParallelizableIT -class TemporalTypesIT -{ +class TemporalTypesIT { private static final int RANDOM_VALUES_TO_TEST = 1_000; private static final int RANDOM_LISTS_TO_TEST = 100; @@ -67,356 +64,314 @@ class TemporalTypesIT static final SessionExtension session = new SessionExtension(); @Test - void shouldSendDate() - { - testSendValue( LocalDate.now(), Value::asLocalDate ); + void shouldSendDate() { + testSendValue(LocalDate.now(), Value::asLocalDate); } @Test - void shouldReceiveDate() - { - testReceiveValue( "RETURN date({year: 1995, month: 12, day: 4})", - LocalDate.of( 1995, 12, 4 ), - Value::asLocalDate ); + void shouldReceiveDate() { + testReceiveValue("RETURN date({year: 1995, month: 12, day: 4})", LocalDate.of(1995, 12, 4), Value::asLocalDate); } @Test - void shouldSendAndReceiveDate() - { - testSendAndReceiveValue( LocalDate.now(), Value::asLocalDate ); + void shouldSendAndReceiveDate() { + testSendAndReceiveValue(LocalDate.now(), Value::asLocalDate); } @Test - void shouldSendAndReceiveRandomDate() - { - testSendAndReceiveRandomValues( TemporalUtil::randomLocalDate, Value::asLocalDate ); + void shouldSendAndReceiveRandomDate() { + testSendAndReceiveRandomValues(TemporalUtil::randomLocalDate, Value::asLocalDate); } @Test - void shouldSendAndReceiveListsWithRandomDates() - { - testSendAndReceiveRandomLists( TemporalUtil::randomLocalDate ); + void shouldSendAndReceiveListsWithRandomDates() { + testSendAndReceiveRandomLists(TemporalUtil::randomLocalDate); } @Test - void shouldSendTime() - { - testSendValue( OffsetTime.now(), Value::asOffsetTime ); + void shouldSendTime() { + testSendValue(OffsetTime.now(), Value::asOffsetTime); } @Test - void shouldReceiveTime() - { - testReceiveValue( "RETURN time({hour: 23, minute: 19, second: 55, timezone:'-07:00'})", - OffsetTime.of( 23, 19, 55, 0, ZoneOffset.ofHours( -7 ) ), - Value::asOffsetTime ); + void shouldReceiveTime() { + testReceiveValue( + "RETURN time({hour: 23, minute: 19, second: 55, timezone:'-07:00'})", + OffsetTime.of(23, 19, 55, 0, ZoneOffset.ofHours(-7)), + Value::asOffsetTime); } @Test - void shouldSendAndReceiveTime() - { - testSendAndReceiveValue( OffsetTime.now(), Value::asOffsetTime ); + void shouldSendAndReceiveTime() { + testSendAndReceiveValue(OffsetTime.now(), Value::asOffsetTime); } @Test - void shouldSendAndReceiveRandomTime() - { - testSendAndReceiveRandomValues( TemporalUtil::randomOffsetTime, Value::asOffsetTime ); + void shouldSendAndReceiveRandomTime() { + testSendAndReceiveRandomValues(TemporalUtil::randomOffsetTime, Value::asOffsetTime); } @Test - void shouldSendAndReceiveListsWithRandomTimes() - { - testSendAndReceiveRandomLists( TemporalUtil::randomOffsetTime ); + void shouldSendAndReceiveListsWithRandomTimes() { + testSendAndReceiveRandomLists(TemporalUtil::randomOffsetTime); } @Test - void shouldSendLocalTime() - { - testSendValue( LocalTime.now(), Value::asLocalTime ); + void shouldSendLocalTime() { + testSendValue(LocalTime.now(), Value::asLocalTime); } @Test - void shouldReceiveLocalTime() - { - testReceiveValue( "RETURN localtime({hour: 22, minute: 59, second: 10, nanosecond: 999999})", - LocalTime.of( 22, 59, 10, 999_999 ), - Value::asLocalTime ); + void shouldReceiveLocalTime() { + testReceiveValue( + "RETURN localtime({hour: 22, minute: 59, second: 10, nanosecond: 999999})", + LocalTime.of(22, 59, 10, 999_999), + Value::asLocalTime); } @Test - void shouldSendAndReceiveLocalTime() - { - testSendAndReceiveValue( LocalTime.now(), Value::asLocalTime ); + void shouldSendAndReceiveLocalTime() { + testSendAndReceiveValue(LocalTime.now(), Value::asLocalTime); } @Test - void shouldSendAndReceiveRandomLocalTime() - { - testSendAndReceiveRandomValues( TemporalUtil::randomLocalTime, Value::asLocalTime ); + void shouldSendAndReceiveRandomLocalTime() { + testSendAndReceiveRandomValues(TemporalUtil::randomLocalTime, Value::asLocalTime); } @Test - void shouldSendAndReceiveListsWithRandomLocalTimes() - { - testSendAndReceiveRandomLists( TemporalUtil::randomLocalTime ); + void shouldSendAndReceiveListsWithRandomLocalTimes() { + testSendAndReceiveRandomLists(TemporalUtil::randomLocalTime); } @Test - void shouldSendLocalDateTime() - { - testSendValue( LocalDateTime.now(), Value::asLocalDateTime ); + void shouldSendLocalDateTime() { + testSendValue(LocalDateTime.now(), Value::asLocalDateTime); } @Test - void shouldReceiveLocalDateTime() - { - testReceiveValue( "RETURN localdatetime({year: 1899, month: 3, day: 20, hour: 12, minute: 17, second: 13, nanosecond: 999})", - LocalDateTime.of( 1899, MARCH, 20, 12, 17, 13, 999 ), - Value::asLocalDateTime ); + void shouldReceiveLocalDateTime() { + testReceiveValue( + "RETURN localdatetime({year: 1899, month: 3, day: 20, hour: 12, minute: 17, second: 13, nanosecond: 999})", + LocalDateTime.of(1899, MARCH, 20, 12, 17, 13, 999), + Value::asLocalDateTime); } @Test - void shouldSendAndReceiveLocalDateTime() - { - testSendAndReceiveValue( LocalDateTime.now(), Value::asLocalDateTime ); + void shouldSendAndReceiveLocalDateTime() { + testSendAndReceiveValue(LocalDateTime.now(), Value::asLocalDateTime); } @Test - void shouldSendAndReceiveRandomLocalDateTime() - { - testSendAndReceiveRandomValues( TemporalUtil::randomLocalDateTime, Value::asLocalDateTime ); + void shouldSendAndReceiveRandomLocalDateTime() { + testSendAndReceiveRandomValues(TemporalUtil::randomLocalDateTime, Value::asLocalDateTime); } @Test - void shouldSendAndReceiveListsWithRandomLocalDateTimes() - { - testSendAndReceiveRandomLists( TemporalUtil::randomLocalDateTime ); + void shouldSendAndReceiveListsWithRandomLocalDateTimes() { + testSendAndReceiveRandomLists(TemporalUtil::randomLocalDateTime); } @Test - void shouldSendDateTimeWithZoneOffset() - { - ZoneOffset offset = ZoneOffset.ofHoursMinutes( -4, -15 ); - testSendValue( ZonedDateTime.of( 1845, 3, 25, 19, 15, 45, 22, offset ), Value::asZonedDateTime ); + void shouldSendDateTimeWithZoneOffset() { + ZoneOffset offset = ZoneOffset.ofHoursMinutes(-4, -15); + testSendValue(ZonedDateTime.of(1845, 3, 25, 19, 15, 45, 22, offset), Value::asZonedDateTime); } @Test - void shouldReceiveDateTimeWithZoneOffset() - { - ZoneOffset offset = ZoneOffset.ofHoursMinutes( 3, 30 ); - testReceiveValue( "RETURN datetime({year:1984, month:10, day:11, hour:21, minute:30, second:34, timezone:'+03:30'})", - ZonedDateTime.of( 1984, 10, 11, 21, 30, 34, 0, offset ), - Value::asZonedDateTime ); + void shouldReceiveDateTimeWithZoneOffset() { + ZoneOffset offset = ZoneOffset.ofHoursMinutes(3, 30); + testReceiveValue( + "RETURN datetime({year:1984, month:10, day:11, hour:21, minute:30, second:34, timezone:'+03:30'})", + ZonedDateTime.of(1984, 10, 11, 21, 30, 34, 0, offset), + Value::asZonedDateTime); } @Test - void shouldSendAndReceiveDateTimeWithZoneOffset() - { - ZoneOffset offset = ZoneOffset.ofHoursMinutes( -7, -15 ); - testSendAndReceiveValue( ZonedDateTime.of( 2017, 3, 9, 11, 12, 13, 14, offset ), Value::asZonedDateTime ); + void shouldSendAndReceiveDateTimeWithZoneOffset() { + ZoneOffset offset = ZoneOffset.ofHoursMinutes(-7, -15); + testSendAndReceiveValue(ZonedDateTime.of(2017, 3, 9, 11, 12, 13, 14, offset), Value::asZonedDateTime); } @Test - void shouldSendAndReceiveRandomDateTimeWithZoneOffset() - { - testSendAndReceiveRandomValues( TemporalUtil::randomZonedDateTimeWithOffset, Value::asZonedDateTime ); + void shouldSendAndReceiveRandomDateTimeWithZoneOffset() { + testSendAndReceiveRandomValues(TemporalUtil::randomZonedDateTimeWithOffset, Value::asZonedDateTime); } @Test - void shouldSendAndReceiveListsWithRandomDateTimeWithZoneOffsets() - { - testSendAndReceiveRandomLists( TemporalUtil::randomZonedDateTimeWithOffset ); + void shouldSendAndReceiveListsWithRandomDateTimeWithZoneOffsets() { + testSendAndReceiveRandomLists(TemporalUtil::randomZonedDateTimeWithOffset); } @Test - void shouldSendDateTimeRepresentedWithOffsetDateTime() - { - testSendValue( OffsetDateTime.of( 1851, 9, 29, 1, 29, 42, 987, ZoneOffset.ofHours( -8 ) ), Value::asOffsetDateTime ); + void shouldSendDateTimeRepresentedWithOffsetDateTime() { + testSendValue(OffsetDateTime.of(1851, 9, 29, 1, 29, 42, 987, ZoneOffset.ofHours(-8)), Value::asOffsetDateTime); } @Test - void shouldReceiveDateTimeRepresentedWithOffsetDateTime() - { - testReceiveValue( "RETURN datetime({year:2121, month:1, day:1, hour:2, minute:2, second:2, timezone:'-07:20'})", - OffsetDateTime.of( 2121, 1, 1, 2, 2, 2, 0, ZoneOffset.ofHoursMinutes( -7, -20 ) ), - Value::asOffsetDateTime ); + void shouldReceiveDateTimeRepresentedWithOffsetDateTime() { + testReceiveValue( + "RETURN datetime({year:2121, month:1, day:1, hour:2, minute:2, second:2, timezone:'-07:20'})", + OffsetDateTime.of(2121, 1, 1, 2, 2, 2, 0, ZoneOffset.ofHoursMinutes(-7, -20)), + Value::asOffsetDateTime); } @Test - void shouldSendAndReceiveDateTimeRepresentedWithOffsetDateTime() - { - testSendAndReceiveValue( OffsetDateTime.of( 1998, 12, 12, 23, 54, 14, 123, ZoneOffset.ofHoursMinutes( 1, 15 ) ), Value::asOffsetDateTime ); + void shouldSendAndReceiveDateTimeRepresentedWithOffsetDateTime() { + testSendAndReceiveValue( + OffsetDateTime.of(1998, 12, 12, 23, 54, 14, 123, ZoneOffset.ofHoursMinutes(1, 15)), + Value::asOffsetDateTime); } @Test - void shouldSendAndReceiveRandomDateTimeRepresentedWithOffsetDateTime() - { - testSendAndReceiveRandomValues( TemporalUtil::randomOffsetDateTime, Value::asOffsetDateTime ); + void shouldSendAndReceiveRandomDateTimeRepresentedWithOffsetDateTime() { + testSendAndReceiveRandomValues(TemporalUtil::randomOffsetDateTime, Value::asOffsetDateTime); } @Test - void shouldSendAndReceiveListsWithRandomDateTimeRepresentedWithOffsetDateTimes() - { - testSendAndReceiveRandomLists( TemporalUtil::randomOffsetDateTime, value -> value.asList( ofOffsetDateTime() ) ); + void shouldSendAndReceiveListsWithRandomDateTimeRepresentedWithOffsetDateTimes() { + testSendAndReceiveRandomLists(TemporalUtil::randomOffsetDateTime, value -> value.asList(ofOffsetDateTime())); } @Test - void shouldSendDateTimeWithZoneId() - { - ZoneId zoneId = ZoneId.of( "Europe/Stockholm" ); - testSendValue( ZonedDateTime.of( 2049, 9, 11, 19, 10, 40, 20, zoneId ), Value::asZonedDateTime ); + void shouldSendDateTimeWithZoneId() { + ZoneId zoneId = ZoneId.of("Europe/Stockholm"); + testSendValue(ZonedDateTime.of(2049, 9, 11, 19, 10, 40, 20, zoneId), Value::asZonedDateTime); } @Test - void shouldReceiveDateTimeWithZoneId() - { - ZoneId zoneId = ZoneId.of( "Europe/London" ); - testReceiveValue( "RETURN datetime({year:2000, month:1, day:1, hour:9, minute:5, second:1, timezone:'Europe/London'})", - ZonedDateTime.of( 2000, 1, 1, 9, 5, 1, 0, zoneId ), - Value::asZonedDateTime ); + void shouldReceiveDateTimeWithZoneId() { + ZoneId zoneId = ZoneId.of("Europe/London"); + testReceiveValue( + "RETURN datetime({year:2000, month:1, day:1, hour:9, minute:5, second:1, timezone:'Europe/London'})", + ZonedDateTime.of(2000, 1, 1, 9, 5, 1, 0, zoneId), + Value::asZonedDateTime); } @Test - void shouldSendAndReceiveDateTimeWithZoneId() - { - ZoneId zoneId = ZoneId.of( "Europe/Stockholm" ); - testSendAndReceiveValue( ZonedDateTime.of( 2099, 12, 29, 12, 59, 59, 59, zoneId ), Value::asZonedDateTime ); + void shouldSendAndReceiveDateTimeWithZoneId() { + ZoneId zoneId = ZoneId.of("Europe/Stockholm"); + testSendAndReceiveValue(ZonedDateTime.of(2099, 12, 29, 12, 59, 59, 59, zoneId), Value::asZonedDateTime); } @Test - void shouldSendAndReceiveRandomDateTimeWithZoneId() - { - testSendAndReceiveRandomValues( TemporalUtil::randomZonedDateTimeWithZoneId, Value::asZonedDateTime ); + void shouldSendAndReceiveRandomDateTimeWithZoneId() { + testSendAndReceiveRandomValues(TemporalUtil::randomZonedDateTimeWithZoneId, Value::asZonedDateTime); } @Test - void shouldSendAndReceiveListsWithRandomDateTimeWithZoneIds() - { - testSendAndReceiveRandomLists( TemporalUtil::randomZonedDateTimeWithZoneId ); + void shouldSendAndReceiveListsWithRandomDateTimeWithZoneIds() { + testSendAndReceiveRandomLists(TemporalUtil::randomZonedDateTimeWithZoneId); } @Test - void shouldSendDuration() - { - testSendValue( newDuration( 8, 12, 90, 8 ), Value::asIsoDuration ); + void shouldSendDuration() { + testSendValue(newDuration(8, 12, 90, 8), Value::asIsoDuration); } @Test - void shouldReceiveDuration() - { - testReceiveValue( "RETURN duration({months: 13, days: 40, seconds: 12, nanoseconds: 999})", - newDuration( 13, 40, 12, 999 ), - Value::asIsoDuration ); + void shouldReceiveDuration() { + testReceiveValue( + "RETURN duration({months: 13, days: 40, seconds: 12, nanoseconds: 999})", + newDuration(13, 40, 12, 999), + Value::asIsoDuration); } @Test - void shouldSendAndReceiveDuration() - { - testSendAndReceiveValue( newDuration( 7, 7, 88, 999_999 ), Value::asIsoDuration ); + void shouldSendAndReceiveDuration() { + testSendAndReceiveValue(newDuration(7, 7, 88, 999_999), Value::asIsoDuration); } @Test - void shouldSendAndReceiveRandomDuration() - { - testSendAndReceiveRandomValues( TemporalUtil::randomDuration, Value::asIsoDuration ); + void shouldSendAndReceiveRandomDuration() { + testSendAndReceiveRandomValues(TemporalUtil::randomDuration, Value::asIsoDuration); } @Test - void shouldSendAndReceiveListsWithRandomDurations() - { - testSendAndReceiveRandomLists( TemporalUtil::randomDuration ); + void shouldSendAndReceiveListsWithRandomDurations() { + testSendAndReceiveRandomLists(TemporalUtil::randomDuration); } @Test - void shouldFormatDurationToString() - { - testDurationToString( 1, 0, "P0M0DT1S" ); - testDurationToString( -1, 0, "P0M0DT-1S" ); + void shouldFormatDurationToString() { + testDurationToString(1, 0, "P0M0DT1S"); + testDurationToString(-1, 0, "P0M0DT-1S"); - testDurationToString( 0, 5, "P0M0DT0.000000005S" ); - testDurationToString( 0, -5, "P0M0DT-0.000000005S" ); - testDurationToString( 0, 999_999_999, "P0M0DT0.999999999S" ); - testDurationToString( 0, -999_999_999, "P0M0DT-0.999999999S" ); + testDurationToString(0, 5, "P0M0DT0.000000005S"); + testDurationToString(0, -5, "P0M0DT-0.000000005S"); + testDurationToString(0, 999_999_999, "P0M0DT0.999999999S"); + testDurationToString(0, -999_999_999, "P0M0DT-0.999999999S"); - testDurationToString( 1, 5, "P0M0DT1.000000005S" ); - testDurationToString( -1, -5, "P0M0DT-1.000000005S" ); - testDurationToString( 1, -5, "P0M0DT0.999999995S" ); - testDurationToString( -1, 5, "P0M0DT-0.999999995S" ); - testDurationToString( 1, 999999999, "P0M0DT1.999999999S" ); - testDurationToString( -1, -999999999, "P0M0DT-1.999999999S" ); - testDurationToString( 1, -999999999, "P0M0DT0.000000001S" ); - testDurationToString( -1, 999999999, "P0M0DT-0.000000001S" ); + testDurationToString(1, 5, "P0M0DT1.000000005S"); + testDurationToString(-1, -5, "P0M0DT-1.000000005S"); + testDurationToString(1, -5, "P0M0DT0.999999995S"); + testDurationToString(-1, 5, "P0M0DT-0.999999995S"); + testDurationToString(1, 999999999, "P0M0DT1.999999999S"); + testDurationToString(-1, -999999999, "P0M0DT-1.999999999S"); + testDurationToString(1, -999999999, "P0M0DT0.000000001S"); + testDurationToString(-1, 999999999, "P0M0DT-0.000000001S"); - testDurationToString( -78036, -143000000, "P0M0DT-78036.143000000S" ); + testDurationToString(-78036, -143000000, "P0M0DT-78036.143000000S"); - testDurationToString( 0, 1_000_000_000, "P0M0DT1S" ); - testDurationToString( 0, -1_000_000_000, "P0M0DT-1S" ); - testDurationToString( 0, 1_000_000_007, "P0M0DT1.000000007S" ); - testDurationToString( 0, -1_000_000_007, "P0M0DT-1.000000007S" ); + testDurationToString(0, 1_000_000_000, "P0M0DT1S"); + testDurationToString(0, -1_000_000_000, "P0M0DT-1S"); + testDurationToString(0, 1_000_000_007, "P0M0DT1.000000007S"); + testDurationToString(0, -1_000_000_007, "P0M0DT-1.000000007S"); - testDurationToString( 40, 2_123_456_789, "P0M0DT42.123456789S" ); - testDurationToString( -40, 2_123_456_789, "P0M0DT-37.876543211S" ); - testDurationToString( 40, -2_123_456_789, "P0M0DT37.876543211S" ); - testDurationToString( -40, -2_123_456_789, "P0M0DT-42.123456789S" ); + testDurationToString(40, 2_123_456_789, "P0M0DT42.123456789S"); + testDurationToString(-40, 2_123_456_789, "P0M0DT-37.876543211S"); + testDurationToString(40, -2_123_456_789, "P0M0DT37.876543211S"); + testDurationToString(-40, -2_123_456_789, "P0M0DT-42.123456789S"); } - private static void testSendAndReceiveRandomValues( Supplier valueSupplier, Function converter ) - { - for ( int i = 0; i < RANDOM_VALUES_TO_TEST; i++ ) - { - testSendAndReceiveValue( valueSupplier.get(), converter ); + private static void testSendAndReceiveRandomValues(Supplier valueSupplier, Function converter) { + for (int i = 0; i < RANDOM_VALUES_TO_TEST; i++) { + testSendAndReceiveValue(valueSupplier.get(), converter); } } - private static void testSendAndReceiveRandomLists( Supplier valueSupplier ) - { - testSendAndReceiveRandomLists( valueSupplier::get, Value::asList ); + private static void testSendAndReceiveRandomLists(Supplier valueSupplier) { + testSendAndReceiveRandomLists(valueSupplier::get, Value::asList); } - private static void testSendAndReceiveRandomLists( Supplier valueSupplier, Function> converter ) - { - for ( int i = 0; i < RANDOM_LISTS_TO_TEST; i++ ) - { - int listSize = ThreadLocalRandom.current().nextInt( MIN_LIST_SIZE, MAX_LIST_SIZE ); - List list = Stream.generate( valueSupplier ) - .limit( listSize ) - .collect( toList() ); + private static void testSendAndReceiveRandomLists( + Supplier valueSupplier, Function> converter) { + for (int i = 0; i < RANDOM_LISTS_TO_TEST; i++) { + int listSize = ThreadLocalRandom.current().nextInt(MIN_LIST_SIZE, MAX_LIST_SIZE); + List list = Stream.generate(valueSupplier).limit(listSize).collect(toList()); - testSendAndReceiveValue( list, converter ); + testSendAndReceiveValue(list, converter); } } - private static void testSendValue( T value, Function converter ) - { - Record record1 = session.run( "CREATE (n:Node {value: $value}) RETURN 42", singletonMap( "value", value ) ).single(); - assertEquals( 42, record1.get( 0 ).asInt() ); + private static void testSendValue(T value, Function converter) { + Record record1 = session.run("CREATE (n:Node {value: $value}) RETURN 42", singletonMap("value", value)) + .single(); + assertEquals(42, record1.get(0).asInt()); - Record record2 = session.run( "MATCH (n:Node) RETURN n.value" ).single(); - assertEquals( value, converter.apply( record2.get( 0 ) ) ); + Record record2 = session.run("MATCH (n:Node) RETURN n.value").single(); + assertEquals(value, converter.apply(record2.get(0))); } - private static void testReceiveValue( String query, T expectedValue, Function converter ) - { - Record record = session.run( query ).single(); - assertEquals( expectedValue, converter.apply( record.get( 0 ) ) ); + private static void testReceiveValue(String query, T expectedValue, Function converter) { + Record record = session.run(query).single(); + assertEquals(expectedValue, converter.apply(record.get(0))); } - private static void testSendAndReceiveValue( T value, Function converter ) - { - Record record = session.run( "CREATE (n:Node {value: $value}) RETURN n.value", singletonMap( "value", value ) ).single(); - assertEquals( value, converter.apply( record.get( 0 ) ) ); + private static void testSendAndReceiveValue(T value, Function converter) { + Record record = session.run("CREATE (n:Node {value: $value}) RETURN n.value", singletonMap("value", value)) + .single(); + assertEquals(value, converter.apply(record.get(0))); } - private static void testDurationToString( long seconds, int nanoseconds, String expectedValue ) - { - Result result = session.run( "RETURN duration({seconds: $s, nanoseconds: $n})", parameters( "s", seconds, "n", nanoseconds ) ); - IsoDuration duration = result.single().get( 0 ).asIsoDuration(); - assertEquals( expectedValue, duration.toString() ); + private static void testDurationToString(long seconds, int nanoseconds, String expectedValue) { + Result result = session.run( + "RETURN duration({seconds: $s, nanoseconds: $n})", parameters("s", seconds, "n", nanoseconds)); + IsoDuration duration = result.single().get(0).asIsoDuration(); + assertEquals(expectedValue, duration.toString()); } - private static IsoDuration newDuration( long months, long days, long seconds, int nanoseconds ) - { - return isoDuration( months, days, seconds, nanoseconds ).asIsoDuration(); + private static IsoDuration newDuration(long months, long days, long seconds, int nanoseconds) { + return isoDuration(months, days, seconds, nanoseconds).asIsoDuration(); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/TransactionBoltV3IT.java b/driver/src/test/java/org/neo4j/driver/integration/TransactionBoltV3IT.java index 80a1c3a8a0..7625de9d95 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/TransactionBoltV3IT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/TransactionBoltV3IT.java @@ -18,16 +18,25 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.time.Duration.ofMillis; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; +import static org.junit.jupiter.api.Assertions.fail; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V3; +import static org.neo4j.driver.util.TestUtil.TX_TIMEOUT_TEST_TIMEOUT; +import static org.neo4j.driver.util.TestUtil.await; import java.time.ZonedDateTime; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletionStage; - -import org.neo4j.driver.Session; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.Value; @@ -40,169 +49,133 @@ import org.neo4j.driver.util.DriverExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.time.Duration.ofMillis; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; -import static org.junit.jupiter.api.Assertions.fail; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V3; -import static org.neo4j.driver.util.TestUtil.TX_TIMEOUT_TEST_TIMEOUT; -import static org.neo4j.driver.util.TestUtil.await; - -@EnabledOnNeo4jWith( BOLT_V3 ) +@EnabledOnNeo4jWith(BOLT_V3) @ParallelizableIT -class TransactionBoltV3IT -{ +class TransactionBoltV3IT { @RegisterExtension static final DriverExtension driver = new DriverExtension(); @Test - void shouldSetTransactionMetadata() - { - Map metadata = new HashMap<>(); - metadata.put( "key1", "value1" ); - metadata.put( "key2", 42L ); - metadata.put( "key3", false ); - - TransactionConfig config = TransactionConfig.builder() - .withMetadata( metadata ) - .build(); - - try ( Transaction tx = driver.session().beginTransaction( config ) ) - { - tx.run( "RETURN 1" ).consume(); - - verifyTransactionMetadata( metadata ); + void shouldSetTransactionMetadata() { + Map metadata = new HashMap<>(); + metadata.put("key1", "value1"); + metadata.put("key2", 42L); + metadata.put("key3", false); + + TransactionConfig config = + TransactionConfig.builder().withMetadata(metadata).build(); + + try (Transaction tx = driver.session().beginTransaction(config)) { + tx.run("RETURN 1").consume(); + + verifyTransactionMetadata(metadata); } } @Test - void shouldSetTransactionMetadataAsync() - { - Map metadata = new HashMap<>(); - metadata.put( "hello", "world" ); - metadata.put( "key", ZonedDateTime.now() ); - - TransactionConfig config = TransactionConfig.builder() - .withMetadata( metadata ) - .build(); - - CompletionStage txFuture = driver.asyncSession().beginTransactionAsync( config ) - .thenCompose( tx -> tx.runAsync( "RETURN 1" ) - .thenCompose( ResultCursor::consumeAsync ) - .thenApply( ignore -> tx ) ); - - AsyncTransaction transaction = await( txFuture ); - try - { - verifyTransactionMetadata( metadata ); - } - finally - { - await( transaction.rollbackAsync() ); + void shouldSetTransactionMetadataAsync() { + Map metadata = new HashMap<>(); + metadata.put("hello", "world"); + metadata.put("key", ZonedDateTime.now()); + + TransactionConfig config = + TransactionConfig.builder().withMetadata(metadata).build(); + + CompletionStage txFuture = driver.asyncSession() + .beginTransactionAsync(config) + .thenCompose(tx -> tx.runAsync("RETURN 1") + .thenCompose(ResultCursor::consumeAsync) + .thenApply(ignore -> tx)); + + AsyncTransaction transaction = await(txFuture); + try { + verifyTransactionMetadata(metadata); + } finally { + await(transaction.rollbackAsync()); } } @Test - void shouldSetTransactionTimeout() - { + void shouldSetTransactionTimeout() { // create a dummy node Session session = driver.session(); - session.run( "CREATE (:Node)" ).consume(); + session.run("CREATE (:Node)").consume(); - try ( Session otherSession = driver.driver().session() ) - { - try ( Transaction otherTx = otherSession.beginTransaction() ) - { + try (Session otherSession = driver.driver().session()) { + try (Transaction otherTx = otherSession.beginTransaction()) { // lock dummy node but keep the transaction open - otherTx.run( "MATCH (n:Node) SET n.prop = 1" ).consume(); + otherTx.run("MATCH (n:Node) SET n.prop = 1").consume(); - assertTimeoutPreemptively( TX_TIMEOUT_TEST_TIMEOUT, () -> { - TransactionConfig config = TransactionConfig.builder() - .withTimeout( ofMillis( 1 ) ) - .build(); + assertTimeoutPreemptively(TX_TIMEOUT_TEST_TIMEOUT, () -> { + TransactionConfig config = + TransactionConfig.builder().withTimeout(ofMillis(1)).build(); // start a new transaction with timeout and try to update the locked dummy node - Exception error = assertThrows( Exception.class, () -> - { - try ( Transaction tx = session.beginTransaction( config ) ) - { - tx.run( "MATCH (n:Node) SET n.prop = 2" ); + Exception error = assertThrows(Exception.class, () -> { + try (Transaction tx = session.beginTransaction(config)) { + tx.run("MATCH (n:Node) SET n.prop = 2"); tx.commit(); } - } ); + }); - verifyValidException( error ); - } ); + verifyValidException(error); + }); } } } @Test - void shouldSetTransactionTimeoutAsync() - { + void shouldSetTransactionTimeoutAsync() { // create a dummy node Session session = driver.session(); AsyncSession asyncSession = driver.asyncSession(); - session.run( "CREATE (:Node)" ).consume(); + session.run("CREATE (:Node)").consume(); - try ( Session otherSession = driver.driver().session() ) - { - try ( Transaction otherTx = otherSession.beginTransaction() ) - { + try (Session otherSession = driver.driver().session()) { + try (Transaction otherTx = otherSession.beginTransaction()) { // lock dummy node but keep the transaction open - otherTx.run( "MATCH (n:Node) SET n.prop = 1" ).consume(); + otherTx.run("MATCH (n:Node) SET n.prop = 1").consume(); - assertTimeoutPreemptively( TX_TIMEOUT_TEST_TIMEOUT, () -> { - TransactionConfig config = TransactionConfig.builder() - .withTimeout( ofMillis( 1 ) ) - .build(); + assertTimeoutPreemptively(TX_TIMEOUT_TEST_TIMEOUT, () -> { + TransactionConfig config = + TransactionConfig.builder().withTimeout(ofMillis(1)).build(); // start a new transaction with timeout and try to update the locked dummy node - CompletionStage txCommitFuture = asyncSession.beginTransactionAsync( config ) - .thenCompose( tx -> tx.runAsync( "MATCH (n:Node) SET n.prop = 2" ) - .thenCompose( ignore -> tx.commitAsync() ) ); + CompletionStage txCommitFuture = asyncSession + .beginTransactionAsync(config) + .thenCompose(tx -> tx.runAsync("MATCH (n:Node) SET n.prop = 2") + .thenCompose(ignore -> tx.commitAsync())); - Exception error = assertThrows( Exception.class, () -> await( txCommitFuture ) ); + Exception error = assertThrows(Exception.class, () -> await(txCommitFuture)); - verifyValidException( error ); - } ); + verifyValidException(error); + }); } } } - - private static void verifyValidException( Exception error ) - { + private static void verifyValidException(Exception error) { // Server 4.1 corrected this exception to ClientException. Testing either here for compatibility - if ( error instanceof TransientException || error instanceof ClientException ) - { - assertThat( error.getMessage(), containsString( "terminated" ) ); - } - else - { - fail( "Expected either a TransientException or ClientException", error ); + if (error instanceof TransientException || error instanceof ClientException) { + assertThat(error.getMessage(), containsString("terminated")); + } else { + fail("Expected either a TransientException or ClientException", error); } } - private static void verifyTransactionMetadata( Map metadata ) - { - try ( Session session = driver.driver().session() ) - { - Result result = session.run( "CALL dbms.listTransactions()" ); - - Map receivedMetadata = result.list() - .stream() - .map( record -> record.get( "metaData" ) ) - .map( Value::asMap ) - .filter( map -> !map.isEmpty() ) + private static void verifyTransactionMetadata(Map metadata) { + try (Session session = driver.driver().session()) { + Result result = session.run("CALL dbms.listTransactions()"); + + Map receivedMetadata = result.list().stream() + .map(record -> record.get("metaData")) + .map(Value::asMap) + .filter(map -> !map.isEmpty()) .findFirst() - .orElseThrow( IllegalStateException::new ); + .orElseThrow(IllegalStateException::new); - assertEquals( metadata, receivedMetadata ); + assertEquals(metadata, receivedMetadata); } } } 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 f11c7ec4d0..ea1c0b3611 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/TransactionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/TransactionIT.java @@ -18,14 +18,25 @@ */ package org.neo4j.driver.integration; -import io.netty.channel.Channel; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.retry.RetrySettings.DEFAULT; +import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; +import io.netty.channel.Channel; import java.util.List; import java.util.Map; import java.util.function.Consumer; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; @@ -43,239 +54,198 @@ import org.neo4j.driver.util.SessionExtension; import org.neo4j.driver.util.TestUtil; -import static java.util.Arrays.asList; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.retry.RetrySettings.DEFAULT; -import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; - @ParallelizableIT -class TransactionIT -{ +class TransactionIT { @RegisterExtension static final SessionExtension session = new SessionExtension(); @Test - void shouldAllowRunRollbackAndClose() - { - shouldRunAndCloseAfterAction( Transaction::rollback, false ); + void shouldAllowRunRollbackAndClose() { + shouldRunAndCloseAfterAction(Transaction::rollback, false); } @Test - void shouldAllowRunCommitAndClose() - { - shouldRunAndCloseAfterAction( Transaction::commit, true ); + void shouldAllowRunCommitAndClose() { + shouldRunAndCloseAfterAction(Transaction::commit, true); } @Test - void shouldAllowRunCloseAndClose() - { - shouldRunAndCloseAfterAction( Transaction::close, false ); + void shouldAllowRunCloseAndClose() { + shouldRunAndCloseAfterAction(Transaction::close, false); } @Test - void shouldRunAndRollbackByDefault() - { + void shouldRunAndRollbackByDefault() { // When - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "CREATE (n:FirstNode)" ); - tx.run( "CREATE (n:SecondNode)" ); + try (Transaction tx = session.beginTransaction()) { + tx.run("CREATE (n:FirstNode)"); + tx.run("CREATE (n:SecondNode)"); } // Then there should be no visible effect of the transaction - Result cursor = session.run( "MATCH (n) RETURN count(n)" ); - long nodes = cursor.single().get( "count(n)" ).asLong(); - assertThat( nodes, equalTo( 0L ) ); + Result cursor = session.run("MATCH (n) RETURN count(n)"); + long nodes = cursor.single().get("count(n)").asLong(); + assertThat(nodes, equalTo(0L)); } @Test - void shouldRetrieveResults() - { + void shouldRetrieveResults() { // Given - session.run( "CREATE (n {name:'Steve Brook'})" ); + session.run("CREATE (n {name:'Steve Brook'})"); // When - try ( Transaction tx = session.beginTransaction() ) - { - Result res = tx.run( "MATCH (n) RETURN n.name" ); + try (Transaction tx = session.beginTransaction()) { + Result res = tx.run("MATCH (n) RETURN n.name"); // Then - assertThat( res.single().get( "n.name" ).asString(), equalTo( "Steve Brook" ) ); + assertThat(res.single().get("n.name").asString(), equalTo("Steve Brook")); } } @Test - void shouldNotAllowSessionLevelQueriesWhenThereIsATransaction() - { + void shouldNotAllowSessionLevelQueriesWhenThereIsATransaction() { session.beginTransaction(); - assertThrows( ClientException.class, () -> session.run( "anything" ) ); + assertThrows(ClientException.class, () -> session.run("anything")); } @Test - void shouldFailToRunQueryAfterTxIsCommitted() - { - shouldFailToRunQueryAfterTxAction( Transaction::commit ); + void shouldFailToRunQueryAfterTxIsCommitted() { + shouldFailToRunQueryAfterTxAction(Transaction::commit); } @Test - void shouldFailToRunQueryAfterTxIsRolledBack() - { - shouldFailToRunQueryAfterTxAction( Transaction::rollback ); + void shouldFailToRunQueryAfterTxIsRolledBack() { + shouldFailToRunQueryAfterTxAction(Transaction::rollback); } @Test - void shouldFailToRunQueryAfterTxIsClosed() - { - shouldFailToRunQueryAfterTxAction( Transaction::close ); + void shouldFailToRunQueryAfterTxIsClosed() { + shouldFailToRunQueryAfterTxAction(Transaction::close); } @Test - void shouldFailToCommitAfterRolledBack() - { + void shouldFailToCommitAfterRolledBack() { Transaction tx = session.beginTransaction(); - tx.run( "CREATE (:MyLabel)" ); + tx.run("CREATE (:MyLabel)"); tx.rollback(); - ClientException e = assertThrows( ClientException.class, tx::commit ); - assertThat( e.getMessage(), startsWith( "Can't commit, transaction has been rolled back" ) ); + ClientException e = assertThrows(ClientException.class, tx::commit); + assertThat(e.getMessage(), startsWith("Can't commit, transaction has been rolled back")); } @Test - void shouldFailToRollbackAfterTxIsCommitted() - { + void shouldFailToRollbackAfterTxIsCommitted() { Transaction tx = session.beginTransaction(); - tx.run( "CREATE (:MyLabel)" ); + tx.run("CREATE (:MyLabel)"); tx.commit(); - ClientException e = assertThrows( ClientException.class, tx::rollback ); - assertThat( e.getMessage(), startsWith( "Can't rollback, transaction has been committed" ) ); + ClientException e = assertThrows(ClientException.class, tx::rollback); + assertThat(e.getMessage(), startsWith("Can't rollback, transaction has been committed")); } @Test - void shouldFailToCommitAfterCommit() throws Throwable - { + void shouldFailToCommitAfterCommit() throws Throwable { Transaction tx = session.beginTransaction(); - tx.run( "CREATE (:MyLabel)" ); + tx.run("CREATE (:MyLabel)"); tx.commit(); - ClientException e = assertThrows( ClientException.class, tx::commit ); - assertThat( e.getMessage(), startsWith( "Can't commit, transaction has been committed" ) ); + ClientException e = assertThrows(ClientException.class, tx::commit); + assertThat(e.getMessage(), startsWith("Can't commit, transaction has been committed")); } @Test - void shouldFailToRollbackAfterRollback() throws Throwable - { + void shouldFailToRollbackAfterRollback() throws Throwable { Transaction tx = session.beginTransaction(); - tx.run( "CREATE (:MyLabel)" ); + tx.run("CREATE (:MyLabel)"); tx.rollback(); - ClientException e = assertThrows( ClientException.class, tx::rollback ); - assertThat( e.getMessage(), startsWith( "Can't rollback, transaction has been rolled back" ) ); + ClientException e = assertThrows(ClientException.class, tx::rollback); + assertThat(e.getMessage(), startsWith("Can't rollback, transaction has been rolled back")); } - @Test - void shouldBeClosedAfterClose() - { - shouldBeClosedAfterAction( Transaction::close ); + void shouldBeClosedAfterClose() { + shouldBeClosedAfterAction(Transaction::close); } @Test - void shouldBeClosedAfterRollback() - { - shouldBeClosedAfterAction( Transaction::rollback ); + void shouldBeClosedAfterRollback() { + shouldBeClosedAfterAction(Transaction::rollback); } @Test - void shouldBeClosedAfterCommit() - { - shouldBeClosedAfterAction( Transaction::commit ); + void shouldBeClosedAfterCommit() { + shouldBeClosedAfterAction(Transaction::commit); } @Test - void shouldBeOpenBeforeCommit() - { + void shouldBeOpenBeforeCommit() { // When Transaction tx = session.beginTransaction(); // Then - assertTrue( tx.isOpen() ); + assertTrue(tx.isOpen()); } @Test - void shouldHandleNullParametersGracefully() - { + void shouldHandleNullParametersGracefully() { // When - session.run( "match (n) return count(n)", (Value) null ); + session.run("match (n) return count(n)", (Value) null); // Then // pass - no exception thrown } - //See GH #146 + // See GH #146 @Test - void shouldHandleFailureAfterClosingTransaction() - { + void shouldHandleFailureAfterClosingTransaction() { // GIVEN a successful query in a transaction Transaction tx = session.beginTransaction(); - Result result = tx.run( "CREATE (n) RETURN n" ); + Result result = tx.run("CREATE (n) RETURN n"); result.consume(); tx.commit(); tx.close(); // WHEN when running a malformed query in the original session - assertThrows( ClientException.class, () -> session.run( "CREAT (n) RETURN n" ).consume() ); + assertThrows( + ClientException.class, () -> session.run("CREAT (n) RETURN n").consume()); } - @SuppressWarnings( "ConstantConditions" ) + @SuppressWarnings("ConstantConditions") @Test - void shouldHandleNullRecordParameters() - { + void shouldHandleNullRecordParameters() { // When - try ( Transaction tx = session.beginTransaction() ) - { + try (Transaction tx = session.beginTransaction()) { Record params = null; - tx.run( "CREATE (n:FirstNode)", params ); + tx.run("CREATE (n:FirstNode)", params); tx.commit(); } // Then it wasn't the end of the world as we know it } - @SuppressWarnings( "ConstantConditions" ) + @SuppressWarnings("ConstantConditions") @Test - void shouldHandleNullValueParameters() - { + void shouldHandleNullValueParameters() { // When - try ( Transaction tx = session.beginTransaction() ) - { + try (Transaction tx = session.beginTransaction()) { Value params = null; - tx.run( "CREATE (n:FirstNode)", params ); + tx.run("CREATE (n:FirstNode)", params); tx.commit(); } // Then it wasn't the end of the world as we know it } - @SuppressWarnings( "ConstantConditions" ) + @SuppressWarnings("ConstantConditions") @Test - void shouldHandleNullMapParameters() - { + void shouldHandleNullMapParameters() { // When - try ( Transaction tx = session.beginTransaction() ) - { - Map params = null; - tx.run( "CREATE (n:FirstNode)", params ); + try (Transaction tx = session.beginTransaction()) { + Map params = null; + tx.run("CREATE (n:FirstNode)", params); tx.commit(); } @@ -283,78 +253,67 @@ void shouldHandleNullMapParameters() } @Test - void shouldRollbackTransactionAfterFailedRunAndCommitAndSessionShouldSuccessfullyBeginNewTransaction() - { + void shouldRollbackTransactionAfterFailedRunAndCommitAndSessionShouldSuccessfullyBeginNewTransaction() { // Given Transaction tx = session.beginTransaction(); - assertThrows( ClientException.class, () -> tx.run( "invalid" ) ); // send run, pull_all - ClientException e = assertThrows( ClientException.class, tx::commit ); - assertNoCircularReferences( e ); - try ( Transaction anotherTx = session.beginTransaction() ) - { - Result cursor = anotherTx.run( "RETURN 1" ); - int val = cursor.single().get( "1" ).asInt(); - assertThat( val, equalTo( 1 ) ); + assertThrows(ClientException.class, () -> tx.run("invalid")); // send run, pull_all + ClientException e = assertThrows(ClientException.class, tx::commit); + assertNoCircularReferences(e); + try (Transaction anotherTx = session.beginTransaction()) { + Result cursor = anotherTx.run("RETURN 1"); + int val = cursor.single().get("1").asInt(); + assertThat(val, equalTo(1)); } } @Test - void shouldRollBackTxIfErrorWithConsume() - { - assertThrows( ClientException.class, () -> - { - try ( Transaction tx = session.beginTransaction() ) - { - Result result = tx.run( "invalid" ); + void shouldRollBackTxIfErrorWithConsume() { + assertThrows(ClientException.class, () -> { + try (Transaction tx = session.beginTransaction()) { + Result result = tx.run("invalid"); result.consume(); } - } ); + }); - try ( Transaction tx = session.beginTransaction() ) - { - Result cursor = tx.run( "RETURN 1" ); - int val = cursor.single().get( "1" ).asInt(); - assertThat( val, equalTo( 1 ) ); + try (Transaction tx = session.beginTransaction()) { + Result cursor = tx.run("RETURN 1"); + int val = cursor.single().get("1").asInt(); + assertThat(val, equalTo(1)); } } @Test - void shouldFailRun() - { - try ( Transaction tx = session.beginTransaction() ) - { - ClientException e = assertThrows( ClientException.class, () -> tx.run( "RETURN Wrong" ) ); + void shouldFailRun() { + try (Transaction tx = session.beginTransaction()) { + ClientException e = assertThrows(ClientException.class, () -> tx.run("RETURN Wrong")); - assertThat( e.code(), containsString( "SyntaxError" ) ); + assertThat(e.code(), containsString("SyntaxError")); } } @Test - void shouldBeResponsiveToThreadInterruptWhenWaitingForResult() - { - try ( Session otherSession = session.driver().session() ) - { - session.run( "CREATE (:Person {name: 'Beta Ray Bill'})" ).consume(); + void shouldBeResponsiveToThreadInterruptWhenWaitingForResult() { + try (Session otherSession = session.driver().session()) { + session.run("CREATE (:Person {name: 'Beta Ray Bill'})").consume(); Transaction tx1 = session.beginTransaction(); Transaction tx2 = otherSession.beginTransaction(); - tx1.run( "MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Mjolnir'" ).consume(); + tx1.run("MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Mjolnir'") + .consume(); // now 'Beta Ray Bill' node is locked // setup other thread to interrupt current thread when it blocks - TestUtil.interruptWhenInWaitingState( Thread.currentThread() ); - - try - { - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, - () -> tx2.run( "MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Stormbreaker'" ).consume() ); - assertThat( e.getMessage(), containsString( "Connection to the database terminated" ) ); - assertThat( e.getMessage(), containsString( "Thread interrupted while running query in transaction" ) ); - } - finally - { + TestUtil.interruptWhenInWaitingState(Thread.currentThread()); + + try { + ServiceUnavailableException e = assertThrows(ServiceUnavailableException.class, () -> tx2.run( + "MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Stormbreaker'") + .consume()); + assertThat(e.getMessage(), containsString("Connection to the database terminated")); + assertThat(e.getMessage(), containsString("Thread interrupted while running query in transaction")); + } finally { // clear interrupted flag Thread.interrupted(); } @@ -362,27 +321,25 @@ void shouldBeResponsiveToThreadInterruptWhenWaitingForResult() } @Test - void shouldBeResponsiveToThreadInterruptWhenWaitingForCommit() - { - try ( Session otherSession = session.driver().session() ) - { - session.run( "CREATE (:Person {name: 'Beta Ray Bill'})" ).consume(); + void shouldBeResponsiveToThreadInterruptWhenWaitingForCommit() { + try (Session otherSession = session.driver().session()) { + session.run("CREATE (:Person {name: 'Beta Ray Bill'})").consume(); Transaction tx1 = session.beginTransaction(); Transaction tx2 = otherSession.beginTransaction(); - tx1.run( "MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Mjolnir'" ).consume(); + tx1.run("MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Mjolnir'") + .consume(); // now 'Beta Ray Bill' node is locked // setup other thread to interrupt current thread when it blocks - TestUtil.interruptWhenInWaitingState( Thread.currentThread() ); + TestUtil.interruptWhenInWaitingState(Thread.currentThread()); - try - { - assertThrows( ServiceUnavailableException.class, () -> tx2.run( "MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Stormbreaker'" ) ); - } - finally - { + try { + assertThrows( + ServiceUnavailableException.class, + () -> tx2.run("MATCH (n:Person {name: 'Beta Ray Bill'}) SET n.hammer = 'Stormbreaker'")); + } finally { // clear interrupted flag Thread.interrupted(); } @@ -390,140 +347,140 @@ void shouldBeResponsiveToThreadInterruptWhenWaitingForCommit() } @Test - void shouldThrowWhenConnectionKilledDuringTransaction() - { - ChannelTrackingDriverFactory factory = new ChannelTrackingDriverFactory( 1, Clock.SYSTEM ); - Config config = Config.builder().withLogging( DEV_NULL_LOGGING ).build(); - - try ( Driver driver = factory.newInstance( session.uri(), session.authToken(), RoutingSettings.DEFAULT, DEFAULT, config, SecurityPlanImpl.insecure() ) ) - { - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, () -> - { - try ( Session session1 = driver.session(); - Transaction tx = session1.beginTransaction() ) - { - tx.run( "CREATE (:MyNode {id: 1})" ).consume(); + void shouldThrowWhenConnectionKilledDuringTransaction() { + ChannelTrackingDriverFactory factory = new ChannelTrackingDriverFactory(1, Clock.SYSTEM); + Config config = Config.builder().withLogging(DEV_NULL_LOGGING).build(); + + try (Driver driver = factory.newInstance( + session.uri(), + session.authToken(), + RoutingSettings.DEFAULT, + DEFAULT, + config, + SecurityPlanImpl.insecure())) { + ServiceUnavailableException e = assertThrows(ServiceUnavailableException.class, () -> { + try (Session session1 = driver.session(); + Transaction tx = session1.beginTransaction()) { + tx.run("CREATE (:MyNode {id: 1})").consume(); // kill all network channels - for ( Channel channel: factory.channels() ) - { + for (Channel channel : factory.channels()) { channel.close().syncUninterruptibly(); } - tx.run( "CREATE (:MyNode {id: 1})" ).consume(); + tx.run("CREATE (:MyNode {id: 1})").consume(); } - } ); + }); - assertThat( e.getMessage(), containsString( "Connection to the database terminated" ) ); + assertThat(e.getMessage(), containsString("Connection to the database terminated")); } - assertEquals( 0, session.run( "MATCH (n:MyNode {id: 1}) RETURN count(n)" ).single().get( 0 ).asInt() ); + assertEquals( + 0, + session.run("MATCH (n:MyNode {id: 1}) RETURN count(n)") + .single() + .get(0) + .asInt()); } @Test - void shouldFailToCommitAfterFailure() throws Throwable - { - try ( Transaction tx = session.beginTransaction() ) - { - List xs = tx.run( "UNWIND [1,2,3] AS x CREATE (:Node) RETURN x" ).list( record -> record.get( 0 ).asInt() ); - assertEquals( asList( 1, 2, 3 ), xs ); - - ClientException error1 = assertThrows( ClientException.class, () -> tx.run( "RETURN unknown" ).consume() ); - assertThat( error1.code(), containsString( "SyntaxError" ) ); - - ClientException error2 = assertThrows( ClientException.class, tx::commit ); - assertThat( error2.getMessage(), startsWith( "Transaction can't be committed. It has been rolled back" ) ); + void shouldFailToCommitAfterFailure() throws Throwable { + try (Transaction tx = session.beginTransaction()) { + List xs = tx.run("UNWIND [1,2,3] AS x CREATE (:Node) RETURN x") + .list(record -> record.get(0).asInt()); + assertEquals(asList(1, 2, 3), xs); + + ClientException error1 = assertThrows( + ClientException.class, () -> tx.run("RETURN unknown").consume()); + assertThat(error1.code(), containsString("SyntaxError")); + + ClientException error2 = assertThrows(ClientException.class, tx::commit); + assertThat(error2.getMessage(), startsWith("Transaction can't be committed. It has been rolled back")); } } @Test - void shouldDisallowQueriesAfterFailureWhenResultsAreConsumed() - { - try ( Transaction tx = session.beginTransaction() ) - { - List xs = tx.run( "UNWIND [1,2,3] AS x CREATE (:Node) RETURN x" ).list( record -> record.get( 0 ).asInt() ); - assertEquals( asList( 1, 2, 3 ), xs ); - - ClientException error1 = assertThrows( ClientException.class, () -> tx.run( "RETURN unknown" ).consume() ); - assertThat( error1.code(), containsString( "SyntaxError" ) ); - - ClientException error2 = assertThrows( ClientException.class, () -> tx.run( "CREATE (:OtherNode)" ).consume() ); - assertThat( error2.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); - - ClientException error3 = assertThrows( ClientException.class, () -> tx.run( "RETURN 42" ).consume() ); - assertThat( error3.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); + void shouldDisallowQueriesAfterFailureWhenResultsAreConsumed() { + try (Transaction tx = session.beginTransaction()) { + List xs = tx.run("UNWIND [1,2,3] AS x CREATE (:Node) RETURN x") + .list(record -> record.get(0).asInt()); + assertEquals(asList(1, 2, 3), xs); + + ClientException error1 = assertThrows( + ClientException.class, () -> tx.run("RETURN unknown").consume()); + assertThat(error1.code(), containsString("SyntaxError")); + + ClientException error2 = assertThrows( + ClientException.class, () -> tx.run("CREATE (:OtherNode)").consume()); + assertThat(error2.getMessage(), startsWith("Cannot run more queries in this transaction")); + + ClientException error3 = assertThrows( + ClientException.class, () -> tx.run("RETURN 42").consume()); + assertThat(error3.getMessage(), startsWith("Cannot run more queries in this transaction")); } - assertEquals( 0, countNodesByLabel( "Node" ) ); - assertEquals( 0, countNodesByLabel( "OtherNode" ) ); + assertEquals(0, countNodesByLabel("Node")); + assertEquals(0, countNodesByLabel("OtherNode")); } @Test - void shouldRollbackWhenOneOfQueriesFails() - { - ClientException error = assertThrows( ClientException.class, () -> - { - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "CREATE (:Node1)" ); - tx.run( "CREATE (:Node2)" ); - tx.run( "CREATE SmthStrange" ); + void shouldRollbackWhenOneOfQueriesFails() { + ClientException error = assertThrows(ClientException.class, () -> { + try (Transaction tx = session.beginTransaction()) { + tx.run("CREATE (:Node1)"); + tx.run("CREATE (:Node2)"); + tx.run("CREATE SmthStrange"); } - } ); + }); - assertThat( error.code(), containsString( "SyntaxError" ) ); + assertThat(error.code(), containsString("SyntaxError")); - assertEquals( 0, countNodesByLabel( "Node1" ) ); - assertEquals( 0, countNodesByLabel( "Node2" ) ); - assertEquals( 0, countNodesByLabel( "Node3" ) ); - assertEquals( 0, countNodesByLabel( "Node4" ) ); + assertEquals(0, countNodesByLabel("Node1")); + assertEquals(0, countNodesByLabel("Node2")); + assertEquals(0, countNodesByLabel("Node3")); + assertEquals(0, countNodesByLabel("Node4")); } - private void shouldRunAndCloseAfterAction( Consumer txConsumer, boolean isCommit ) - { + private void shouldRunAndCloseAfterAction(Consumer txConsumer, boolean isCommit) { // When - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "CREATE (n:FirstNode)" ); - tx.run( "CREATE (n:SecondNode)" ); - txConsumer.accept( tx ); + try (Transaction tx = session.beginTransaction()) { + tx.run("CREATE (n:FirstNode)"); + tx.run("CREATE (n:SecondNode)"); + txConsumer.accept(tx); } // Then the outcome of both queries should be visible - Result result = session.run( "MATCH (n) RETURN count(n)" ); - long nodes = result.single().get( "count(n)" ).asLong(); - if (isCommit) - { - assertThat( nodes, equalTo( 2L ) ); - } - else - { - assertThat( nodes, equalTo( 0L ) ); + Result result = session.run("MATCH (n) RETURN count(n)"); + long nodes = result.single().get("count(n)").asLong(); + if (isCommit) { + assertThat(nodes, equalTo(2L)); + } else { + assertThat(nodes, equalTo(0L)); } } - private void shouldBeClosedAfterAction( Consumer txConsumer ) - { + private void shouldBeClosedAfterAction(Consumer txConsumer) { // When Transaction tx = session.beginTransaction(); - txConsumer.accept( tx ); + txConsumer.accept(tx); // Then - assertFalse( tx.isOpen() ); + assertFalse(tx.isOpen()); } - private void shouldFailToRunQueryAfterTxAction( Consumer txConsumer ) - { + private void shouldFailToRunQueryAfterTxAction(Consumer txConsumer) { Transaction tx = session.beginTransaction(); - tx.run( "CREATE (:MyLabel)" ); - txConsumer.accept( tx ); + tx.run("CREATE (:MyLabel)"); + txConsumer.accept(tx); - ClientException e = assertThrows( ClientException.class, () -> tx.run( "CREATE (:MyOtherLabel)" ) ); - assertThat( e.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); + ClientException e = assertThrows(ClientException.class, () -> tx.run("CREATE (:MyOtherLabel)")); + assertThat(e.getMessage(), startsWith("Cannot run more queries in this transaction")); } - private static int countNodesByLabel( String label ) - { - return session.run( "MATCH (n:" + label + ") RETURN count(n)" ).single().get( 0 ).asInt(); + private static int countNodesByLabel(String label) { + return session.run("MATCH (n:" + label + ") RETURN count(n)") + .single() + .get(0) + .asInt(); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/TrustCustomCertificateIT.java b/driver/src/test/java/org/neo4j/driver/integration/TrustCustomCertificateIT.java index 9d7ec61623..ca592292ab 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/TrustCustomCertificateIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/TrustCustomCertificateIT.java @@ -18,12 +18,17 @@ */ package org.neo4j.driver.integration; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.Config.TrustStrategy.trustCustomCertificateSignedBy; +import static org.neo4j.driver.util.CertificateUtil.createNewCertificateAndKey; +import static org.neo4j.driver.util.CertificateUtil.createNewCertificateAndKeySignedBy; import java.io.File; import java.util.function.Supplier; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; @@ -35,62 +40,54 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.Config.TrustStrategy.trustCustomCertificateSignedBy; -import static org.neo4j.driver.util.CertificateUtil.createNewCertificateAndKey; -import static org.neo4j.driver.util.CertificateUtil.createNewCertificateAndKeySignedBy; - @ParallelizableIT -class TrustCustomCertificateIT -{ +class TrustCustomCertificateIT { @RegisterExtension static final DatabaseExtension neo4j = new CertificateExtension(); @Test - void shouldAcceptServerWithCertificateSignedByDriverCertificate() throws Throwable - { + void shouldAcceptServerWithCertificateSignedByDriverCertificate() throws Throwable { // Given root certificate - CertificateKeyPair root = createNewCertificateAndKey(); + CertificateKeyPair root = createNewCertificateAndKey(); // When - CertificateKeyPair server = createNewCertificateAndKeySignedBy( root ); - neo4j.updateEncryptionKeyAndCert( server.key(), server.cert() ); + CertificateKeyPair server = createNewCertificateAndKeySignedBy(root); + neo4j.updateEncryptionKeyAndCert(server.key(), server.cert()); // Then - shouldBeAbleToRunCypher( () -> createDriverWithCustomCertificate( root.cert() ) ); + shouldBeAbleToRunCypher(() -> createDriverWithCustomCertificate(root.cert())); } @Test - void shouldAcceptServerWithSameCertificate() throws Throwable - { - shouldBeAbleToRunCypher( () -> createDriverWithCustomCertificate( neo4j.tlsCertFile() ) ); + void shouldAcceptServerWithSameCertificate() throws Throwable { + shouldBeAbleToRunCypher(() -> createDriverWithCustomCertificate(neo4j.tlsCertFile())); } @Test - void shouldRejectServerWithUntrustedCertificate() throws Throwable - { + void shouldRejectServerWithUntrustedCertificate() throws Throwable { // Given a driver with a (random) cert - CertificateKeyPair certificateAndKey = createNewCertificateAndKey(); + CertificateKeyPair certificateAndKey = createNewCertificateAndKey(); // When & Then - final Driver driver = createDriverWithCustomCertificate( certificateAndKey.cert() ); - SecurityException error = assertThrows( SecurityException.class, driver::verifyConnectivity ); + final Driver driver = createDriverWithCustomCertificate(certificateAndKey.cert()); + SecurityException error = assertThrows(SecurityException.class, driver::verifyConnectivity); } - private void shouldBeAbleToRunCypher( Supplier driverSupplier ) - { - try ( Driver driver = driverSupplier.get(); Session session = driver.session() ) - { - Result result = session.run( "RETURN 1 as n" ); - assertThat( result.single().get( "n" ).asInt(), equalTo( 1 ) ); + private void shouldBeAbleToRunCypher(Supplier driverSupplier) { + try (Driver driver = driverSupplier.get(); + Session session = driver.session()) { + Result result = session.run("RETURN 1 as n"); + assertThat(result.single().get("n").asInt(), equalTo(1)); } } - private Driver createDriverWithCustomCertificate( File cert ) - { - return GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), - Config.builder().withEncryption().withTrustStrategy( trustCustomCertificateSignedBy( cert ) ).build() ); + private Driver createDriverWithCustomCertificate(File cert) { + return GraphDatabase.driver( + neo4j.uri(), + neo4j.authToken(), + Config.builder() + .withEncryption() + .withTrustStrategy(trustCustomCertificateSignedBy(cert)) + .build()); } } 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 f8661a54f2..504ee42a64 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java @@ -18,17 +18,26 @@ */ package org.neo4j.driver.integration; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.util.TestUtil.await; + import io.netty.channel.Channel; import io.netty.channel.ChannelPipeline; import io.netty.util.concurrent.Future; +import java.io.IOException; +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.io.IOException; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.Query; @@ -48,204 +57,178 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.util.TestUtil.await; - - @ParallelizableIT -class UnmanagedTransactionIT -{ +class UnmanagedTransactionIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private NetworkSession session; @BeforeEach - void setUp() - { - session = ((InternalDriver) neo4j.driver()).newSession( SessionConfig.defaultConfig() ); + void setUp() { + session = ((InternalDriver) neo4j.driver()).newSession(SessionConfig.defaultConfig()); } @AfterEach - void tearDown() - { + void tearDown() { session.closeAsync(); } - private UnmanagedTransaction beginTransaction() - { - return beginTransaction( session ); + private UnmanagedTransaction beginTransaction() { + return beginTransaction(session); } - private UnmanagedTransaction beginTransaction(NetworkSession session ) - { - return await( session.beginTransactionAsync( TransactionConfig.empty() ) ); + private UnmanagedTransaction beginTransaction(NetworkSession session) { + return await(session.beginTransactionAsync(TransactionConfig.empty())); } - private ResultCursor sessionRun(NetworkSession session, Query query) - { - return await( session.runAsync( query, TransactionConfig.empty() ) ); + private ResultCursor sessionRun(NetworkSession session, Query query) { + return await(session.runAsync(query, TransactionConfig.empty())); } - private ResultCursor txRun(UnmanagedTransaction tx, String query ) - { - return await( tx.runAsync( new Query( query ) ) ); + private ResultCursor txRun(UnmanagedTransaction tx, String query) { + return await(tx.runAsync(new Query(query))); } @Test - void shouldDoNothingWhenCommittedSecondTime() - { + void shouldDoNothingWhenCommittedSecondTime() { UnmanagedTransaction tx = beginTransaction(); - assertNull( await( tx.commitAsync() ) ); + assertNull(await(tx.commitAsync())); - assertTrue( tx.commitAsync().toCompletableFuture().isDone() ); - assertFalse( tx.isOpen() ); + assertTrue(tx.commitAsync().toCompletableFuture().isDone()); + assertFalse(tx.isOpen()); } @Test - void shouldFailToCommitAfterRollback() - { + void shouldFailToCommitAfterRollback() { UnmanagedTransaction tx = beginTransaction(); - assertNull( await( tx.rollbackAsync() ) ); + assertNull(await(tx.rollbackAsync())); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertEquals( "Can't commit, transaction has been rolled back", e.getMessage() ); - assertFalse( tx.isOpen() ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertEquals("Can't commit, transaction has been rolled back", e.getMessage()); + assertFalse(tx.isOpen()); } @Test - void shouldFailToCommitAfterTermination() - { + void shouldFailToCommitAfterTermination() { UnmanagedTransaction tx = beginTransaction(); - tx.markTerminated( null ); + tx.markTerminated(null); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertThat( e.getMessage(), startsWith( "Transaction can't be committed" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertThat(e.getMessage(), startsWith("Transaction can't be committed")); } @Test - void shouldDoNothingWhenRolledBackSecondTime() - { + void shouldDoNothingWhenRolledBackSecondTime() { UnmanagedTransaction tx = beginTransaction(); - assertNull( await( tx.rollbackAsync() ) ); + assertNull(await(tx.rollbackAsync())); - assertTrue( tx.rollbackAsync().toCompletableFuture().isDone() ); - assertFalse( tx.isOpen() ); + assertTrue(tx.rollbackAsync().toCompletableFuture().isDone()); + assertFalse(tx.isOpen()); } @Test - void shouldFailToRollbackAfterCommit() - { + void shouldFailToRollbackAfterCommit() { UnmanagedTransaction tx = beginTransaction(); - assertNull( await( tx.commitAsync() ) ); + assertNull(await(tx.commitAsync())); - ClientException e = assertThrows( ClientException.class, () -> await( tx.rollbackAsync() ) ); - assertEquals( "Can't rollback, transaction has been committed", e.getMessage() ); - assertFalse( tx.isOpen() ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.rollbackAsync())); + assertEquals("Can't rollback, transaction has been committed", e.getMessage()); + assertFalse(tx.isOpen()); } @Test - void shouldRollbackAfterTermination() - { + void shouldRollbackAfterTermination() { UnmanagedTransaction tx = beginTransaction(); - tx.markTerminated( null ); + tx.markTerminated(null); - assertNull( await( tx.rollbackAsync() ) ); - assertFalse( tx.isOpen() ); + assertNull(await(tx.rollbackAsync())); + assertFalse(tx.isOpen()); } @Test - void shouldFailToRunQueryWhenTerminated() - { + void shouldFailToRunQueryWhenTerminated() { UnmanagedTransaction tx = beginTransaction(); - txRun( tx, "CREATE (:MyLabel)" ); - tx.markTerminated( null ); + txRun(tx, "CREATE (:MyLabel)"); + tx.markTerminated(null); - ClientException e = assertThrows( ClientException.class, () -> txRun( tx, "CREATE (:MyOtherLabel)" ) ); - assertThat( e.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); + ClientException e = assertThrows(ClientException.class, () -> txRun(tx, "CREATE (:MyOtherLabel)")); + assertThat(e.getMessage(), startsWith("Cannot run more queries in this transaction")); } @Test - void shouldBePossibleToRunMoreTransactionsAfterOneIsTerminated() - { + void shouldBePossibleToRunMoreTransactionsAfterOneIsTerminated() { UnmanagedTransaction tx1 = beginTransaction(); - tx1.markTerminated( null ); + tx1.markTerminated(null); // commit should fail, make session forget about this transaction and release the connection to the pool - ClientException e = assertThrows( ClientException.class, () -> await( tx1.commitAsync() ) ); - assertThat( e.getMessage(), startsWith( "Transaction can't be committed" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx1.commitAsync())); + assertThat(e.getMessage(), startsWith("Transaction can't be committed")); - await( session.beginTransactionAsync( TransactionConfig.empty() ) - .thenCompose( tx -> tx.runAsync( new Query( "CREATE (:Node {id: 42})" ) ) - .thenCompose( ResultCursor::consumeAsync ) - .thenApply( ignore -> tx ) - ).thenCompose( UnmanagedTransaction::commitAsync ) ); + await(session.beginTransactionAsync(TransactionConfig.empty()) + .thenCompose(tx -> tx.runAsync(new Query("CREATE (:Node {id: 42})")) + .thenCompose(ResultCursor::consumeAsync) + .thenApply(ignore -> tx)) + .thenCompose(UnmanagedTransaction::commitAsync)); - assertEquals( 1, countNodes( 42 ) ); + assertEquals(1, countNodes(42)); } @Test - void shouldPropagateCommitFailureAfterFatalError() - { - testCommitAndRollbackFailurePropagation( true ); + void shouldPropagateCommitFailureAfterFatalError() { + testCommitAndRollbackFailurePropagation(true); } @Test - void shouldPropagateRollbackFailureAfterFatalError() - { - testCommitAndRollbackFailurePropagation( false ); + void shouldPropagateRollbackFailureAfterFatalError() { + testCommitAndRollbackFailurePropagation(false); } - private int countNodes( Object id ) - { - Query query = new Query( "MATCH (n:Node {id: $id}) RETURN count(n)", parameters( "id", id ) ); - ResultCursor cursor = sessionRun( session, query); - return await( cursor.singleAsync() ).get( 0 ).asInt(); + private int countNodes(Object id) { + Query query = new Query("MATCH (n:Node {id: $id}) RETURN count(n)", parameters("id", id)); + ResultCursor cursor = sessionRun(session, query); + return await(cursor.singleAsync()).get(0).asInt(); } - private void testCommitAndRollbackFailurePropagation( boolean commit ) - { - ChannelTrackingDriverFactory driverFactory = new ChannelTrackingDriverFactory( 1, Clock.SYSTEM ); - Config config = Config.builder().withLogging( DEV_NULL_LOGGING ).build(); + private void testCommitAndRollbackFailurePropagation(boolean commit) { + ChannelTrackingDriverFactory driverFactory = new ChannelTrackingDriverFactory(1, Clock.SYSTEM); + Config config = Config.builder().withLogging(DEV_NULL_LOGGING).build(); - try ( Driver driver = driverFactory.newInstance( neo4j.uri(), neo4j.authToken(), RoutingSettings.DEFAULT, RetrySettings.DEFAULT, config, - SecurityPlanImpl.insecure() ) ) - { - NetworkSession session = ((InternalDriver) driver).newSession( SessionConfig.defaultConfig() ); + try (Driver driver = driverFactory.newInstance( + neo4j.uri(), + neo4j.authToken(), + RoutingSettings.DEFAULT, + RetrySettings.DEFAULT, + config, + SecurityPlanImpl.insecure())) { + NetworkSession session = ((InternalDriver) driver).newSession(SessionConfig.defaultConfig()); { - UnmanagedTransaction tx = beginTransaction( session ); + UnmanagedTransaction tx = beginTransaction(session); // run query but do not consume the result - txRun( tx, "UNWIND range(0, 10000) AS x RETURN x + 1" ); + txRun(tx, "UNWIND range(0, 10000) AS x RETURN x + 1"); - IOException ioError = new IOException( "Connection reset by peer" ); - for ( Channel channel : driverFactory.channels() ) - { + IOException ioError = new IOException("Connection reset by peer"); + for (Channel channel : driverFactory.channels()) { // make channel experience a fatal network error // run in the event loop thread and wait for the whole operation to complete - Future future = channel.eventLoop().submit( () -> channel.pipeline().fireExceptionCaught( ioError ) ); - await( future ); + Future future = + channel.eventLoop().submit(() -> channel.pipeline().fireExceptionCaught(ioError)); + await(future); } CompletionStage commitOrRollback = commit ? tx.commitAsync() : tx.rollbackAsync(); // commit/rollback should fail and propagate the network error - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, () -> await( commitOrRollback ) ); - assertEquals( ioError, e.getCause() ); + ServiceUnavailableException e = + assertThrows(ServiceUnavailableException.class, () -> await(commitOrRollback)); + assertEquals(ioError, e.getCause()); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/UnsupportedBoltV3IT.java b/driver/src/test/java/org/neo4j/driver/integration/UnsupportedBoltV3IT.java index ee2dfca995..d22432503d 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/UnsupportedBoltV3IT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/UnsupportedBoltV3IT.java @@ -18,72 +18,64 @@ */ package org.neo4j.driver.integration; +import static java.time.Duration.ofSeconds; +import static java.util.Collections.singletonMap; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V3; +import static org.neo4j.driver.util.TestUtil.await; + +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.function.Executable; - -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.util.DisabledOnNeo4jWith; import org.neo4j.driver.util.DriverExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.time.Duration.ofSeconds; -import static java.util.Collections.singletonMap; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.startsWith; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V3; -import static org.neo4j.driver.util.TestUtil.await; - -@DisabledOnNeo4jWith( BOLT_V3 ) +@DisabledOnNeo4jWith(BOLT_V3) @ParallelizableIT -class UnsupportedBoltV3IT -{ +class UnsupportedBoltV3IT { @RegisterExtension static final DriverExtension driver = new DriverExtension(); private final TransactionConfig txConfig = TransactionConfig.builder() - .withTimeout( ofSeconds( 4 ) ) - .withMetadata( singletonMap( "key", "value" ) ) + .withTimeout(ofSeconds(4)) + .withMetadata(singletonMap("key", "value")) .build(); @Test - void shouldNotSupportAutoCommitQueriesWithTransactionConfig() - { - assertTxConfigNotSupported( () -> driver.session().run( "RETURN 42", txConfig ) ); + void shouldNotSupportAutoCommitQueriesWithTransactionConfig() { + assertTxConfigNotSupported(() -> driver.session().run("RETURN 42", txConfig)); } @Test - void shouldNotSupportAsyncAutoCommitQueriesWithTransactionConfig() - { - assertTxConfigNotSupported( driver.asyncSession().runAsync( "RETURN 42", txConfig ) ); + void shouldNotSupportAsyncAutoCommitQueriesWithTransactionConfig() { + assertTxConfigNotSupported(driver.asyncSession().runAsync("RETURN 42", txConfig)); } @Test - void shouldNotSupportTransactionFunctionsWithTransactionConfig() - { - assertTxConfigNotSupported( () -> driver.session().readTransaction( tx -> tx.run( "RETURN 42" ), txConfig ) ); + void shouldNotSupportTransactionFunctionsWithTransactionConfig() { + assertTxConfigNotSupported(() -> driver.session().readTransaction(tx -> tx.run("RETURN 42"), txConfig)); } @Test - void shouldNotSupportAsyncTransactionFunctionsWithTransactionConfig() - { - assertTxConfigNotSupported( driver.asyncSession().readTransactionAsync( tx -> tx.runAsync( "RETURN 42" ), txConfig ) ); + void shouldNotSupportAsyncTransactionFunctionsWithTransactionConfig() { + assertTxConfigNotSupported( + driver.asyncSession().readTransactionAsync(tx -> tx.runAsync("RETURN 42"), txConfig)); } @Test - void shouldNotSupportUnmanagedTransactionsWithTransactionConfig() - { - assertTxConfigNotSupported( () -> driver.session().beginTransaction( txConfig ) ); + void shouldNotSupportUnmanagedTransactionsWithTransactionConfig() { + assertTxConfigNotSupported(() -> driver.session().beginTransaction(txConfig)); } @Test - void shouldNotSupportAsyncUnmanagedTransactionsWithTransactionConfig() - { - assertTxConfigNotSupported( driver.asyncSession().beginTransactionAsync( txConfig ) ); + void shouldNotSupportAsyncUnmanagedTransactionsWithTransactionConfig() { + assertTxConfigNotSupported(driver.asyncSession().beginTransactionAsync(txConfig)); } /** @@ -91,14 +83,14 @@ void shouldNotSupportAsyncUnmanagedTransactionsWithTransactionConfig() * * @param stage the stage to verify. */ - private static void assertTxConfigNotSupported( CompletionStage stage ) - { - assertTxConfigNotSupported( () -> await( stage ) ); + private static void assertTxConfigNotSupported(CompletionStage stage) { + assertTxConfigNotSupported(() -> await(stage)); } - private static void assertTxConfigNotSupported( Executable executable ) - { - ClientException error = assertThrows( ClientException.class, executable ); - assertThat( error.getMessage(), startsWith( "Driver is connected to the database that does not support transaction configuration" ) ); + private static void assertTxConfigNotSupported(Executable executable) { + ClientException error = assertThrows(ClientException.class, executable); + assertThat( + error.getMessage(), + startsWith("Driver is connected to the database that does not support transaction configuration")); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/async/AsyncQueryIT.java b/driver/src/test/java/org/neo4j/driver/integration/async/AsyncQueryIT.java index e26f4e304c..f873b65a51 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/async/AsyncQueryIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/async/AsyncQueryIT.java @@ -18,57 +18,49 @@ */ package org.neo4j.driver.integration.async; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; + +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.util.ArrayList; -import java.util.concurrent.ExecutionException; - import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; - -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; @ParallelizableIT -public class AsyncQueryIT -{ +public class AsyncQueryIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private AsyncSession session; @BeforeEach - void setUp() - { + void setUp() { session = neo4j.driver().asyncSession(); } @AfterEach - void tearDown() - { + void tearDown() { session.closeAsync(); } @Test - void shouldBeAbleToLogSemanticWrongExceptions() throws ExecutionException, InterruptedException - { - session.writeTransactionAsync( tx -> Flux.from( - Mono.fromCompletionStage( - tx.runAsync( "MATCH (n:Element) WHERE n.name = {param} RETURN n", parameters("param", "Luke") ) - )).collectList().toFuture()) - - .toCompletableFuture() - .exceptionally( ex -> { - assertNoCircularReferences(ex); - return new ArrayList<>(); - } ) - .get(); + void shouldBeAbleToLogSemanticWrongExceptions() throws ExecutionException, InterruptedException { + session.writeTransactionAsync(tx -> Flux.from(Mono.fromCompletionStage(tx.runAsync( + "MATCH (n:Element) WHERE n.name = {param} RETURN n", parameters("param", "Luke")))) + .collectList() + .toFuture()) + .toCompletableFuture() + .exceptionally(ex -> { + assertNoCircularReferences(ex); + return new ArrayList<>(); + }) + .get(); } - } diff --git a/driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionIT.java b/driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionIT.java index 942d534d7a..888402e618 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionIT.java @@ -18,10 +18,32 @@ */ package org.neo4j.driver.integration.async; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Collections.emptyIterator; +import static java.util.Collections.emptyMap; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.util.Futures.failedFuture; +import static org.neo4j.driver.internal.util.Iterables.single; +import static org.neo4j.driver.internal.util.Matchers.arithmeticError; +import static org.neo4j.driver.internal.util.Matchers.containsResultAvailableAfterAndResultConsumedAfter; +import static org.neo4j.driver.internal.util.Matchers.syntaxError; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V3; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; +import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; +import static org.neo4j.driver.util.TestUtil.await; +import static org.neo4j.driver.util.TestUtil.awaitAll; import java.io.IOException; import java.util.ArrayList; @@ -34,7 +56,10 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; import org.neo4j.driver.Record; @@ -60,931 +85,815 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.util.Collections.emptyIterator; -import static java.util.Collections.emptyMap; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.util.Futures.failedFuture; -import static org.neo4j.driver.internal.util.Iterables.single; -import static org.neo4j.driver.internal.util.Matchers.arithmeticError; -import static org.neo4j.driver.internal.util.Matchers.containsResultAvailableAfterAndResultConsumedAfter; -import static org.neo4j.driver.internal.util.Matchers.syntaxError; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V3; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; -import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; -import static org.neo4j.driver.util.TestUtil.await; -import static org.neo4j.driver.util.TestUtil.awaitAll; - @ParallelizableIT -class AsyncSessionIT -{ +class AsyncSessionIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private AsyncSession session; @BeforeEach - void setUp() - { + void setUp() { session = neo4j.driver().asyncSession(); } @AfterEach - void tearDown() - { + void tearDown() { session.closeAsync(); } @Test - void shouldRunQueryWithEmptyResult() - { - ResultCursor cursor = await( session.runAsync( "CREATE (:Person)" ) ); + void shouldRunQueryWithEmptyResult() { + ResultCursor cursor = await(session.runAsync("CREATE (:Person)")); - assertNull( await( cursor.nextAsync() ) ); + assertNull(await(cursor.nextAsync())); } @Test - void shouldRunQueryWithSingleResult() - { - ResultCursor cursor = await( session.runAsync( "CREATE (p:Person {name: 'Nick Fury'}) RETURN p" ) ); + void shouldRunQueryWithSingleResult() { + ResultCursor cursor = await(session.runAsync("CREATE (p:Person {name: 'Nick Fury'}) RETURN p")); - Record record = await( cursor.nextAsync() ); - assertNotNull( record ); - Node node = record.get( 0 ).asNode(); - assertEquals( "Person", single( node.labels() ) ); - assertEquals( "Nick Fury", node.get( "name" ).asString() ); + Record record = await(cursor.nextAsync()); + assertNotNull(record); + Node node = record.get(0).asNode(); + assertEquals("Person", single(node.labels())); + assertEquals("Nick Fury", node.get("name").asString()); - assertNull( await( cursor.nextAsync() ) ); + assertNull(await(cursor.nextAsync())); } @Test - void shouldRunQueryWithMultipleResults() - { - ResultCursor cursor = await( session.runAsync( "UNWIND [1,2,3] AS x RETURN x" ) ); + void shouldRunQueryWithMultipleResults() { + ResultCursor cursor = await(session.runAsync("UNWIND [1,2,3] AS x RETURN x")); - Record record1 = await( cursor.nextAsync() ); - assertNotNull( record1 ); - assertEquals( 1, record1.get( 0 ).asInt() ); + Record record1 = await(cursor.nextAsync()); + assertNotNull(record1); + assertEquals(1, record1.get(0).asInt()); - Record record2 = await( cursor.nextAsync() ); - assertNotNull( record2 ); - assertEquals( 2, record2.get( 0 ).asInt() ); + Record record2 = await(cursor.nextAsync()); + assertNotNull(record2); + assertEquals(2, record2.get(0).asInt()); - Record record3 = await( cursor.nextAsync() ); - assertNotNull( record3 ); - assertEquals( 3, record3.get( 0 ).asInt() ); + Record record3 = await(cursor.nextAsync()); + assertNotNull(record3); + assertEquals(3, record3.get(0).asInt()); - assertNull( await( cursor.nextAsync() ) ); + assertNull(await(cursor.nextAsync())); } @Test - void shouldFailForIncorrectQuery() - { - Exception e = assertThrows( Exception.class, () -> await( session.runAsync( "RETURN" ) ) ); + void shouldFailForIncorrectQuery() { + Exception e = assertThrows(Exception.class, () -> await(session.runAsync("RETURN"))); - assertThat( e, is( syntaxError() ) ); + assertThat(e, is(syntaxError())); } @Test - void shouldFailWhenQueryFailsAtRuntime() - { - ResultCursor cursor = await( session.runAsync( "CYPHER runtime=interpreted UNWIND [1, 2, 0] AS x RETURN 10 / x" ) ); + void shouldFailWhenQueryFailsAtRuntime() { + ResultCursor cursor = await(session.runAsync("CYPHER runtime=interpreted UNWIND [1, 2, 0] AS x RETURN 10 / x")); - Record record1 = await( cursor.nextAsync() ); - assertNotNull( record1 ); - assertEquals( 10, record1.get( 0 ).asInt() ); + Record record1 = await(cursor.nextAsync()); + assertNotNull(record1); + assertEquals(10, record1.get(0).asInt()); - Record record2 = await( cursor.nextAsync() ); - assertNotNull( record2 ); - assertEquals( 5, record2.get( 0 ).asInt() ); + Record record2 = await(cursor.nextAsync()); + assertNotNull(record2); + assertEquals(5, record2.get(0).asInt()); - Exception e = assertThrows( Exception.class, () -> await( cursor.nextAsync() ) ); - assertThat( e, is( arithmeticError() ) ); + Exception e = assertThrows(Exception.class, () -> await(cursor.nextAsync())); + assertThat(e, is(arithmeticError())); } @Test - void shouldAllowNestedQueries() - { - ResultCursor cursor = - await( session.runAsync( "UNWIND [1, 2, 3] AS x CREATE (p:Person {id: x}) RETURN p" ) ); + void shouldAllowNestedQueries() { + ResultCursor cursor = await(session.runAsync("UNWIND [1, 2, 3] AS x CREATE (p:Person {id: x}) RETURN p")); - Future>> queriesExecuted = runNestedQueries( cursor ); - List> futures = await( queriesExecuted ); + Future>> queriesExecuted = runNestedQueries(cursor); + List> futures = await(queriesExecuted); - List futureResults = awaitAll( futures ); - assertEquals( 7, futureResults.size() ); + List futureResults = awaitAll(futures); + assertEquals(7, futureResults.size()); - ResultCursor personCursor = await( session.runAsync( "MATCH (p:Person) RETURN p ORDER BY p.id" ) ); + ResultCursor personCursor = await(session.runAsync("MATCH (p:Person) RETURN p ORDER BY p.id")); List personNodes = new ArrayList<>(); Record record; - while ( (record = await( personCursor.nextAsync() )) != null ) - { - personNodes.add( record.get( 0 ).asNode() ); + while ((record = await(personCursor.nextAsync())) != null) { + personNodes.add(record.get(0).asNode()); } - assertEquals( 3, personNodes.size() ); + assertEquals(3, personNodes.size()); - Node node1 = personNodes.get( 0 ); - assertEquals( 1, node1.get( "id" ).asInt() ); - assertEquals( 10, node1.get( "age" ).asInt() ); + Node node1 = personNodes.get(0); + assertEquals(1, node1.get("id").asInt()); + assertEquals(10, node1.get("age").asInt()); - Node node2 = personNodes.get( 1 ); - assertEquals( 2, node2.get( "id" ).asInt() ); - assertEquals( 20, node2.get( "age" ).asInt() ); + Node node2 = personNodes.get(1); + assertEquals(2, node2.get("id").asInt()); + assertEquals(20, node2.get("age").asInt()); - Node node3 = personNodes.get( 2 ); - assertEquals( 3, node3.get( "id" ).asInt() ); - assertEquals( 30, personNodes.get( 2 ).get( "age" ).asInt() ); + Node node3 = personNodes.get(2); + assertEquals(3, node3.get("id").asInt()); + assertEquals(30, personNodes.get(2).get("age").asInt()); } @Test - void shouldAllowMultipleAsyncRunsWithoutConsumingResults() - { + void shouldAllowMultipleAsyncRunsWithoutConsumingResults() { int queryCount = 13; List> cursors = new ArrayList<>(); - for ( int i = 0; i < queryCount; i++ ) - { - cursors.add( session.runAsync( "CREATE (:Person)" ) ); + for (int i = 0; i < queryCount; i++) { + cursors.add(session.runAsync("CREATE (:Person)")); } List> records = new ArrayList<>(); - for ( ResultCursor cursor : awaitAll( cursors ) ) - { - records.add( cursor.nextAsync() ); + for (ResultCursor cursor : awaitAll(cursors)) { + records.add(cursor.nextAsync()); } - awaitAll( records ); + awaitAll(records); - await( session.closeAsync() ); + await(session.closeAsync()); session = neo4j.driver().asyncSession(); - ResultCursor cursor = await( session.runAsync( "MATCH (p:Person) RETURN count(p)" ) ); - Record record = await( cursor.nextAsync() ); - assertNotNull( record ); - assertEquals( queryCount, record.get( 0 ).asInt() ); + ResultCursor cursor = await(session.runAsync("MATCH (p:Person) RETURN count(p)")); + Record record = await(cursor.nextAsync()); + assertNotNull(record); + assertEquals(queryCount, record.get(0).asInt()); } @Test - void shouldExposeQueryKeysForColumnsWithAliases() - { - ResultCursor cursor = await( session.runAsync( "RETURN 1 AS one, 2 AS two, 3 AS three, 4 AS five" ) ); + void shouldExposeQueryKeysForColumnsWithAliases() { + ResultCursor cursor = await(session.runAsync("RETURN 1 AS one, 2 AS two, 3 AS three, 4 AS five")); - assertEquals( Arrays.asList( "one", "two", "three", "five" ), cursor.keys() ); + assertEquals(Arrays.asList("one", "two", "three", "five"), cursor.keys()); } @Test - void shouldExposeQueryKeysForColumnsWithoutAliases() - { - ResultCursor cursor = await( session.runAsync( "RETURN 1, 2, 3, 5" ) ); + void shouldExposeQueryKeysForColumnsWithoutAliases() { + ResultCursor cursor = await(session.runAsync("RETURN 1, 2, 3, 5")); - assertEquals( Arrays.asList( "1", "2", "3", "5" ), cursor.keys() ); + assertEquals(Arrays.asList("1", "2", "3", "5"), cursor.keys()); } @Test - void shouldExposeResultSummaryForSimpleQuery() - { + void shouldExposeResultSummaryForSimpleQuery() { String query = "CREATE (:Node {id: $id, name: $name})"; - Value params = parameters( "id", 1, "name", "TheNode" ); + Value params = parameters("id", 1, "name", "TheNode"); - ResultCursor cursor = await( session.runAsync( query, params ) ); - ResultSummary summary = await( cursor.consumeAsync() ); + ResultCursor cursor = await(session.runAsync(query, params)); + ResultSummary summary = await(cursor.consumeAsync()); - assertEquals( new Query( query, params ), summary.query() ); - assertEquals( 1, summary.counters().nodesCreated() ); - assertEquals( 1, summary.counters().labelsAdded() ); - assertEquals( 2, summary.counters().propertiesSet() ); - assertEquals( 0, summary.counters().relationshipsCreated() ); - assertEquals( QueryType.WRITE_ONLY, summary.queryType() ); - assertFalse( summary.hasPlan() ); - assertFalse( summary.hasProfile() ); - assertNull( summary.plan() ); - assertNull( summary.profile() ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); + assertEquals(new Query(query, params), summary.query()); + assertEquals(1, summary.counters().nodesCreated()); + assertEquals(1, summary.counters().labelsAdded()); + assertEquals(2, summary.counters().propertiesSet()); + assertEquals(0, summary.counters().relationshipsCreated()); + assertEquals(QueryType.WRITE_ONLY, summary.queryType()); + assertFalse(summary.hasPlan()); + assertFalse(summary.hasProfile()); + assertNull(summary.plan()); + assertNull(summary.profile()); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); } @Test - void shouldExposeResultSummaryForExplainQuery() - { + void shouldExposeResultSummaryForExplainQuery() { String query = "EXPLAIN CREATE (),() WITH * MATCH (n)-->(m) CREATE (n)-[:HI {id: 'id'}]->(m) RETURN n, m"; - ResultCursor cursor = await( session.runAsync( query ) ); - ResultSummary summary = await( cursor.consumeAsync() ); - - assertEquals( new Query( query ), summary.query() ); - assertEquals( 0, summary.counters().nodesCreated() ); - assertEquals( 0, summary.counters().propertiesSet() ); - assertEquals( 0, summary.counters().relationshipsCreated() ); - assertEquals( QueryType.READ_WRITE, summary.queryType() ); - assertTrue( summary.hasPlan() ); - assertFalse( summary.hasProfile() ); - assertNotNull( summary.plan() ); + ResultCursor cursor = await(session.runAsync(query)); + ResultSummary summary = await(cursor.consumeAsync()); + + assertEquals(new Query(query), summary.query()); + assertEquals(0, summary.counters().nodesCreated()); + assertEquals(0, summary.counters().propertiesSet()); + assertEquals(0, summary.counters().relationshipsCreated()); + assertEquals(QueryType.READ_WRITE, summary.queryType()); + assertTrue(summary.hasPlan()); + assertFalse(summary.hasProfile()); + assertNotNull(summary.plan()); // asserting on plan is a bit fragile and can break when server side changes or with different // server versions; that is why do fuzzy assertions in this test based on string content String planAsString = summary.plan().toString().toLowerCase(); - assertThat( planAsString, containsString( "create" ) ); - assertThat( planAsString, containsString( "expand" ) ); - assertNull( summary.profile() ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); + assertThat(planAsString, containsString("create")); + assertThat(planAsString, containsString("expand")); + assertNull(summary.profile()); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); } @Test - void shouldExposeResultSummaryForProfileQuery() - { + void shouldExposeResultSummaryForProfileQuery() { String query = "PROFILE CREATE (:Node)-[:KNOWS]->(:Node) WITH * MATCH (n) RETURN n"; - ResultCursor cursor = await( session.runAsync( query ) ); - ResultSummary summary = await( cursor.consumeAsync() ); - - assertEquals( new Query( query ), summary.query() ); - assertEquals( 2, summary.counters().nodesCreated() ); - assertEquals( 0, summary.counters().propertiesSet() ); - assertEquals( 1, summary.counters().relationshipsCreated() ); - assertEquals( QueryType.READ_WRITE, summary.queryType() ); - assertTrue( summary.hasPlan() ); - assertTrue( summary.hasProfile() ); - assertNotNull( summary.plan() ); - assertNotNull( summary.profile() ); + ResultCursor cursor = await(session.runAsync(query)); + ResultSummary summary = await(cursor.consumeAsync()); + + assertEquals(new Query(query), summary.query()); + assertEquals(2, summary.counters().nodesCreated()); + assertEquals(0, summary.counters().propertiesSet()); + assertEquals(1, summary.counters().relationshipsCreated()); + assertEquals(QueryType.READ_WRITE, summary.queryType()); + assertTrue(summary.hasPlan()); + assertTrue(summary.hasProfile()); + assertNotNull(summary.plan()); + assertNotNull(summary.profile()); // asserting on profile is a bit fragile and can break when server side changes or with different // server versions; that is why do fuzzy assertions in this test based on string content String profileAsString = summary.profile().toString().toLowerCase(); - assertThat( profileAsString, containsString( "hits" ) ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); + assertThat(profileAsString, containsString("hits")); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); } @Test - void shouldRunAsyncTransactionWithoutRetries() - { - InvocationTrackingWork work = new InvocationTrackingWork( "CREATE (:Apa) RETURN 42" ); - CompletionStage txStage = session.writeTransactionAsync( work ); + void shouldRunAsyncTransactionWithoutRetries() { + InvocationTrackingWork work = new InvocationTrackingWork("CREATE (:Apa) RETURN 42"); + CompletionStage txStage = session.writeTransactionAsync(work); - Record record = await( txStage ); - assertNotNull( record ); - assertEquals( 42L, record.get( 0 ).asLong() ); + Record record = await(txStage); + assertNotNull(record); + assertEquals(42L, record.get(0).asLong()); - assertEquals( 1, work.invocationCount() ); - assertEquals( 1, countNodesByLabel( "Apa" ) ); + assertEquals(1, work.invocationCount()); + assertEquals(1, countNodesByLabel("Apa")); } @Test - void shouldRunAsyncTransactionWithRetriesOnAsyncFailures() - { - InvocationTrackingWork work = new InvocationTrackingWork( "CREATE (:Node) RETURN 24" ).withAsyncFailures( - new ServiceUnavailableException( "Oh!" ), - new SessionExpiredException( "Ah!" ), - new TransientException( "Code", "Message" ) ); + void shouldRunAsyncTransactionWithRetriesOnAsyncFailures() { + InvocationTrackingWork work = new InvocationTrackingWork("CREATE (:Node) RETURN 24") + .withAsyncFailures( + new ServiceUnavailableException("Oh!"), + new SessionExpiredException("Ah!"), + new TransientException("Code", "Message")); - CompletionStage txStage = session.writeTransactionAsync( work ); + CompletionStage txStage = session.writeTransactionAsync(work); - Record record = await( txStage ); - assertNotNull( record ); - assertEquals( 24L, record.get( 0 ).asLong() ); + Record record = await(txStage); + assertNotNull(record); + assertEquals(24L, record.get(0).asLong()); - assertEquals( 4, work.invocationCount() ); - assertEquals( 1, countNodesByLabel( "Node" ) ); + assertEquals(4, work.invocationCount()); + assertEquals(1, countNodesByLabel("Node")); } @Test - void shouldRunAsyncTransactionWithRetriesOnSyncFailures() - { - InvocationTrackingWork work = new InvocationTrackingWork( "CREATE (:Test) RETURN 12" ).withSyncFailures( - new TransientException( "Oh!", "Deadlock!" ), - new ServiceUnavailableException( "Oh! Network Failure" ) ); + void shouldRunAsyncTransactionWithRetriesOnSyncFailures() { + InvocationTrackingWork work = new InvocationTrackingWork("CREATE (:Test) RETURN 12") + .withSyncFailures( + new TransientException("Oh!", "Deadlock!"), + new ServiceUnavailableException("Oh! Network Failure")); - CompletionStage txStage = session.writeTransactionAsync( work ); + CompletionStage txStage = session.writeTransactionAsync(work); - Record record = await( txStage ); - assertNotNull( record ); - assertEquals( 12L, record.get( 0 ).asLong() ); + Record record = await(txStage); + assertNotNull(record); + assertEquals(12L, record.get(0).asLong()); - assertEquals( 3, work.invocationCount() ); - assertEquals( 1, countNodesByLabel( "Test" ) ); + assertEquals(3, work.invocationCount()); + assertEquals(1, countNodesByLabel("Test")); } @Test - void shouldRunAsyncTransactionThatCanNotBeRetried() - { - InvocationTrackingWork work = new InvocationTrackingWork( "UNWIND [10, 5, 0] AS x CREATE (:Hi) RETURN 10/x" ); - CompletionStage txStage = session.writeTransactionAsync( work ); + void shouldRunAsyncTransactionThatCanNotBeRetried() { + InvocationTrackingWork work = new InvocationTrackingWork("UNWIND [10, 5, 0] AS x CREATE (:Hi) RETURN 10/x"); + CompletionStage txStage = session.writeTransactionAsync(work); - ClientException e = assertThrows( ClientException.class, () -> await( txStage ) ); - assertNoCircularReferences( e ); - assertEquals( 1, work.invocationCount() ); - assertEquals( 0, countNodesByLabel( "Hi" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(txStage)); + assertNoCircularReferences(e); + assertEquals(1, work.invocationCount()); + assertEquals(0, countNodesByLabel("Hi")); } @Test - void shouldRunAsyncTransactionThatCanNotBeRetriedAfterATransientFailure() - { + void shouldRunAsyncTransactionThatCanNotBeRetriedAfterATransientFailure() { // first throw TransientException directly from work, retry can happen afterwards // then return a future failed with DatabaseException, retry can't happen afterwards - InvocationTrackingWork work = new InvocationTrackingWork( "CREATE (:Person) RETURN 1" ) - .withSyncFailures( new TransientException( "Oh!", "Deadlock!" ) ) - .withAsyncFailures( new DatabaseException( "Oh!", "OutOfMemory!" ) ); - CompletionStage txStage = session.writeTransactionAsync( work ); + InvocationTrackingWork work = new InvocationTrackingWork("CREATE (:Person) RETURN 1") + .withSyncFailures(new TransientException("Oh!", "Deadlock!")) + .withAsyncFailures(new DatabaseException("Oh!", "OutOfMemory!")); + CompletionStage txStage = session.writeTransactionAsync(work); - DatabaseException e = assertThrows( DatabaseException.class, () -> await( txStage ) ); + DatabaseException e = assertThrows(DatabaseException.class, () -> await(txStage)); - assertEquals( 1, e.getSuppressed().length ); - assertThat( e.getSuppressed()[0], instanceOf( TransientException.class ) ); - assertEquals( 2, work.invocationCount() ); - assertEquals( 0, countNodesByLabel( "Person" ) ); + assertEquals(1, e.getSuppressed().length); + assertThat(e.getSuppressed()[0], instanceOf(TransientException.class)); + assertEquals(2, work.invocationCount()); + assertEquals(0, countNodesByLabel("Person")); } @Test - void shouldPeekRecordFromCursor() - { - ResultCursor cursor = await( session.runAsync( "UNWIND [1, 2, 42] AS x RETURN x" ) ); + void shouldPeekRecordFromCursor() { + ResultCursor cursor = await(session.runAsync("UNWIND [1, 2, 42] AS x RETURN x")); - assertEquals( 1, await( cursor.peekAsync() ).get( 0 ).asInt() ); - assertEquals( 1, await( cursor.peekAsync() ).get( 0 ).asInt() ); - assertEquals( 1, await( cursor.peekAsync() ).get( 0 ).asInt() ); + assertEquals(1, await(cursor.peekAsync()).get(0).asInt()); + assertEquals(1, await(cursor.peekAsync()).get(0).asInt()); + assertEquals(1, await(cursor.peekAsync()).get(0).asInt()); - assertEquals( 1, await( cursor.nextAsync() ).get( 0 ).asInt() ); + assertEquals(1, await(cursor.nextAsync()).get(0).asInt()); - assertEquals( 2, await( cursor.peekAsync() ).get( 0 ).asInt() ); - assertEquals( 2, await( cursor.peekAsync() ).get( 0 ).asInt() ); + assertEquals(2, await(cursor.peekAsync()).get(0).asInt()); + assertEquals(2, await(cursor.peekAsync()).get(0).asInt()); - assertEquals( 2, await( cursor.nextAsync() ).get( 0 ).asInt() ); + assertEquals(2, await(cursor.nextAsync()).get(0).asInt()); - assertEquals( 42, await( cursor.nextAsync() ).get( 0 ).asInt() ); + assertEquals(42, await(cursor.nextAsync()).get(0).asInt()); - assertNull( await( cursor.peekAsync() ) ); - assertNull( await( cursor.nextAsync() ) ); + assertNull(await(cursor.peekAsync())); + assertNull(await(cursor.nextAsync())); } @Test - void shouldForEachWithEmptyCursor() - { - testForEach( "CREATE ()", 0 ); + void shouldForEachWithEmptyCursor() { + testForEach("CREATE ()", 0); } @Test - void shouldForEachWithNonEmptyCursor() - { - testForEach( "UNWIND range(1, 100000) AS x RETURN x", 100000 ); + void shouldForEachWithNonEmptyCursor() { + testForEach("UNWIND range(1, 100000) AS x RETURN x", 100000); } @Test - void shouldFailForEachWhenActionFails() - { - ResultCursor cursor = await( session.runAsync( "RETURN 42" ) ); - IOException error = new IOException( "Hi" ); + void shouldFailForEachWhenActionFails() { + ResultCursor cursor = await(session.runAsync("RETURN 42")); + IOException error = new IOException("Hi"); - IOException e = assertThrows( IOException.class, () -> - await( cursor.forEachAsync( record -> - { - throw new CompletionException( error ); - } ) ) ); - assertEquals( error, e ); + IOException e = assertThrows( + IOException.class, + () -> await(cursor.forEachAsync(record -> { + throw new CompletionException(error); + }))); + assertEquals(error, e); } @Test - void shouldConvertToListWithEmptyCursor() - { - testList( "MATCH (n:NoSuchLabel) RETURN n", Collections.emptyList() ); + void shouldConvertToListWithEmptyCursor() { + testList("MATCH (n:NoSuchLabel) RETURN n", Collections.emptyList()); } @Test - void shouldConvertToListWithNonEmptyCursor() - { - testList( "UNWIND range(1, 100, 10) AS x RETURN x", - Arrays.asList( 1L, 11L, 21L, 31L, 41L, 51L, 61L, 71L, 81L, 91L ) ); + void shouldConvertToListWithNonEmptyCursor() { + testList( + "UNWIND range(1, 100, 10) AS x RETURN x", + Arrays.asList(1L, 11L, 21L, 31L, 41L, 51L, 61L, 71L, 81L, 91L)); } @Test - void shouldConvertToTransformedListWithEmptyCursor() - { - ResultCursor cursor = await( session.runAsync( "CREATE ()" ) ); - List strings = await( cursor.listAsync( record -> "Hi!" ) ); - assertEquals( 0, strings.size() ); + void shouldConvertToTransformedListWithEmptyCursor() { + ResultCursor cursor = await(session.runAsync("CREATE ()")); + List strings = await(cursor.listAsync(record -> "Hi!")); + assertEquals(0, strings.size()); } @Test - void shouldConvertToTransformedListWithNonEmptyCursor() - { - ResultCursor cursor = await( session.runAsync( "UNWIND [1,2,3] AS x RETURN x" ) ); - List ints = await( cursor.listAsync( record -> record.get( 0 ).asInt() + 1 ) ); - assertEquals( Arrays.asList( 2, 3, 4 ), ints ); + void shouldConvertToTransformedListWithNonEmptyCursor() { + ResultCursor cursor = await(session.runAsync("UNWIND [1,2,3] AS x RETURN x")); + List ints = await(cursor.listAsync(record -> record.get(0).asInt() + 1)); + assertEquals(Arrays.asList(2, 3, 4), ints); } @Test - void shouldFailWhenListTransformationFunctionFails() - { - ResultCursor cursor = await( session.runAsync( "RETURN 42" ) ); - RuntimeException error = new RuntimeException( "Hi!" ); + void shouldFailWhenListTransformationFunctionFails() { + ResultCursor cursor = await(session.runAsync("RETURN 42")); + RuntimeException error = new RuntimeException("Hi!"); - RuntimeException e = assertThrows( RuntimeException.class, () -> - await( cursor.listAsync( record -> - { - throw error; - } ) ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows( + RuntimeException.class, + () -> await(cursor.listAsync(record -> { + throw error; + }))); + assertEquals(error, e); } @Test - void shouldFailSingleWithEmptyCursor() - { - ResultCursor cursor = await( session.runAsync( "CREATE ()" ) ); + void shouldFailSingleWithEmptyCursor() { + ResultCursor cursor = await(session.runAsync("CREATE ()")); - NoSuchRecordException e = assertThrows( NoSuchRecordException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), containsString( "result is empty" ) ); + NoSuchRecordException e = assertThrows(NoSuchRecordException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), containsString("result is empty")); } @Test - void shouldFailSingleWithMultiRecordCursor() - { - ResultCursor cursor = await( session.runAsync( "UNWIND [1, 2, 3] AS x RETURN x" ) ); + void shouldFailSingleWithMultiRecordCursor() { + ResultCursor cursor = await(session.runAsync("UNWIND [1, 2, 3] AS x RETURN x")); - NoSuchRecordException e = assertThrows( NoSuchRecordException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), startsWith( "Expected a result with a single record" ) ); + NoSuchRecordException e = assertThrows(NoSuchRecordException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), startsWith("Expected a result with a single record")); } @Test - void shouldReturnSingleWithSingleRecordCursor() - { - ResultCursor cursor = await( session.runAsync( "RETURN 42" ) ); + void shouldReturnSingleWithSingleRecordCursor() { + ResultCursor cursor = await(session.runAsync("RETURN 42")); - Record record = await( cursor.singleAsync() ); + Record record = await(cursor.singleAsync()); - assertEquals( 42, record.get( 0 ).asInt() ); + assertEquals(42, record.get(0).asInt()); } @Test - void shouldPropagateFailureFromFirstRecordInSingleAsync() - { - ResultCursor cursor = await( session.runAsync( "UNWIND [0] AS x RETURN 10 / x" ) ); + void shouldPropagateFailureFromFirstRecordInSingleAsync() { + ResultCursor cursor = await(session.runAsync("UNWIND [0] AS x RETURN 10 / x")); - ClientException e = assertThrows( ClientException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), containsString("/ by zero")); } @Test - void shouldNotPropagateFailureFromSecondRecordInSingleAsync() - { - ResultCursor cursor = await( session.runAsync( "UNWIND [1, 0] AS x RETURN 10 / x" ) ); + void shouldNotPropagateFailureFromSecondRecordInSingleAsync() { + ResultCursor cursor = await(session.runAsync("UNWIND [1, 0] AS x RETURN 10 / x")); - ClientException e = assertThrows( ClientException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), containsString("/ by zero")); } @Test - void shouldConsumeEmptyCursor() - { - testConsume( "CREATE ()" ); + void shouldConsumeEmptyCursor() { + testConsume("CREATE ()"); } @Test - void shouldConsumeNonEmptyCursor() - { - testConsume( "UNWIND [42, 42] AS x RETURN x" ); + void shouldConsumeNonEmptyCursor() { + testConsume("UNWIND [42, 42] AS x RETURN x"); } @Test - @DisabledOnNeo4jWith( BOLT_V3 ) - void shouldRunAfterBeginTxFailureOnBookmark() - { - Bookmark illegalBookmark = InternalBookmark.parse( "Illegal Bookmark" ); - session = neo4j.driver().asyncSession( builder().withBookmarks( illegalBookmark ).build() ); + @DisabledOnNeo4jWith(BOLT_V3) + void shouldRunAfterBeginTxFailureOnBookmark() { + Bookmark illegalBookmark = InternalBookmark.parse("Illegal Bookmark"); + session = neo4j.driver() + .asyncSession(builder().withBookmarks(illegalBookmark).build()); - assertThrows( ClientException.class, () -> await( session.beginTransactionAsync() ) ); + assertThrows(ClientException.class, () -> await(session.beginTransactionAsync())); - ResultCursor cursor = await( session.runAsync( "RETURN 'Hello!'" ) ); - Record record = await( cursor.singleAsync() ); - assertEquals( "Hello!", record.get( 0 ).asString() ); + ResultCursor cursor = await(session.runAsync("RETURN 'Hello!'")); + Record record = await(cursor.singleAsync()); + assertEquals("Hello!", record.get(0).asString()); } @Test - void shouldNotBeginTxAfterBeginTxFailureOnBookmark() - { - Bookmark illegalBookmark = InternalBookmark.parse( "Illegal Bookmark" ); - session = neo4j.driver().asyncSession( builder().withBookmarks( illegalBookmark ).build() ); - assertThrows( ClientException.class, () -> await( session.beginTransactionAsync() ) ); - assertThrows( ClientException.class, () -> await( session.beginTransactionAsync() ) ); + void shouldNotBeginTxAfterBeginTxFailureOnBookmark() { + Bookmark illegalBookmark = InternalBookmark.parse("Illegal Bookmark"); + session = neo4j.driver() + .asyncSession(builder().withBookmarks(illegalBookmark).build()); + assertThrows(ClientException.class, () -> await(session.beginTransactionAsync())); + assertThrows(ClientException.class, () -> await(session.beginTransactionAsync())); } @Test - @EnabledOnNeo4jWith( BOLT_V3 ) - void shouldNotRunAfterBeginTxFailureOnBookmark() - { - Bookmark illegalBookmark = InternalBookmark.parse( "Illegal Bookmark" ); - session = neo4j.driver().asyncSession( builder().withBookmarks( illegalBookmark ).build() ); - assertThrows( ClientException.class, () -> await( session.beginTransactionAsync() ) ); - assertThrows( ClientException.class, () -> await( session.runAsync( "RETURN 'Hello!'" ) ) ); + @EnabledOnNeo4jWith(BOLT_V3) + void shouldNotRunAfterBeginTxFailureOnBookmark() { + Bookmark illegalBookmark = InternalBookmark.parse("Illegal Bookmark"); + session = neo4j.driver() + .asyncSession(builder().withBookmarks(illegalBookmark).build()); + assertThrows(ClientException.class, () -> await(session.beginTransactionAsync())); + assertThrows(ClientException.class, () -> await(session.runAsync("RETURN 'Hello!'"))); } @Test - void shouldExecuteReadTransactionUntilSuccessWhenWorkThrows() - { + void shouldExecuteReadTransactionUntilSuccessWhenWorkThrows() { int maxFailures = 1; - CompletionStage result = session.readTransactionAsync( new AsyncTransactionWork>() - { - final AtomicInteger failures = new AtomicInteger(); - - @Override - public CompletionStage execute( AsyncTransaction tx ) - { - if ( failures.getAndIncrement() < maxFailures ) - { - throw new SessionExpiredException( "Oh!" ); - } - return tx.runAsync( "UNWIND range(1, 10) AS x RETURN count(x)" ) - .thenCompose( ResultCursor::singleAsync ) - .thenApply( record -> record.get( 0 ).asInt() ); - } - } ); + CompletionStage result = + session.readTransactionAsync(new AsyncTransactionWork>() { + final AtomicInteger failures = new AtomicInteger(); + + @Override + public CompletionStage execute(AsyncTransaction tx) { + if (failures.getAndIncrement() < maxFailures) { + throw new SessionExpiredException("Oh!"); + } + return tx.runAsync("UNWIND range(1, 10) AS x RETURN count(x)") + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> record.get(0).asInt()); + } + }); - assertEquals( 10, await( result ).intValue() ); + assertEquals(10, await(result).intValue()); } @Test - void shouldExecuteWriteTransactionUntilSuccessWhenWorkThrows() - { + void shouldExecuteWriteTransactionUntilSuccessWhenWorkThrows() { int maxFailures = 2; - CompletionStage result = session.writeTransactionAsync( new AsyncTransactionWork>() - { - final AtomicInteger failures = new AtomicInteger(); - - @Override - public CompletionStage execute( AsyncTransaction tx ) - { - if ( failures.getAndIncrement() < maxFailures ) - { - throw new ServiceUnavailableException( "Oh!" ); - } - return tx.runAsync( "CREATE (n1:TestNode), (n2:TestNode) RETURN 2" ) - .thenCompose( ResultCursor::singleAsync ) - .thenApply( record -> record.get( 0 ).asInt() ); - } - } ); + CompletionStage result = + session.writeTransactionAsync(new AsyncTransactionWork>() { + final AtomicInteger failures = new AtomicInteger(); + + @Override + public CompletionStage execute(AsyncTransaction tx) { + if (failures.getAndIncrement() < maxFailures) { + throw new ServiceUnavailableException("Oh!"); + } + return tx.runAsync("CREATE (n1:TestNode), (n2:TestNode) RETURN 2") + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> record.get(0).asInt()); + } + }); - assertEquals( 2, await( result ).intValue() ); - assertEquals( 2, countNodesByLabel( "TestNode" ) ); + assertEquals(2, await(result).intValue()); + assertEquals(2, countNodesByLabel("TestNode")); } @Test - void shouldExecuteReadTransactionUntilSuccessWhenWorkFails() - { + void shouldExecuteReadTransactionUntilSuccessWhenWorkFails() { int maxFailures = 3; - CompletionStage result = session.readTransactionAsync( new AsyncTransactionWork>() - { - final AtomicInteger failures = new AtomicInteger(); - - @Override - public CompletionStage execute( AsyncTransaction tx ) - { - return tx.runAsync( "RETURN 42" ) - .thenCompose( ResultCursor::singleAsync ) - .thenApply( record -> record.get( 0 ).asInt() ) - .thenCompose( result -> - { - if ( failures.getAndIncrement() < maxFailures ) - { - return failedFuture( new TransientException( "A", "B" ) ); - } - return completedFuture( result ); - } ); - } - } ); + CompletionStage result = + session.readTransactionAsync(new AsyncTransactionWork>() { + final AtomicInteger failures = new AtomicInteger(); + + @Override + public CompletionStage execute(AsyncTransaction tx) { + return tx.runAsync("RETURN 42") + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> record.get(0).asInt()) + .thenCompose(result -> { + if (failures.getAndIncrement() < maxFailures) { + return failedFuture(new TransientException("A", "B")); + } + return completedFuture(result); + }); + } + }); - assertEquals( 42, await( result ).intValue() ); + assertEquals(42, await(result).intValue()); } @Test - void shouldExecuteWriteTransactionUntilSuccessWhenWorkFails() - { + void shouldExecuteWriteTransactionUntilSuccessWhenWorkFails() { int maxFailures = 2; - CompletionStage result = session.writeTransactionAsync( new AsyncTransactionWork>() - { - final AtomicInteger failures = new AtomicInteger(); - - @Override - public CompletionStage execute( AsyncTransaction tx ) - { - return tx.runAsync( "CREATE (:MyNode) RETURN 'Hello'" ) - .thenCompose( ResultCursor::singleAsync ) - .thenApply( record -> record.get( 0 ).asString() ) - .thenCompose( result -> - { - if ( failures.getAndIncrement() < maxFailures ) - { - return failedFuture( new ServiceUnavailableException( "Hi" ) ); - } - return completedFuture( result ); - } ); - } - } ); + CompletionStage result = + session.writeTransactionAsync(new AsyncTransactionWork>() { + final AtomicInteger failures = new AtomicInteger(); - assertEquals( "Hello", await( result ) ); - assertEquals( 1, countNodesByLabel( "MyNode" ) ); + @Override + public CompletionStage execute(AsyncTransaction tx) { + return tx.runAsync("CREATE (:MyNode) RETURN 'Hello'") + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> record.get(0).asString()) + .thenCompose(result -> { + if (failures.getAndIncrement() < maxFailures) { + return failedFuture(new ServiceUnavailableException("Hi")); + } + return completedFuture(result); + }); + } + }); + + assertEquals("Hello", await(result)); + assertEquals(1, countNodesByLabel("MyNode")); } @Test - void shouldNotPropagateRunFailureWhenClosed() - { - session.runAsync( "RETURN 10 / 0" ); + void shouldNotPropagateRunFailureWhenClosed() { + session.runAsync("RETURN 10 / 0"); - await( session.closeAsync() ); + await(session.closeAsync()); } @Test - void shouldPropagateRunFailureImmediately() - { - ClientException e = assertThrows( ClientException.class, () -> await( session.runAsync( "RETURN 10 / 0" ) ) ); + void shouldPropagateRunFailureImmediately() { + ClientException e = assertThrows(ClientException.class, () -> await(session.runAsync("RETURN 10 / 0"))); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + assertThat(e.getMessage(), containsString("/ by zero")); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void shouldNotPropagateFailureWhenStreamingIsCancelled() - { - session.runAsync( "UNWIND range(20000, 0, -1) AS x RETURN 10 / x" ); + @EnabledOnNeo4jWith(BOLT_V4) + void shouldNotPropagateFailureWhenStreamingIsCancelled() { + session.runAsync("UNWIND range(20000, 0, -1) AS x RETURN 10 / x"); - await( session.closeAsync() ); + await(session.closeAsync()); } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void shouldNotPropagateBlockedPullAllFailureWhenClosed() - { - await( session.runAsync( "UNWIND range(20000, 0, -1) AS x RETURN 10 / x" ) ); + @EnabledOnNeo4jWith(BOLT_V4) + void shouldNotPropagateBlockedPullAllFailureWhenClosed() { + await(session.runAsync("UNWIND range(20000, 0, -1) AS x RETURN 10 / x")); - await( session.closeAsync() ); + await(session.closeAsync()); } @Test - void shouldCloseCleanlyWhenRunErrorConsumed() - { - ClientException e = assertThrows( ClientException.class, () -> await( session.runAsync( "SomeWrongQuery" ) ) ); + void shouldCloseCleanlyWhenRunErrorConsumed() { + ClientException e = assertThrows(ClientException.class, () -> await(session.runAsync("SomeWrongQuery"))); - assertThat( e.getMessage(), startsWith( "Invalid input" ) ); - assertNull( await( session.closeAsync() ) ); + assertThat(e.getMessage(), startsWith("Invalid input")); + assertNull(await(session.closeAsync())); } @Test - void shouldCloseCleanlyWhenPullAllErrorConsumed() - { - ResultCursor cursor = await( session.runAsync( "UNWIND range(10, 0, -1) AS x RETURN 1 / x" ) ); + void shouldCloseCleanlyWhenPullAllErrorConsumed() { + ResultCursor cursor = await(session.runAsync("UNWIND range(10, 0, -1) AS x RETURN 1 / x")); - ClientException e = assertThrows( ClientException.class, () -> await( cursor.consumeAsync() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); - assertNull( await( session.closeAsync() ) ); + ClientException e = assertThrows(ClientException.class, () -> await(cursor.consumeAsync())); + assertThat(e.getMessage(), containsString("/ by zero")); + assertNull(await(session.closeAsync())); } @Test - void shouldNotPropagateFailureInCloseFromPreviousRun() - { - session.runAsync( "CREATE ()" ); - session.runAsync( "CREATE ()" ); - session.runAsync( "CREATE ()" ); - session.runAsync( "RETURN invalid" ); + void shouldNotPropagateFailureInCloseFromPreviousRun() { + session.runAsync("CREATE ()"); + session.runAsync("CREATE ()"); + session.runAsync("CREATE ()"); + session.runAsync("RETURN invalid"); - await( session.closeAsync() ); + await(session.closeAsync()); } @Test - void shouldCloseCleanlyAfterFailure() - { - CompletionStage runWithOpenTx = session.beginTransactionAsync() - .thenCompose( tx -> session.runAsync( "RETURN 1" ) ); + void shouldCloseCleanlyAfterFailure() { + CompletionStage runWithOpenTx = + session.beginTransactionAsync().thenCompose(tx -> session.runAsync("RETURN 1")); - ClientException e = assertThrows( ClientException.class, () -> await( runWithOpenTx ) ); - assertThat( e.getMessage(), startsWith( "Queries cannot be run directly on a session with an open transaction" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(runWithOpenTx)); + assertThat(e.getMessage(), startsWith("Queries cannot be run directly on a session with an open transaction")); - await( session.closeAsync() ); + await(session.closeAsync()); } @Test - void shouldPropagateFailureFromFirstIllegalQuery() - { - CompletionStage allQueries = session.runAsync( "CREATE (:Node1)" ) - .thenCompose( ignore -> session.runAsync( "CREATE (:Node2)" ) ) - .thenCompose( ignore -> session.runAsync( "RETURN invalid" ) ) - .thenCompose( ignore -> session.runAsync( "CREATE (:Node3)" ) ); + void shouldPropagateFailureFromFirstIllegalQuery() { + CompletionStage allQueries = session.runAsync("CREATE (:Node1)") + .thenCompose(ignore -> session.runAsync("CREATE (:Node2)")) + .thenCompose(ignore -> session.runAsync("RETURN invalid")) + .thenCompose(ignore -> session.runAsync("CREATE (:Node3)")); - ClientException e = assertThrows( ClientException.class, () -> await( allQueries ) ); - assertThat( e, is( syntaxError( "Variable `invalid` not defined" ) ) ); + ClientException e = assertThrows(ClientException.class, () -> await(allQueries)); + assertThat(e, is(syntaxError("Variable `invalid` not defined"))); - assertEquals( 1, countNodesByLabel( "Node1" ) ); - assertEquals( 1, countNodesByLabel( "Node2" ) ); - assertEquals( 0, countNodesByLabel( "Node3" ) ); + assertEquals(1, countNodesByLabel("Node1")); + assertEquals(1, countNodesByLabel("Node2")); + assertEquals(0, countNodesByLabel("Node3")); } @Test - void shouldAllowReturningNullFromAsyncTransactionFunction() - { - CompletionStage readResult = session.readTransactionAsync( tx -> null ); - assertNull( await( readResult ) ); + void shouldAllowReturningNullFromAsyncTransactionFunction() { + CompletionStage readResult = session.readTransactionAsync(tx -> null); + assertNull(await(readResult)); - CompletionStage writeResult = session.writeTransactionAsync( tx -> null ); - assertNull( await( writeResult ) ); + CompletionStage writeResult = session.writeTransactionAsync(tx -> null); + assertNull(await(writeResult)); } - private Future>> runNestedQueries( ResultCursor inputCursor ) - { + private Future>> runNestedQueries(ResultCursor inputCursor) { CompletableFuture>> resultFuture = new CompletableFuture<>(); - runNestedQueries( inputCursor, new ArrayList<>(), resultFuture ); + runNestedQueries(inputCursor, new ArrayList<>(), resultFuture); return resultFuture; } - private void runNestedQueries( ResultCursor inputCursor, List> stages, - CompletableFuture>> resultFuture ) - { + private void runNestedQueries( + ResultCursor inputCursor, + List> stages, + CompletableFuture>> resultFuture) { final CompletionStage recordResponse = inputCursor.nextAsync(); - stages.add( recordResponse ); - - recordResponse.whenComplete( ( record, error ) -> - { - if ( error != null ) - { - resultFuture.completeExceptionally( error ); - } - else if ( record != null ) - { - runNestedQuery( inputCursor, record, stages, resultFuture ); - } - else - { - resultFuture.complete( stages ); - } - } ); - } - - private void runNestedQuery( ResultCursor inputCursor, Record record, - List> stages, CompletableFuture>> resultFuture ) - { - Node node = record.get( 0 ).asNode(); - long id = node.get( "id" ).asLong(); + stages.add(recordResponse); + + recordResponse.whenComplete((record, error) -> { + if (error != null) { + resultFuture.completeExceptionally(error); + } else if (record != null) { + runNestedQuery(inputCursor, record, stages, resultFuture); + } else { + resultFuture.complete(stages); + } + }); + } + + private void runNestedQuery( + ResultCursor inputCursor, + Record record, + List> stages, + CompletableFuture>> resultFuture) { + Node node = record.get(0).asNode(); + long id = node.get("id").asLong(); long age = id * 10; - CompletionStage response = - session.runAsync( "MATCH (p:Person {id: $id}) SET p.age = $age RETURN p", - parameters( "id", id, "age", age ) ); + CompletionStage response = session.runAsync( + "MATCH (p:Person {id: $id}) SET p.age = $age RETURN p", parameters("id", id, "age", age)); - response.whenComplete( ( cursor, error ) -> - { - if ( error != null ) - { - resultFuture.completeExceptionally( Futures.completionExceptionCause( error ) ); - } - else - { - stages.add( cursor.nextAsync() ); - runNestedQueries( inputCursor, stages, resultFuture ); - } - } ); + response.whenComplete((cursor, error) -> { + if (error != null) { + resultFuture.completeExceptionally(Futures.completionExceptionCause(error)); + } else { + stages.add(cursor.nextAsync()); + runNestedQueries(inputCursor, stages, resultFuture); + } + }); } - private long countNodesByLabel( String label ) - { - CompletionStage countStage = session.runAsync( "MATCH (n:" + label + ") RETURN count(n)" ) - .thenCompose( ResultCursor::singleAsync ) - .thenApply( record -> record.get( 0 ).asLong() ); + private long countNodesByLabel(String label) { + CompletionStage countStage = session.runAsync("MATCH (n:" + label + ") RETURN count(n)") + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> record.get(0).asLong()); - return await( countStage ); + return await(countStage); } - private void testForEach( String query, int expectedSeenRecords ) - { - ResultCursor cursor = await( session.runAsync( query ) ); + private void testForEach(String query, int expectedSeenRecords) { + ResultCursor cursor = await(session.runAsync(query)); AtomicInteger recordsSeen = new AtomicInteger(); - CompletionStage forEachDone = cursor.forEachAsync( record -> recordsSeen.incrementAndGet() ); - ResultSummary summary = await( forEachDone ); + CompletionStage forEachDone = cursor.forEachAsync(record -> recordsSeen.incrementAndGet()); + ResultSummary summary = await(forEachDone); - assertNotNull( summary ); - assertEquals( query, summary.query().text() ); - assertEquals( emptyMap(), summary.query().parameters().asMap() ); - assertEquals( expectedSeenRecords, recordsSeen.get() ); + assertNotNull(summary); + assertEquals(query, summary.query().text()); + assertEquals(emptyMap(), summary.query().parameters().asMap()); + assertEquals(expectedSeenRecords, recordsSeen.get()); } - private void testList( String query, List expectedList ) - { - ResultCursor cursor = await( session.runAsync( query ) ); - List records = await( cursor.listAsync() ); + private void testList(String query, List expectedList) { + ResultCursor cursor = await(session.runAsync(query)); + List records = await(cursor.listAsync()); List actualList = new ArrayList<>(); - for ( Record record : records ) - { - actualList.add( record.get( 0 ).asObject() ); + for (Record record : records) { + actualList.add(record.get(0).asObject()); } - assertEquals( expectedList, actualList ); + assertEquals(expectedList, actualList); } - private void testConsume( String query ) - { - ResultCursor cursor = await( session.runAsync( query ) ); - ResultSummary summary = await( cursor.consumeAsync() ); + private void testConsume(String query) { + ResultCursor cursor = await(session.runAsync(query)); + ResultSummary summary = await(cursor.consumeAsync()); - assertNotNull( summary ); - assertEquals( query, summary.query().text() ); - assertEquals( emptyMap(), summary.query().parameters().asMap() ); + assertNotNull(summary); + assertEquals(query, summary.query().text()); + assertEquals(emptyMap(), summary.query().parameters().asMap()); // no records should be available, they should all be consumed - assertThrows( ResultConsumedException.class, () -> await( cursor.nextAsync() ) ); + assertThrows(ResultConsumedException.class, () -> await(cursor.nextAsync())); } - private static class InvocationTrackingWork implements AsyncTransactionWork> - { + private static class InvocationTrackingWork implements AsyncTransactionWork> { final String query; final AtomicInteger invocationCount; Iterator asyncFailures = emptyIterator(); Iterator syncFailures = emptyIterator(); - InvocationTrackingWork( String query ) - { + InvocationTrackingWork(String query) { this.query = query; this.invocationCount = new AtomicInteger(); } - InvocationTrackingWork withAsyncFailures( RuntimeException... failures ) - { - asyncFailures = Arrays.asList( failures ).iterator(); + InvocationTrackingWork withAsyncFailures(RuntimeException... failures) { + asyncFailures = Arrays.asList(failures).iterator(); return this; } - InvocationTrackingWork withSyncFailures( RuntimeException... failures ) - { - syncFailures = Arrays.asList( failures ).iterator(); + InvocationTrackingWork withSyncFailures(RuntimeException... failures) { + syncFailures = Arrays.asList(failures).iterator(); return this; } - int invocationCount() - { + int invocationCount() { return invocationCount.get(); } @Override - public CompletionStage execute( AsyncTransaction tx ) - { + public CompletionStage execute(AsyncTransaction tx) { invocationCount.incrementAndGet(); - if ( syncFailures.hasNext() ) - { + if (syncFailures.hasNext()) { throw syncFailures.next(); } CompletableFuture resultFuture = new CompletableFuture<>(); - tx.runAsync( query ).whenComplete( ( cursor, error ) -> - processQueryResult( cursor, Futures.completionExceptionCause( error ), resultFuture ) ); + tx.runAsync(query) + .whenComplete((cursor, error) -> + processQueryResult(cursor, Futures.completionExceptionCause(error), resultFuture)); return resultFuture; } - private void processQueryResult( ResultCursor cursor, Throwable error, - CompletableFuture resultFuture ) - { - if ( error != null ) - { - resultFuture.completeExceptionally( error ); + private void processQueryResult(ResultCursor cursor, Throwable error, CompletableFuture resultFuture) { + if (error != null) { + resultFuture.completeExceptionally(error); return; } - cursor.nextAsync().whenComplete( ( record, fetchError ) -> - processFetchResult( record, Futures.completionExceptionCause( fetchError ), resultFuture ) ); + cursor.nextAsync() + .whenComplete((record, fetchError) -> + processFetchResult(record, Futures.completionExceptionCause(fetchError), resultFuture)); } - private void processFetchResult( Record record, Throwable error, CompletableFuture resultFuture ) - { - if ( error != null ) - { - resultFuture.completeExceptionally( error ); + private void processFetchResult(Record record, Throwable error, CompletableFuture resultFuture) { + if (error != null) { + resultFuture.completeExceptionally(error); return; } - if ( record == null ) - { - resultFuture.completeExceptionally( new AssertionError( "Record not available" ) ); + if (record == null) { + resultFuture.completeExceptionally(new AssertionError("Record not available")); return; } - if ( asyncFailures.hasNext() ) - { - resultFuture.completeExceptionally( asyncFailures.next() ); - } - else - { - resultFuture.complete( record ); + if (asyncFailures.hasNext()) { + resultFuture.completeExceptionally(asyncFailures.next()); + } else { + resultFuture.complete(record); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionServerRestartIT.java b/driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionServerRestartIT.java index 98c2a5e90f..7370eb0d0d 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionServerRestartIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionServerRestartIT.java @@ -18,13 +18,16 @@ */ package org.neo4j.driver.integration.async; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.util.TestUtil.await; + +import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.List; - import org.neo4j.driver.Record; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.AsyncTransaction; @@ -33,94 +36,78 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.util.TestUtil.await; - @ParallelizableIT -class AsyncSessionServerRestartIT -{ +class AsyncSessionServerRestartIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private AsyncSession session; @BeforeEach - void setUp() - { + void setUp() { session = neo4j.driver().asyncSession(); } @AfterEach - void tearDown() - { + void tearDown() { session.closeAsync(); } @Test - void shouldFailWhenServerIsRestarted() - { + void shouldFailWhenServerIsRestarted() { int queryCount = 10_000; - String query = "UNWIND range(1, 100) AS x " + - "CREATE (n1:Node {value: x})-[r:LINKED {value: x}]->(n2:Node {value: x}) " + - "DETACH DELETE n1, n2 " + - "RETURN x"; + String query = "UNWIND range(1, 100) AS x " + + "CREATE (n1:Node {value: x})-[r:LINKED {value: x}]->(n2:Node {value: x}) " + + "DETACH DELETE n1, n2 " + + "RETURN x"; - assertThrows( ServiceUnavailableException.class, () -> - { - for ( int i = 0; i < queryCount; i++ ) - { - ResultCursor cursor = await( session.runAsync( query ) ); + assertThrows(ServiceUnavailableException.class, () -> { + for (int i = 0; i < queryCount; i++) { + ResultCursor cursor = await(session.runAsync(query)); - if ( i == 0 ) - { + if (i == 0) { neo4j.stopDb(); } - List records = await( cursor.listAsync() ); - assertEquals( 100, records.size() ); + List records = await(cursor.listAsync()); + assertEquals(100, records.size()); } - } ); + }); neo4j.startDb(); } @Test - void shouldRunAfterRunFailureToAcquireConnection() - { + void shouldRunAfterRunFailureToAcquireConnection() { neo4j.stopDb(); - assertThrows( ServiceUnavailableException.class, () -> - { - ResultCursor cursor = await( session.runAsync( "RETURN 42" ) ); - await( cursor.nextAsync() ); - } ); + assertThrows(ServiceUnavailableException.class, () -> { + ResultCursor cursor = await(session.runAsync("RETURN 42")); + await(cursor.nextAsync()); + }); neo4j.startDb(); - ResultCursor cursor2 = await( session.runAsync( "RETURN 42" ) ); - Record record = await( cursor2.singleAsync() ); - assertEquals( 42, record.get( 0 ).asInt() ); + ResultCursor cursor2 = await(session.runAsync("RETURN 42")); + Record record = await(cursor2.singleAsync()); + assertEquals(42, record.get(0).asInt()); } @Test - void shouldBeginTxAfterRunFailureToAcquireConnection() - { + void shouldBeginTxAfterRunFailureToAcquireConnection() { neo4j.stopDb(); - assertThrows( ServiceUnavailableException.class, () -> - { - ResultCursor cursor = await( session.runAsync( "RETURN 42" ) ); - await( cursor.consumeAsync() ); - } ); + assertThrows(ServiceUnavailableException.class, () -> { + ResultCursor cursor = await(session.runAsync("RETURN 42")); + await(cursor.consumeAsync()); + }); neo4j.startDb(); - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor2 = await( tx.runAsync( "RETURN 42" ) ); - Record record = await( cursor2.singleAsync() ); - assertEquals( 42, record.get( 0 ).asInt() ); - assertNull( await( tx.rollbackAsync() ) ); + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor2 = await(tx.runAsync("RETURN 42")); + Record record = await(cursor2.singleAsync()); + assertEquals(42, record.get(0).asInt()); + assertNull(await(tx.rollbackAsync())); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/async/AsyncTransactionIT.java b/driver/src/test/java/org/neo4j/driver/integration/async/AsyncTransactionIT.java index 16fa94fff3..b1e95d2d45 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/async/AsyncTransactionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/async/AsyncTransactionIT.java @@ -18,10 +18,27 @@ */ package org.neo4j.driver.integration.async; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Collections.emptyMap; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.InternalBookmark.parse; +import static org.neo4j.driver.internal.util.Iterables.single; +import static org.neo4j.driver.internal.util.Matchers.containsResultAvailableAfterAndResultConsumedAfter; +import static org.neo4j.driver.internal.util.Matchers.syntaxError; +import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; +import static org.neo4j.driver.util.TestUtil.await; import java.io.IOException; import java.util.ArrayList; @@ -32,7 +49,10 @@ import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicInteger; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; import org.neo4j.driver.Record; @@ -50,776 +70,693 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.util.Collections.emptyMap; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.InternalBookmark.parse; -import static org.neo4j.driver.internal.util.Iterables.single; -import static org.neo4j.driver.internal.util.Matchers.containsResultAvailableAfterAndResultConsumedAfter; -import static org.neo4j.driver.internal.util.Matchers.syntaxError; -import static org.neo4j.driver.util.TestUtil.assertNoCircularReferences; -import static org.neo4j.driver.util.TestUtil.await; - @ParallelizableIT -class AsyncTransactionIT -{ +class AsyncTransactionIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private AsyncSession session; @BeforeEach - void setUp() - { + void setUp() { session = neo4j.driver().asyncSession(); } @AfterEach - void tearDown() - { + void tearDown() { session.closeAsync(); } @Test - void shouldBePossibleToCommitEmptyTx() - { + void shouldBePossibleToCommitEmptyTx() { Bookmark bookmarkBefore = session.lastBookmark(); - AsyncTransaction tx = await( session.beginTransactionAsync() ); - assertThat( await( tx.commitAsync() ), is( nullValue() ) ); + AsyncTransaction tx = await(session.beginTransactionAsync()); + assertThat(await(tx.commitAsync()), is(nullValue())); Bookmark bookmarkAfter = session.lastBookmark(); - assertNotNull( bookmarkAfter ); - assertNotEquals( bookmarkBefore, bookmarkAfter ); + assertNotNull(bookmarkAfter); + assertNotEquals(bookmarkBefore, bookmarkAfter); } @Test - void shouldBePossibleToRollbackEmptyTx() - { + void shouldBePossibleToRollbackEmptyTx() { Bookmark bookmarkBefore = session.lastBookmark(); - AsyncTransaction tx = await( session.beginTransactionAsync() ); - assertThat( await( tx.rollbackAsync() ), is( nullValue() ) ); + AsyncTransaction tx = await(session.beginTransactionAsync()); + assertThat(await(tx.rollbackAsync()), is(nullValue())); Bookmark bookmarkAfter = session.lastBookmark(); - assertEquals( bookmarkBefore, bookmarkAfter ); + assertEquals(bookmarkBefore, bookmarkAfter); } @Test - void shouldBePossibleToRunSingleQueryAndCommit() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldBePossibleToRunSingleQueryAndCommit() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - ResultCursor cursor = await( tx.runAsync( "CREATE (n:Node {id: 42}) RETURN n" ) ); + ResultCursor cursor = await(tx.runAsync("CREATE (n:Node {id: 42}) RETURN n")); - Record record = await( cursor.nextAsync() ); - assertNotNull( record ); - Node node = record.get( 0 ).asNode(); - assertEquals( "Node", single( node.labels() ) ); - assertEquals( 42, node.get( "id" ).asInt() ); - assertNull( await( cursor.nextAsync() ) ); + Record record = await(cursor.nextAsync()); + assertNotNull(record); + Node node = record.get(0).asNode(); + assertEquals("Node", single(node.labels())); + assertEquals(42, node.get("id").asInt()); + assertNull(await(cursor.nextAsync())); - assertNull( await( tx.commitAsync() ) ); - assertEquals( 1, countNodes( 42 ) ); + assertNull(await(tx.commitAsync())); + assertEquals(1, countNodes(42)); } @Test - void shouldBePossibleToRunSingleQueryAndRollback() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldBePossibleToRunSingleQueryAndRollback() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - ResultCursor cursor = await( tx.runAsync( "CREATE (n:Node {id: 4242}) RETURN n" ) ); - Record record = await( cursor.nextAsync() ); - assertNotNull( record ); - Node node = record.get( 0 ).asNode(); - assertEquals( "Node", single( node.labels() ) ); - assertEquals( 4242, node.get( "id" ).asInt() ); - assertNull( await( cursor.nextAsync() ) ); + ResultCursor cursor = await(tx.runAsync("CREATE (n:Node {id: 4242}) RETURN n")); + Record record = await(cursor.nextAsync()); + assertNotNull(record); + Node node = record.get(0).asNode(); + assertEquals("Node", single(node.labels())); + assertEquals(4242, node.get("id").asInt()); + assertNull(await(cursor.nextAsync())); - assertNull( await( tx.rollbackAsync() ) ); - assertEquals( 0, countNodes( 4242 ) ); + assertNull(await(tx.rollbackAsync())); + assertEquals(0, countNodes(4242)); } @Test - void shouldBePossibleToRunMultipleQueriesAndCommit() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldBePossibleToRunMultipleQueriesAndCommit() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - ResultCursor cursor1 = await( tx.runAsync( "CREATE (n:Node {id: 1})" ) ); - assertNull( await( cursor1.nextAsync() ) ); + ResultCursor cursor1 = await(tx.runAsync("CREATE (n:Node {id: 1})")); + assertNull(await(cursor1.nextAsync())); - ResultCursor cursor2 = await( tx.runAsync( "CREATE (n:Node {id: 2})" ) ); - assertNull( await( cursor2.nextAsync() ) ); + ResultCursor cursor2 = await(tx.runAsync("CREATE (n:Node {id: 2})")); + assertNull(await(cursor2.nextAsync())); - ResultCursor cursor3 = await( tx.runAsync( "CREATE (n:Node {id: 2})" ) ); - assertNull( await( cursor3.nextAsync() ) ); + ResultCursor cursor3 = await(tx.runAsync("CREATE (n:Node {id: 2})")); + assertNull(await(cursor3.nextAsync())); - assertNull( await( tx.commitAsync() ) ); - assertEquals( 1, countNodes( 1 ) ); - assertEquals( 2, countNodes( 2 ) ); + assertNull(await(tx.commitAsync())); + assertEquals(1, countNodes(1)); + assertEquals(2, countNodes(2)); } @Test - void shouldBePossibleToRunMultipleQueriesAndCommitWithoutWaiting() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldBePossibleToRunMultipleQueriesAndCommitWithoutWaiting() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - tx.runAsync( "CREATE (n:Node {id: 1})" ); - tx.runAsync( "CREATE (n:Node {id: 2})" ); - tx.runAsync( "CREATE (n:Node {id: 1})" ); + tx.runAsync("CREATE (n:Node {id: 1})"); + tx.runAsync("CREATE (n:Node {id: 2})"); + tx.runAsync("CREATE (n:Node {id: 1})"); - assertNull( await( tx.commitAsync() ) ); - assertEquals( 1, countNodes( 2 ) ); - assertEquals( 2, countNodes( 1 ) ); + assertNull(await(tx.commitAsync())); + assertEquals(1, countNodes(2)); + assertEquals(2, countNodes(1)); } @Test - void shouldBePossibleToRunMultipleQueriesAndRollback() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldBePossibleToRunMultipleQueriesAndRollback() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - ResultCursor cursor1 = await( tx.runAsync( "CREATE (n:Node {id: 1})" ) ); - assertNull( await( cursor1.nextAsync() ) ); + ResultCursor cursor1 = await(tx.runAsync("CREATE (n:Node {id: 1})")); + assertNull(await(cursor1.nextAsync())); - ResultCursor cursor2 = await( tx.runAsync( "CREATE (n:Node {id: 42})" ) ); - assertNull( await( cursor2.nextAsync() ) ); + ResultCursor cursor2 = await(tx.runAsync("CREATE (n:Node {id: 42})")); + assertNull(await(cursor2.nextAsync())); - assertNull( await( tx.rollbackAsync() ) ); - assertEquals( 0, countNodes( 1 ) ); - assertEquals( 0, countNodes( 42 ) ); + assertNull(await(tx.rollbackAsync())); + assertEquals(0, countNodes(1)); + assertEquals(0, countNodes(42)); } @Test - void shouldBePossibleToRunMultipleQueriesAndRollbackWithoutWaiting() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldBePossibleToRunMultipleQueriesAndRollbackWithoutWaiting() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - tx.runAsync( "CREATE (n:Node {id: 1})" ); - tx.runAsync( "CREATE (n:Node {id: 42})" ); + tx.runAsync("CREATE (n:Node {id: 1})"); + tx.runAsync("CREATE (n:Node {id: 42})"); - assertNull( await( tx.rollbackAsync() ) ); - assertEquals( 0, countNodes( 1 ) ); - assertEquals( 0, countNodes( 42 ) ); + assertNull(await(tx.rollbackAsync())); + assertEquals(0, countNodes(1)); + assertEquals(0, countNodes(42)); } @Test - void shouldFailToCommitAfterSingleWrongQuery() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldFailToCommitAfterSingleWrongQuery() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - Exception e = assertThrows( Exception.class, () -> await( tx.runAsync( "RETURN" ) ) ); - assertThat( e, is( syntaxError() ) ); + Exception e = assertThrows(Exception.class, () -> await(tx.runAsync("RETURN"))); + assertThat(e, is(syntaxError())); - assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); + assertThrows(ClientException.class, () -> await(tx.commitAsync())); } @Test - void shouldAllowRollbackAfterSingleWrongQuery() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldAllowRollbackAfterSingleWrongQuery() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - Exception e = assertThrows( Exception.class, () -> await( tx.runAsync( "RETURN" ) ) ); - assertThat( e, is( syntaxError() ) ); - assertThat( await( tx.rollbackAsync() ), is( nullValue() ) ); + Exception e = assertThrows(Exception.class, () -> await(tx.runAsync("RETURN"))); + assertThat(e, is(syntaxError())); + assertThat(await(tx.rollbackAsync()), is(nullValue())); } @Test - void shouldFailToCommitAfterCoupleCorrectAndSingleWrongQuery() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldFailToCommitAfterCoupleCorrectAndSingleWrongQuery() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - ResultCursor cursor1 = await( tx.runAsync( "CREATE (n:Node) RETURN n" ) ); - Record record1 = await( cursor1.nextAsync() ); - assertNotNull( record1 ); - assertTrue( record1.get( 0 ).asNode().hasLabel( "Node" ) ); + ResultCursor cursor1 = await(tx.runAsync("CREATE (n:Node) RETURN n")); + Record record1 = await(cursor1.nextAsync()); + assertNotNull(record1); + assertTrue(record1.get(0).asNode().hasLabel("Node")); - ResultCursor cursor2 = await( tx.runAsync( "RETURN 42" ) ); - Record record2 = await( cursor2.nextAsync() ); - assertNotNull( record2 ); - assertEquals( 42, record2.get( 0 ).asInt() ); + ResultCursor cursor2 = await(tx.runAsync("RETURN 42")); + Record record2 = await(cursor2.nextAsync()); + assertNotNull(record2); + assertEquals(42, record2.get(0).asInt()); - Exception e = assertThrows( Exception.class, () -> await( tx.runAsync( "RETURN" ) ) ); - assertThat( e, is( syntaxError() ) ); + Exception e = assertThrows(Exception.class, () -> await(tx.runAsync("RETURN"))); + assertThat(e, is(syntaxError())); - assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); + assertThrows(ClientException.class, () -> await(tx.commitAsync())); } @Test - void shouldAllowRollbackAfterCoupleCorrectAndSingleWrongQuery() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldAllowRollbackAfterCoupleCorrectAndSingleWrongQuery() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - ResultCursor cursor1 = await( tx.runAsync( "RETURN 4242" ) ); - Record record1 = await( cursor1.nextAsync() ); - assertNotNull( record1 ); - assertEquals( 4242, record1.get( 0 ).asInt() ); + ResultCursor cursor1 = await(tx.runAsync("RETURN 4242")); + Record record1 = await(cursor1.nextAsync()); + assertNotNull(record1); + assertEquals(4242, record1.get(0).asInt()); - ResultCursor cursor2 = await( tx.runAsync( "CREATE (n:Node) DELETE n RETURN 42" ) ); - Record record2 = await( cursor2.nextAsync() ); - assertNotNull( record2 ); - assertEquals( 42, record2.get( 0 ).asInt() ); + ResultCursor cursor2 = await(tx.runAsync("CREATE (n:Node) DELETE n RETURN 42")); + Record record2 = await(cursor2.nextAsync()); + assertNotNull(record2); + assertEquals(42, record2.get(0).asInt()); - Exception e = assertThrows( Exception.class, () -> await( tx.runAsync( "RETURN" ) ) ); - assertThat( e, is( syntaxError() ) ); - assertThat( await( tx.rollbackAsync() ), is( nullValue() ) ); + Exception e = assertThrows(Exception.class, () -> await(tx.runAsync("RETURN"))); + assertThat(e, is(syntaxError())); + assertThat(await(tx.rollbackAsync()), is(nullValue())); } @Test - void shouldNotAllowNewQueriesAfterAnIncorrectQuery() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldNotAllowNewQueriesAfterAnIncorrectQuery() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - Exception e1 = assertThrows( Exception.class, () -> await( tx.runAsync( "RETURN" ) ) ); - assertThat( e1, is( syntaxError() ) ); + Exception e1 = assertThrows(Exception.class, () -> await(tx.runAsync("RETURN"))); + assertThat(e1, is(syntaxError())); - ClientException e2 = assertThrows( ClientException.class, () -> tx.runAsync( "CREATE ()" ) ); - assertThat( e2.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); + ClientException e2 = assertThrows(ClientException.class, () -> tx.runAsync("CREATE ()")); + assertThat(e2.getMessage(), startsWith("Cannot run more queries in this transaction")); } @Test - void shouldFailBoBeginTxWithInvalidBookmark() - { - AsyncSession session = neo4j.driver().asyncSession( builder().withBookmarks( parse( "InvalidBookmark" ) ).build() ); + void shouldFailBoBeginTxWithInvalidBookmark() { + AsyncSession session = neo4j.driver() + .asyncSession(builder().withBookmarks(parse("InvalidBookmark")).build()); - ClientException e = assertThrows( ClientException.class, () -> await( session.beginTransactionAsync() ) ); - assertThat( e.getMessage(), containsString( "InvalidBookmark" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(session.beginTransactionAsync())); + assertThat(e.getMessage(), containsString("InvalidBookmark")); } @Test - void shouldFailToCommitWhenCommitted() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - tx.runAsync( "CREATE ()" ); - assertNull( await( tx.commitAsync() ) ); + void shouldFailToCommitWhenCommitted() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + tx.runAsync("CREATE ()"); + assertNull(await(tx.commitAsync())); // should not be possible to commit after commit - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertThat( e.getMessage(), containsString( "transaction has been committed" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertThat(e.getMessage(), containsString("transaction has been committed")); } @Test - void shouldFailToRollbackWhenRolledBack() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - tx.runAsync( "CREATE ()" ); - assertNull( await( tx.rollbackAsync() ) ); + void shouldFailToRollbackWhenRolledBack() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + tx.runAsync("CREATE ()"); + assertNull(await(tx.rollbackAsync())); // should not be possible to rollback after rollback - ClientException e = assertThrows( ClientException.class, () -> await( tx.rollbackAsync() ) ); - assertThat( e.getMessage(), containsString( "transaction has been rolled back" ) ); } + ClientException e = assertThrows(ClientException.class, () -> await(tx.rollbackAsync())); + assertThat(e.getMessage(), containsString("transaction has been rolled back")); + } @Test - void shouldFailToCommitWhenRolledBack() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - tx.runAsync( "CREATE ()" ); - assertNull( await( tx.rollbackAsync() ) ); + void shouldFailToCommitWhenRolledBack() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + tx.runAsync("CREATE ()"); + assertNull(await(tx.rollbackAsync())); // should not be possible to commit after rollback - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertThat( e.getMessage(), containsString( "transaction has been rolled back" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertThat(e.getMessage(), containsString("transaction has been rolled back")); } @Test - void shouldFailToRollbackWhenCommitted() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - tx.runAsync( "CREATE ()" ); - assertNull( await( tx.commitAsync() ) ); + void shouldFailToRollbackWhenCommitted() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + tx.runAsync("CREATE ()"); + assertNull(await(tx.commitAsync())); // should not be possible to rollback after commit - ClientException e = assertThrows( ClientException.class, () -> await( tx.rollbackAsync() ) ); - assertThat( e.getMessage(), containsString( "transaction has been committed" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.rollbackAsync())); + assertThat(e.getMessage(), containsString("transaction has been committed")); } @Test - void shouldExposeQueryKeysForColumnsWithAliases() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "RETURN 1 AS one, 2 AS two, 3 AS three, 4 AS five" ) ); + void shouldExposeQueryKeysForColumnsWithAliases() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("RETURN 1 AS one, 2 AS two, 3 AS three, 4 AS five")); - assertEquals( Arrays.asList( "one", "two", "three", "five" ), cursor.keys() ); + assertEquals(Arrays.asList("one", "two", "three", "five"), cursor.keys()); } @Test - void shouldExposeQueryKeysForColumnsWithoutAliases() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "RETURN 1, 2, 3, 5" ) ); + void shouldExposeQueryKeysForColumnsWithoutAliases() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("RETURN 1, 2, 3, 5")); - assertEquals( Arrays.asList( "1", "2", "3", "5" ), cursor.keys() ); + assertEquals(Arrays.asList("1", "2", "3", "5"), cursor.keys()); } @Test - void shouldExposeResultSummaryForSimpleQuery() - { + void shouldExposeResultSummaryForSimpleQuery() { String query = "CREATE (p1:Person {name: $name1})-[:KNOWS]->(p2:Person {name: $name2}) RETURN p1, p2"; - Value params = parameters( "name1", "Bob", "name2", "John" ); + Value params = parameters("name1", "Bob", "name2", "John"); - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( query, params ) ); - ResultSummary summary = await( cursor.consumeAsync() ); + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync(query, params)); + ResultSummary summary = await(cursor.consumeAsync()); - assertEquals( new Query( query, params ), summary.query() ); - assertEquals( 2, summary.counters().nodesCreated() ); - assertEquals( 2, summary.counters().labelsAdded() ); - assertEquals( 2, summary.counters().propertiesSet() ); - assertEquals( 1, summary.counters().relationshipsCreated() ); - assertEquals( QueryType.READ_WRITE, summary.queryType() ); - assertFalse( summary.hasPlan() ); - assertFalse( summary.hasProfile() ); - assertNull( summary.plan() ); - assertNull( summary.profile() ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); + assertEquals(new Query(query, params), summary.query()); + assertEquals(2, summary.counters().nodesCreated()); + assertEquals(2, summary.counters().labelsAdded()); + assertEquals(2, summary.counters().propertiesSet()); + assertEquals(1, summary.counters().relationshipsCreated()); + assertEquals(QueryType.READ_WRITE, summary.queryType()); + assertFalse(summary.hasPlan()); + assertFalse(summary.hasProfile()); + assertNull(summary.plan()); + assertNull(summary.profile()); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); } @Test - void shouldExposeResultSummaryForExplainQuery() - { + void shouldExposeResultSummaryForExplainQuery() { String query = "EXPLAIN MATCH (n) RETURN n"; - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( query ) ); - ResultSummary summary = await( cursor.consumeAsync() ); - - assertEquals( new Query( query ), summary.query() ); - assertEquals( 0, summary.counters().nodesCreated() ); - assertEquals( 0, summary.counters().propertiesSet() ); - assertEquals( QueryType.READ_ONLY, summary.queryType() ); - assertTrue( summary.hasPlan() ); - assertFalse( summary.hasProfile() ); - assertNotNull( summary.plan() ); + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync(query)); + ResultSummary summary = await(cursor.consumeAsync()); + + assertEquals(new Query(query), summary.query()); + assertEquals(0, summary.counters().nodesCreated()); + assertEquals(0, summary.counters().propertiesSet()); + assertEquals(QueryType.READ_ONLY, summary.queryType()); + assertTrue(summary.hasPlan()); + assertFalse(summary.hasProfile()); + assertNotNull(summary.plan()); // asserting on plan is a bit fragile and can break when server side changes or with different // server versions; that is why do fuzzy assertions in this test based on string content - assertThat( summary.plan().toString().toLowerCase(), containsString( "scan" ) ); - assertNull( summary.profile() ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); - } - - @Test - void shouldExposeResultSummaryForProfileQuery() - { - String query = "PROFILE MERGE (n {name: $name}) " + - "ON CREATE SET n.created = timestamp() " + - "ON MATCH SET n.counter = coalesce(n.counter, 0) + 1"; - - Value params = parameters( "name", "Bob" ); - - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( query, params ) ); - ResultSummary summary = await( cursor.consumeAsync() ); - - assertEquals( new Query( query, params ), summary.query() ); - assertEquals( 1, summary.counters().nodesCreated() ); - assertEquals( 2, summary.counters().propertiesSet() ); - assertEquals( 0, summary.counters().relationshipsCreated() ); - assertEquals( QueryType.WRITE_ONLY, summary.queryType() ); - assertTrue( summary.hasPlan() ); - assertTrue( summary.hasProfile() ); - assertNotNull( summary.plan() ); - assertNotNull( summary.profile() ); + assertThat(summary.plan().toString().toLowerCase(), containsString("scan")); + assertNull(summary.profile()); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); + } + + @Test + void shouldExposeResultSummaryForProfileQuery() { + String query = "PROFILE MERGE (n {name: $name}) " + "ON CREATE SET n.created = timestamp() " + + "ON MATCH SET n.counter = coalesce(n.counter, 0) + 1"; + + Value params = parameters("name", "Bob"); + + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync(query, params)); + ResultSummary summary = await(cursor.consumeAsync()); + + assertEquals(new Query(query, params), summary.query()); + assertEquals(1, summary.counters().nodesCreated()); + assertEquals(2, summary.counters().propertiesSet()); + assertEquals(0, summary.counters().relationshipsCreated()); + assertEquals(QueryType.WRITE_ONLY, summary.queryType()); + assertTrue(summary.hasPlan()); + assertTrue(summary.hasProfile()); + assertNotNull(summary.plan()); + assertNotNull(summary.profile()); // asserting on profile is a bit fragile and can break when server side changes or with different // server versions; that is why do fuzzy assertions in this test based on string content String profileAsString = summary.profile().toString().toLowerCase(); - assertThat( profileAsString, containsString( "hits" ) ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); + assertThat(profileAsString, containsString("hits")); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); } @Test - void shouldPeekRecordFromCursor() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "UNWIND ['a', 'b', 'c'] AS x RETURN x" ) ); + void shouldPeekRecordFromCursor() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("UNWIND ['a', 'b', 'c'] AS x RETURN x")); - assertEquals( "a", await( cursor.peekAsync() ).get( 0 ).asString() ); - assertEquals( "a", await( cursor.peekAsync() ).get( 0 ).asString() ); + assertEquals("a", await(cursor.peekAsync()).get(0).asString()); + assertEquals("a", await(cursor.peekAsync()).get(0).asString()); - assertEquals( "a", await( cursor.nextAsync() ).get( 0 ).asString() ); + assertEquals("a", await(cursor.nextAsync()).get(0).asString()); - assertEquals( "b", await( cursor.peekAsync() ).get( 0 ).asString() ); - assertEquals( "b", await( cursor.peekAsync() ).get( 0 ).asString() ); - assertEquals( "b", await( cursor.peekAsync() ).get( 0 ).asString() ); + assertEquals("b", await(cursor.peekAsync()).get(0).asString()); + assertEquals("b", await(cursor.peekAsync()).get(0).asString()); + assertEquals("b", await(cursor.peekAsync()).get(0).asString()); - assertEquals( "b", await( cursor.nextAsync() ).get( 0 ).asString() ); - assertEquals( "c", await( cursor.nextAsync() ).get( 0 ).asString() ); + assertEquals("b", await(cursor.nextAsync()).get(0).asString()); + assertEquals("c", await(cursor.nextAsync()).get(0).asString()); - assertNull( await( cursor.peekAsync() ) ); - assertNull( await( cursor.nextAsync() ) ); + assertNull(await(cursor.peekAsync())); + assertNull(await(cursor.nextAsync())); - await( tx.rollbackAsync() ); + await(tx.rollbackAsync()); } @Test - void shouldForEachWithEmptyCursor() - { - testForEach( "MATCH (n:SomeReallyStrangeLabel) RETURN n", 0 ); + void shouldForEachWithEmptyCursor() { + testForEach("MATCH (n:SomeReallyStrangeLabel) RETURN n", 0); } @Test - void shouldForEachWithNonEmptyCursor() - { - testForEach( "UNWIND range(1, 12555) AS x CREATE (n:Node {id: x}) RETURN n", 12555 ); + void shouldForEachWithNonEmptyCursor() { + testForEach("UNWIND range(1, 12555) AS x CREATE (n:Node {id: x}) RETURN n", 12555); } @Test - void shouldFailForEachWhenActionFails() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "RETURN 'Hi!'" ) ); + void shouldFailForEachWhenActionFails() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("RETURN 'Hi!'")); RuntimeException error = new RuntimeException(); - RuntimeException e = assertThrows( RuntimeException.class, () -> - { - await( cursor.forEachAsync( record -> - { + RuntimeException e = assertThrows(RuntimeException.class, () -> { + await(cursor.forEachAsync(record -> { throw error; - } ) ); - } ); - assertEquals( error, e ); + })); + }); + assertEquals(error, e); } @Test - void shouldConvertToListWithEmptyCursor() - { - testList( "CREATE (:Person)-[:KNOWS]->(:Person)", Collections.emptyList() ); + void shouldConvertToListWithEmptyCursor() { + testList("CREATE (:Person)-[:KNOWS]->(:Person)", Collections.emptyList()); } @Test - void shouldConvertToListWithNonEmptyCursor() - { - testList( "UNWIND [1, '1', 2, '2', 3, '3'] AS x RETURN x", Arrays.asList( 1L, "1", 2L, "2", 3L, "3" ) ); + void shouldConvertToListWithNonEmptyCursor() { + testList("UNWIND [1, '1', 2, '2', 3, '3'] AS x RETURN x", Arrays.asList(1L, "1", 2L, "2", 3L, "3")); } @Test - void shouldConvertToTransformedListWithEmptyCursor() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "CREATE ()" ) ); - List> maps = await( cursor.listAsync( record -> record.get( 0 ).asMap() ) ); - assertEquals( 0, maps.size() ); + void shouldConvertToTransformedListWithEmptyCursor() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("CREATE ()")); + List> maps = + await(cursor.listAsync(record -> record.get(0).asMap())); + assertEquals(0, maps.size()); } @Test - void shouldConvertToTransformedListWithNonEmptyCursor() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "UNWIND ['a', 'b', 'c'] AS x RETURN x" ) ); - List strings = await( cursor.listAsync( record -> record.get( 0 ).asString() + "!" ) ); - assertEquals( Arrays.asList( "a!", "b!", "c!" ), strings ); + void shouldConvertToTransformedListWithNonEmptyCursor() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("UNWIND ['a', 'b', 'c'] AS x RETURN x")); + List strings = await(cursor.listAsync(record -> record.get(0).asString() + "!")); + assertEquals(Arrays.asList("a!", "b!", "c!"), strings); } @Test - void shouldFailWhenListTransformationFunctionFails() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "RETURN 'Hello'" ) ); - IOException error = new IOException( "World" ); + void shouldFailWhenListTransformationFunctionFails() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("RETURN 'Hello'")); + IOException error = new IOException("World"); - Exception e = assertThrows( Exception.class, () -> - await( cursor.listAsync( record -> - { - throw new CompletionException( error ); - } ) ) ); - assertEquals( error, e ); + Exception e = assertThrows( + Exception.class, + () -> await(cursor.listAsync(record -> { + throw new CompletionException(error); + }))); + assertEquals(error, e); } @Test - void shouldFailToCommitWhenServerIsRestarted() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldFailToCommitWhenServerIsRestarted() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - await( tx.runAsync( "CREATE ()" ) ); + await(tx.runAsync("CREATE ()")); neo4j.stopDb(); - assertThrows( ServiceUnavailableException.class, () -> await( tx.commitAsync() ) ); + assertThrows(ServiceUnavailableException.class, () -> await(tx.commitAsync())); } @Test - void shouldFailSingleWithEmptyCursor() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "MATCH (n:NoSuchLabel) RETURN n" ) ); + void shouldFailSingleWithEmptyCursor() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("MATCH (n:NoSuchLabel) RETURN n")); - NoSuchRecordException e = assertThrows( NoSuchRecordException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), containsString( "result is empty" ) ); + NoSuchRecordException e = assertThrows(NoSuchRecordException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), containsString("result is empty")); } @Test - void shouldFailSingleWithMultiRecordCursor() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "UNWIND ['a', 'b'] AS x RETURN x" ) ); + void shouldFailSingleWithMultiRecordCursor() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("UNWIND ['a', 'b'] AS x RETURN x")); - NoSuchRecordException e = assertThrows( NoSuchRecordException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), startsWith( "Expected a result with a single record" ) ); + NoSuchRecordException e = assertThrows(NoSuchRecordException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), startsWith("Expected a result with a single record")); } @Test - void shouldReturnSingleWithSingleRecordCursor() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "RETURN 'Hello!'" ) ); + void shouldReturnSingleWithSingleRecordCursor() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("RETURN 'Hello!'")); - Record record = await( cursor.singleAsync() ); + Record record = await(cursor.singleAsync()); - assertEquals( "Hello!", record.get( 0 ).asString() ); + assertEquals("Hello!", record.get(0).asString()); } @Test - void shouldPropagateFailureFromFirstRecordInSingleAsync() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "UNWIND [0] AS x RETURN 10 / x" ) ); + void shouldPropagateFailureFromFirstRecordInSingleAsync() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("UNWIND [0] AS x RETURN 10 / x")); - ClientException e = assertThrows( ClientException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), containsString("/ by zero")); } @Test - void shouldNotPropagateFailureFromSecondRecordInSingleAsync() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "UNWIND [1, 0] AS x RETURN 10 / x" ) ); + void shouldNotPropagateFailureFromSecondRecordInSingleAsync() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("UNWIND [1, 0] AS x RETURN 10 / x")); - ClientException e = assertThrows( ClientException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), containsString("/ by zero")); } @Test - void shouldConsumeEmptyCursor() - { - testConsume( "MATCH (n:NoSuchLabel) RETURN n" ); + void shouldConsumeEmptyCursor() { + testConsume("MATCH (n:NoSuchLabel) RETURN n"); } @Test - void shouldConsumeNonEmptyCursor() - { - testConsume( "RETURN 42" ); + void shouldConsumeNonEmptyCursor() { + testConsume("RETURN 42"); } @Test - void shouldFailToRunQueryAfterCommit() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - tx.runAsync( "CREATE (:MyLabel)" ); - assertNull( await( tx.commitAsync() ) ); + void shouldFailToRunQueryAfterCommit() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + tx.runAsync("CREATE (:MyLabel)"); + assertNull(await(tx.commitAsync())); - ResultCursor cursor = await( session.runAsync( "MATCH (n:MyLabel) RETURN count(n)" ) ); - assertEquals( 1, await( cursor.singleAsync() ).get( 0 ).asInt() ); + ResultCursor cursor = await(session.runAsync("MATCH (n:MyLabel) RETURN count(n)")); + assertEquals(1, await(cursor.singleAsync()).get(0).asInt()); - ClientException e = assertThrows( ClientException.class, () -> await( tx.runAsync( "CREATE (:MyOtherLabel)" ) ) ); - assertEquals( "Cannot run more queries in this transaction, it has been committed", e.getMessage() ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.runAsync("CREATE (:MyOtherLabel)"))); + assertEquals("Cannot run more queries in this transaction, it has been committed", e.getMessage()); } @Test - void shouldFailToRunQueryAfterRollback() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - tx.runAsync( "CREATE (:MyLabel)" ); - assertNull( await( tx.rollbackAsync() ) ); + void shouldFailToRunQueryAfterRollback() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + tx.runAsync("CREATE (:MyLabel)"); + assertNull(await(tx.rollbackAsync())); - ResultCursor cursor = await( session.runAsync( "MATCH (n:MyLabel) RETURN count(n)" ) ); - assertEquals( 0, await( cursor.singleAsync() ).get( 0 ).asInt() ); + ResultCursor cursor = await(session.runAsync("MATCH (n:MyLabel) RETURN count(n)")); + assertEquals(0, await(cursor.singleAsync()).get(0).asInt()); - ClientException e = assertThrows( ClientException.class, () -> await( tx.runAsync( "CREATE (:MyOtherLabel)" ) ) ); - assertEquals( "Cannot run more queries in this transaction, it has been rolled back", e.getMessage() ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.runAsync("CREATE (:MyOtherLabel)"))); + assertEquals("Cannot run more queries in this transaction, it has been rolled back", e.getMessage()); } @Test - void shouldUpdateSessionBookmarkAfterCommit() - { + void shouldUpdateSessionBookmarkAfterCommit() { Bookmark bookmarkBefore = session.lastBookmark(); - await( session.beginTransactionAsync() - .thenCompose( tx -> tx.runAsync( "CREATE (:MyNode)" ) - .thenCompose( ignore -> tx.commitAsync() ) ) ); + await(session.beginTransactionAsync() + .thenCompose(tx -> tx.runAsync("CREATE (:MyNode)").thenCompose(ignore -> tx.commitAsync()))); Bookmark bookmarkAfter = session.lastBookmark(); - assertNotNull( bookmarkAfter ); - assertNotEquals( bookmarkBefore, bookmarkAfter ); + assertNotNull(bookmarkAfter); + assertNotEquals(bookmarkBefore, bookmarkAfter); } @Test - void shouldFailToCommitWhenQueriesFail() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldFailToCommitWhenQueriesFail() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - tx.runAsync( "CREATE (:TestNode)" ); - tx.runAsync( "CREATE (:TestNode)" ); - tx.runAsync( "RETURN 10 / 0" ); - tx.runAsync( "CREATE (:TestNode)" ); + tx.runAsync("CREATE (:TestNode)"); + tx.runAsync("CREATE (:TestNode)"); + tx.runAsync("RETURN 10 / 0"); + tx.runAsync("CREATE (:TestNode)"); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertNoCircularReferences( e ); - assertEquals( "Transaction can't be committed. It has been rolled back either because of an error or explicit termination", - e.getMessage() ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertNoCircularReferences(e); + assertEquals( + "Transaction can't be committed. It has been rolled back either because of an error or explicit termination", + e.getMessage()); } @Test - void shouldFailToCommitWhenRunFailed() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldFailToCommitWhenRunFailed() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - tx.runAsync( "RETURN ILLEGAL" ); + tx.runAsync("RETURN ILLEGAL"); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertNoCircularReferences( e ); - assertThat( e.getMessage(), containsString( "Transaction can't be committed" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertNoCircularReferences(e); + assertThat(e.getMessage(), containsString("Transaction can't be committed")); } @Test - void shouldFailToCommitWhenBlockedRunFailed() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldFailToCommitWhenBlockedRunFailed() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - ClientException runException = assertThrows( ClientException.class, () -> await( tx.runAsync( "RETURN 42 / 0" ) ) ); + ClientException runException = assertThrows(ClientException.class, () -> await(tx.runAsync("RETURN 42 / 0"))); - ClientException commitException = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertThat( runException.getMessage(), containsString( "/ by zero" ) ); - assertNoCircularReferences( commitException ); - assertThat( commitException.getMessage(), containsString( "Transaction can't be committed" ) ); + ClientException commitException = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertThat(runException.getMessage(), containsString("/ by zero")); + assertNoCircularReferences(commitException); + assertThat(commitException.getMessage(), containsString("Transaction can't be committed")); } @Test - void shouldRollbackSuccessfullyWhenRunFailed() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldRollbackSuccessfullyWhenRunFailed() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - tx.runAsync( "RETURN ILLEGAL" ); + tx.runAsync("RETURN ILLEGAL"); - await( tx.rollbackAsync() ); + await(tx.rollbackAsync()); } @Test - void shouldRollbackSuccessfullyWhenBlockedRunFailed() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldRollbackSuccessfullyWhenBlockedRunFailed() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - assertThrows( ClientException.class, () -> await( tx.runAsync( "RETURN 42 / 0" ) ) ); + assertThrows(ClientException.class, () -> await(tx.runAsync("RETURN 42 / 0"))); - await( tx.rollbackAsync() ); + await(tx.rollbackAsync()); } @Test - void shouldPropagatePullAllFailureFromCommit() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldPropagatePullAllFailureFromCommit() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - tx.runAsync( "UNWIND [1, 2, 3, 'Hi'] AS x RETURN 10 / x" ); + tx.runAsync("UNWIND [1, 2, 3, 'Hi'] AS x RETURN 10 / x"); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertNoCircularReferences( e ); - assertThat( e.code(), containsString( "TypeError" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertNoCircularReferences(e); + assertThat(e.code(), containsString("TypeError")); } @Test - void shouldPropagateBlockedPullAllFailureFromCommit() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldPropagateBlockedPullAllFailureFromCommit() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - await( tx.runAsync( "UNWIND [1, 2, 3, 'Hi'] AS x RETURN 10 / x" ) ); + await(tx.runAsync("UNWIND [1, 2, 3, 'Hi'] AS x RETURN 10 / x")); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertNoCircularReferences( e ); - assertThat( e.code(), containsString( "TypeError" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertNoCircularReferences(e); + assertThat(e.code(), containsString("TypeError")); } @Test - void shouldPropagatePullAllFailureFromRollback() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldPropagatePullAllFailureFromRollback() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - tx.runAsync( "UNWIND [1, 2, 3, 'Hi'] AS x RETURN 10 / x" ); + tx.runAsync("UNWIND [1, 2, 3, 'Hi'] AS x RETURN 10 / x"); - ClientException e = assertThrows( ClientException.class, () -> await( tx.rollbackAsync() ) ); - assertThat( e.code(), containsString( "TypeError" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.rollbackAsync())); + assertThat(e.code(), containsString("TypeError")); } @Test - void shouldPropagateBlockedPullAllFailureFromRollback() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); + void shouldPropagateBlockedPullAllFailureFromRollback() { + AsyncTransaction tx = await(session.beginTransactionAsync()); - await( tx.runAsync( "UNWIND [1, 2, 3, 'Hi'] AS x RETURN 10 / x" ) ); + await(tx.runAsync("UNWIND [1, 2, 3, 'Hi'] AS x RETURN 10 / x")); - ClientException e = assertThrows( ClientException.class, () -> await( tx.rollbackAsync() ) ); - assertThat( e.code(), containsString( "TypeError" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.rollbackAsync())); + assertThat(e.code(), containsString("TypeError")); } @Test - void shouldRollbackWhenPullAllFailureIsConsumed() - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( "UNWIND [1, 0] AS x RETURN 5 / x" ) ); + void shouldRollbackWhenPullAllFailureIsConsumed() { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync("UNWIND [1, 0] AS x RETURN 5 / x")); - ClientException e = assertThrows( ClientException.class, () -> await( cursor.consumeAsync() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); - assertNull( await( tx.rollbackAsync() ) ); + ClientException e = assertThrows(ClientException.class, () -> await(cursor.consumeAsync())); + assertThat(e.getMessage(), containsString("/ by zero")); + assertNull(await(tx.rollbackAsync())); } - private int countNodes( Object id ) - { - ResultCursor cursor = await( session.runAsync( "MATCH (n:Node {id: $id}) RETURN count(n)", parameters( "id", id ) ) ); - return await( cursor.singleAsync() ).get( 0 ).asInt(); + private int countNodes(Object id) { + ResultCursor cursor = await(session.runAsync("MATCH (n:Node {id: $id}) RETURN count(n)", parameters("id", id))); + return await(cursor.singleAsync()).get(0).asInt(); } - private void testForEach( String query, int expectedSeenRecords ) - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( query ) ); + private void testForEach(String query, int expectedSeenRecords) { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync(query)); AtomicInteger recordsSeen = new AtomicInteger(); - CompletionStage forEachDone = cursor.forEachAsync( record -> recordsSeen.incrementAndGet() ); - ResultSummary summary = await( forEachDone ); + CompletionStage forEachDone = cursor.forEachAsync(record -> recordsSeen.incrementAndGet()); + ResultSummary summary = await(forEachDone); - assertNotNull( summary ); - assertEquals( query, summary.query().text() ); - assertEquals( emptyMap(), summary.query().parameters().asMap() ); - assertEquals( expectedSeenRecords, recordsSeen.get() ); + assertNotNull(summary); + assertEquals(query, summary.query().text()); + assertEquals(emptyMap(), summary.query().parameters().asMap()); + assertEquals(expectedSeenRecords, recordsSeen.get()); } - private void testList( String query, List expectedList ) - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( query ) ); - List records = await( cursor.listAsync() ); + private void testList(String query, List expectedList) { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync(query)); + List records = await(cursor.listAsync()); List actualList = new ArrayList<>(); - for ( Record record : records ) - { - actualList.add( record.get( 0 ).asObject() ); + for (Record record : records) { + actualList.add(record.get(0).asObject()); } - assertEquals( expectedList, actualList ); + assertEquals(expectedList, actualList); } - private void testConsume( String query ) - { - AsyncTransaction tx = await( session.beginTransactionAsync() ); - ResultCursor cursor = await( tx.runAsync( query ) ); - ResultSummary summary = await( cursor.consumeAsync() ); + private void testConsume(String query) { + AsyncTransaction tx = await(session.beginTransactionAsync()); + ResultCursor cursor = await(tx.runAsync(query)); + ResultSummary summary = await(cursor.consumeAsync()); - assertNotNull( summary ); - assertEquals( query, summary.query().text() ); - assertEquals( emptyMap(), summary.query().parameters().asMap() ); + assertNotNull(summary); + assertEquals(query, summary.query().text()); + assertEquals(emptyMap(), summary.query().parameters().asMap()); // no records should be available, they should all be consumed - assertThrows( ResultConsumedException.class, () -> await( cursor.nextAsync() ) ); + assertThrows(ResultConsumedException.class, () -> await(cursor.nextAsync())); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/reactive/RxNestedQueriesIT.java b/driver/src/test/java/org/neo4j/driver/integration/reactive/RxNestedQueriesIT.java index 3c028c01c1..fd1e631008 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/reactive/RxNestedQueriesIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/reactive/RxNestedQueriesIT.java @@ -18,129 +18,144 @@ */ package org.neo4j.driver.integration.reactive; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; import java.util.Collections; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.exceptions.TransactionNestingException; import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; -import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.reactive.RxResult; +import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.reactive.RxTransaction; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; - -@EnabledOnNeo4jWith( BOLT_V4 ) +@EnabledOnNeo4jWith(BOLT_V4) @ParallelizableIT -class RxNestedQueriesIT -{ +class RxNestedQueriesIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - void shouldErrorForNestingQueriesAmongSessionRuns() - { + void shouldErrorForNestingQueriesAmongSessionRuns() { int size = 12555; Flux nodeIds = Flux.usingWhen( - Mono.fromSupplier( () -> neo4j.driver().rxSession() ), - session -> Flux.from( session.run( "UNWIND range(1, $size) AS x RETURN x", Collections.singletonMap( "size", size ) ).records() ) - .limitRate( 20 ).flatMap( record -> { - int x = record.get( "x" ).asInt(); - RxResult innerResult = session.run( "CREATE (n:Node {id: $x}) RETURN n.id", Collections.singletonMap( "x", x ) ); + Mono.fromSupplier(() -> neo4j.driver().rxSession()), + session -> Flux.from(session.run( + "UNWIND range(1, $size) AS x RETURN x", Collections.singletonMap("size", size)) + .records()) + .limitRate(20) + .flatMap(record -> { + int x = record.get("x").asInt(); + RxResult innerResult = session.run( + "CREATE (n:Node {id: $x}) RETURN n.id", Collections.singletonMap("x", x)); return innerResult.records(); - } ).map( r -> r.get( 0 ).asInt() ), - RxSession::close ); + }) + .map(r -> r.get(0).asInt()), + RxSession::close); - StepVerifier.create( nodeIds ).expectError( TransactionNestingException.class ).verify(); + StepVerifier.create(nodeIds) + .expectError(TransactionNestingException.class) + .verify(); } @Test - void shouldErrorForNestingQueriesAmongTransactionFunctions() - { + void shouldErrorForNestingQueriesAmongTransactionFunctions() { int size = 12555; Flux nodeIds = Flux.usingWhen( - Mono.fromSupplier( () -> neo4j.driver().rxSession() ), - session -> Flux.from( session.readTransaction( tx -> - tx.run( "UNWIND range(1, $size) AS x RETURN x", - Collections.singletonMap( "size", size ) ).records() ) ) - .limitRate( 20 ) - .flatMap( record -> { - int x = record.get( "x" ).asInt(); - return session.writeTransaction( tx -> - tx.run( "CREATE (n:Node {id: $x}) RETURN n.id", - Collections.singletonMap( "x", x ) ).records() ); - } ).map( r -> r.get( 0 ).asInt() ), - RxSession::close ); - - StepVerifier.create( nodeIds ).expectError( TransactionNestingException.class ).verify(); + Mono.fromSupplier(() -> neo4j.driver().rxSession()), + session -> Flux.from(session.readTransaction(tx -> tx.run( + "UNWIND range(1, $size) AS x RETURN x", Collections.singletonMap("size", size)) + .records())) + .limitRate(20) + .flatMap(record -> { + int x = record.get("x").asInt(); + return session.writeTransaction(tx -> tx.run( + "CREATE (n:Node {id: $x}) RETURN n.id", Collections.singletonMap("x", x)) + .records()); + }) + .map(r -> r.get(0).asInt()), + RxSession::close); + + StepVerifier.create(nodeIds) + .expectError(TransactionNestingException.class) + .verify(); } @Test - void shouldErrorForNestingQueriesAmongSessionRunAndTransactionFunction() - { + void shouldErrorForNestingQueriesAmongSessionRunAndTransactionFunction() { int size = 12555; Flux nodeIds = Flux.usingWhen( - Mono.fromSupplier( () -> neo4j.driver().rxSession() ), - session -> Flux.from( session.run( "UNWIND range(1, $size) AS x RETURN x", - Collections.singletonMap( "size", size ) ).records() ) - .limitRate( 20 ) - .flatMap( record -> { - int x = record.get( "x" ).asInt(); - return session.writeTransaction( tx -> - tx.run( "CREATE (n:Node {id: $x}) RETURN n.id", - Collections.singletonMap( "x", x ) ).records() ); - } ).map( r -> r.get( 0 ).asInt() ), - RxSession::close ); - - StepVerifier.create( nodeIds ).expectError( TransactionNestingException.class ).verify(); + Mono.fromSupplier(() -> neo4j.driver().rxSession()), + session -> Flux.from(session.run( + "UNWIND range(1, $size) AS x RETURN x", Collections.singletonMap("size", size)) + .records()) + .limitRate(20) + .flatMap(record -> { + int x = record.get("x").asInt(); + return session.writeTransaction(tx -> tx.run( + "CREATE (n:Node {id: $x}) RETURN n.id", Collections.singletonMap("x", x)) + .records()); + }) + .map(r -> r.get(0).asInt()), + RxSession::close); + + StepVerifier.create(nodeIds) + .expectError(TransactionNestingException.class) + .verify(); } @Test - void shouldErrorForNestingQueriesAmongTransactionFunctionAndSessionRun() - { + void shouldErrorForNestingQueriesAmongTransactionFunctionAndSessionRun() { int size = 12555; Flux nodeIds = Flux.usingWhen( - Mono.fromSupplier( () -> neo4j.driver().rxSession() ), - session -> Flux.from( session.readTransaction( tx -> - tx.run( "UNWIND range(1, $size) AS x RETURN x", - Collections.singletonMap( "size", size ) ).records() ) ) - .limitRate( 20 ) - .flatMap( record -> { - int x = record.get( "x" ).asInt(); - return session.run( "CREATE (n:Node {id: $x}) RETURN n.id", - Collections.singletonMap( "x", x ) ).records(); - } ).map( r -> r.get( 0 ).asInt() ), - RxSession::close ); - - StepVerifier.create( nodeIds ).expectError( TransactionNestingException.class ).verify(); + Mono.fromSupplier(() -> neo4j.driver().rxSession()), + session -> Flux.from(session.readTransaction(tx -> tx.run( + "UNWIND range(1, $size) AS x RETURN x", Collections.singletonMap("size", size)) + .records())) + .limitRate(20) + .flatMap(record -> { + int x = record.get("x").asInt(); + return session.run("CREATE (n:Node {id: $x}) RETURN n.id", Collections.singletonMap("x", x)) + .records(); + }) + .map(r -> r.get(0).asInt()), + RxSession::close); + + StepVerifier.create(nodeIds) + .expectError(TransactionNestingException.class) + .verify(); } @Test - void shouldHandleNestedQueriesInTheSameTransaction() throws Throwable - { + void shouldHandleNestedQueriesInTheSameTransaction() throws Throwable { int size = 12555; RxSession session = neo4j.driver().rxSession(); Flux nodeIds = Flux.usingWhen( session.beginTransaction(), tx -> { - RxResult result = tx.run( "UNWIND range(1, $size) AS x RETURN x", - Collections.singletonMap( "size", size ) ); - return Flux.from( result.records() ).limitRate( 20 ).flatMap( record -> { - int x = record.get( "x" ).asInt(); - RxResult innerResult = tx.run( "CREATE (n:Node {id: $x}) RETURN n.id", - Collections.singletonMap( "x", x ) ); - return innerResult.records(); - } ).map( record -> record.get( 0 ).asInt() ); - }, RxTransaction::commit, ( tx, error ) -> tx.rollback(), null ); - - StepVerifier.create( nodeIds ).expectNextCount( size ).verifyComplete(); + RxResult result = + tx.run("UNWIND range(1, $size) AS x RETURN x", Collections.singletonMap("size", size)); + return Flux.from(result.records()) + .limitRate(20) + .flatMap(record -> { + int x = record.get("x").asInt(); + RxResult innerResult = tx.run( + "CREATE (n:Node {id: $x}) RETURN n.id", Collections.singletonMap("x", x)); + return innerResult.records(); + }) + .map(record -> record.get(0).asInt()); + }, + RxTransaction::commit, + (tx, error) -> tx.rollback(), + null); + + StepVerifier.create(nodeIds).expectNextCount(size).verifyComplete(); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/reactive/RxResultIT.java b/driver/src/test/java/org/neo4j/driver/integration/reactive/RxResultIT.java index d66f1c0194..103e5a2485 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/reactive/RxResultIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/reactive/RxResultIT.java @@ -18,24 +18,6 @@ */ package org.neo4j.driver.integration.reactive; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import java.util.List; - -import org.neo4j.driver.Record; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; -import org.neo4j.driver.reactive.RxSession; -import org.neo4j.driver.reactive.RxResult; -import org.neo4j.driver.summary.ResultSummary; -import org.neo4j.driver.summary.QueryType; -import org.neo4j.driver.util.DatabaseExtension; -import org.neo4j.driver.util.ParallelizableIT; - import static java.util.Collections.EMPTY_LIST; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -50,437 +32,457 @@ import static org.neo4j.driver.Values.parameters; import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; -@EnabledOnNeo4jWith( BOLT_V4 ) +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.neo4j.driver.Record; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; +import org.neo4j.driver.reactive.RxResult; +import org.neo4j.driver.reactive.RxSession; +import org.neo4j.driver.summary.QueryType; +import org.neo4j.driver.summary.ResultSummary; +import org.neo4j.driver.util.DatabaseExtension; +import org.neo4j.driver.util.ParallelizableIT; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +@EnabledOnNeo4jWith(BOLT_V4) @ParallelizableIT -class RxResultIT -{ +class RxResultIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - void shouldAllowIteratingOverResultStream() - { + void shouldAllowIteratingOverResultStream() { // When RxResult res = sessionRunUnwind(); // Then I should be able to iterate over the result - verifyCanAccessFullRecords( res ); + verifyCanAccessFullRecords(res); } @Test - void shouldAllowIteratingOverLargeResultStream() - { + void shouldAllowIteratingOverLargeResultStream() { // When int size = 100000; RxSession session = neo4j.driver().rxSession(); - RxResult res = session.run( "UNWIND range(1, $size) AS x RETURN x", parameters( "size", size ) ); + RxResult res = session.run("UNWIND range(1, $size) AS x RETURN x", parameters("size", size)); // Then I should be able to iterate over the result - StepVerifier.FirstStep step = StepVerifier.create( Flux.from( res.records() ).limitRate( 100 ).map( r -> r.get( "x" ).asInt() ) ); + StepVerifier.FirstStep step = StepVerifier.create( + Flux.from(res.records()).limitRate(100).map(r -> r.get("x").asInt())); - for ( int i = 1; i <= size; i++ ) - { - step.expectNext( i ); + for (int i = 1; i <= size; i++) { + step.expectNext(i); } step.expectComplete().verify(); } @Test - void shouldReturnKeysRecordsAndSummaryInOrder() - { + void shouldReturnKeysRecordsAndSummaryInOrder() { // When RxResult res = sessionRunUnwind(); // Then I should be able to iterate over the result - verifyCanAccessKeys( res ); - verifyCanAccessFullRecords( res ); - verifyCanAccessSummary( res ); + verifyCanAccessKeys(res); + verifyCanAccessFullRecords(res); + verifyCanAccessSummary(res); } @Test - void shouldSecondVisitOfRecordReceiveEmptyRecordStream() throws Throwable - { + void shouldSecondVisitOfRecordReceiveEmptyRecordStream() throws Throwable { // When RxResult res = sessionRunUnwind(); // Then I should be able to iterate over the result - verifyCanAccessFullRecords( res ); + verifyCanAccessFullRecords(res); // Second visit shall return empty record stream - verifyRecordsAlreadyDiscarded( res ); + verifyRecordsAlreadyDiscarded(res); } @Test - void shouldReturnKeysSummaryAndDiscardRecords() - { + void shouldReturnKeysSummaryAndDiscardRecords() { // When RxResult res = sessionRunUnwind(); - verifyCanAccessKeys( res ); - verifyCanAccessSummary( res ); - verifyRecordsAlreadyDiscarded( res ); + verifyCanAccessKeys(res); + verifyCanAccessSummary(res); + verifyRecordsAlreadyDiscarded(res); } @Test - void shouldAllowOnlySummary() - { + void shouldAllowOnlySummary() { // When RxResult res = sessionRunUnwind(); - verifyCanAccessSummary( res ); + verifyCanAccessSummary(res); } @Test - void shouldAllowAccessKeysAndSummaryAfterRecord() throws Throwable - { + void shouldAllowAccessKeysAndSummaryAfterRecord() throws Throwable { // Given RxResult res = sessionRunUnwind(); // Then I should be able to iterate over the result - verifyCanAccessFullRecords( res ); + verifyCanAccessFullRecords(res); // Access keys and summary after records - verifyCanAccessKeys( res ); - verifyCanAccessSummary( res ); + verifyCanAccessKeys(res); + verifyCanAccessSummary(res); // Multiple times allowed - verifyCanAccessKeys( res ); - verifyCanAccessSummary( res ); + verifyCanAccessKeys(res); + verifyCanAccessSummary(res); } @Test - void shouldGiveHelpfulFailureMessageWhenAccessNonExistingField() - { + void shouldGiveHelpfulFailureMessageWhenAccessNonExistingField() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult rs = - session.run( "CREATE (n:Person {name:$name}) RETURN n", parameters( "name", "Tom Hanks" ) ); + RxResult rs = session.run("CREATE (n:Person {name:$name}) RETURN n", parameters("name", "Tom Hanks")); // When - StepVerifier.create( Flux.from( rs.records() ).single() ).assertNext( record -> { - // Then - assertTrue( record.get( "m" ).isNull() ); - } ).expectComplete().verify(); + StepVerifier.create(Flux.from(rs.records()).single()) + .assertNext(record -> { + // Then + assertTrue(record.get("m").isNull()); + }) + .expectComplete() + .verify(); } @Test - void shouldGiveHelpfulFailureMessageWhenAccessNonExistingPropertyOnNode() - { + void shouldGiveHelpfulFailureMessageWhenAccessNonExistingPropertyOnNode() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult rs = - session.run( "CREATE (n:Person {name:$name}) RETURN n", parameters( "name", "Tom Hanks" ) ); + RxResult rs = session.run("CREATE (n:Person {name:$name}) RETURN n", parameters("name", "Tom Hanks")); // When - StepVerifier.create( Flux.from( rs.records() ).single() ).assertNext( record -> { - // Then - assertTrue( record.get( "n" ).get( "age" ).isNull() ); - } ).expectComplete().verify(); + StepVerifier.create(Flux.from(rs.records()).single()) + .assertNext(record -> { + // Then + assertTrue(record.get("n").get("age").isNull()); + }) + .expectComplete() + .verify(); } @Test - void shouldHaveFieldNamesInResult() - { + void shouldHaveFieldNamesInResult() { // When RxSession session = neo4j.driver().rxSession(); - RxResult res = session.run( "CREATE (n:TestNode {name:'test'}) RETURN n" ); + RxResult res = session.run("CREATE (n:TestNode {name:'test'}) RETURN n"); // Then - StepVerifier.create( res.keys() ).expectNext( singletonList( "n" ) ).expectComplete().verify(); - StepVerifier.create( res.records() ) - .assertNext( record -> { - assertEquals( "[n]", record.keys().toString() ); - } ) + StepVerifier.create(res.keys()) + .expectNext(singletonList("n")) + .expectComplete() + .verify(); + StepVerifier.create(res.records()) + .assertNext(record -> { + assertEquals("[n]", record.keys().toString()); + }) .expectComplete() .verify(); } @Test - void shouldReturnEmptyKeyAndRecordOnEmptyResult() - { + void shouldReturnEmptyKeyAndRecordOnEmptyResult() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult rs = session.run( "CREATE (n:Person {name:$name})", parameters( "name", "Tom Hanks" ) ); + RxResult rs = session.run("CREATE (n:Person {name:$name})", parameters("name", "Tom Hanks")); // Then - StepVerifier.create( rs.keys() ).expectNext( emptyList() ).expectComplete().verify(); - StepVerifier.create( rs.records() ).expectComplete().verify(); + StepVerifier.create(rs.keys()).expectNext(emptyList()).expectComplete().verify(); + StepVerifier.create(rs.records()).expectComplete().verify(); } @Test - void shouldOnlyErrorRecordAfterFailure() - { + void shouldOnlyErrorRecordAfterFailure() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "INVALID" ); + RxResult result = session.run("INVALID"); // When - Flux> keys = Flux.from( result.keys() ); - Flux records = Flux.from( result.records() ); - Mono summaryMono = Mono.from( result.consume() ); + Flux> keys = Flux.from(result.keys()); + Flux records = Flux.from(result.records()); + Mono summaryMono = Mono.from(result.consume()); // Then - StepVerifier.create( keys ).expectNext( emptyList() ).verifyComplete(); - - StepVerifier.create( records ).expectErrorSatisfies( error -> { - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), containsString( "Invalid input" ) ); - } ).verify(); - - StepVerifier.create( summaryMono ) - .assertNext( summary -> { - assertThat( summary.query().text(), equalTo( "INVALID" ) ); - assertNotNull( summary.server().address() ); - assertNotNull( summary.server().version() ); - } ).verifyComplete(); - } + StepVerifier.create(keys).expectNext(emptyList()).verifyComplete(); + StepVerifier.create(records) + .expectErrorSatisfies(error -> { + assertThat(error, instanceOf(ClientException.class)); + assertThat(error.getMessage(), containsString("Invalid input")); + }) + .verify(); + + StepVerifier.create(summaryMono) + .assertNext(summary -> { + assertThat(summary.query().text(), equalTo("INVALID")); + assertNotNull(summary.server().address()); + assertNotNull(summary.server().version()); + }) + .verifyComplete(); + } @Test - void shouldErrorOnSummaryIfNoRecord() throws Throwable - { + void shouldErrorOnSummaryIfNoRecord() throws Throwable { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "INVALID" ); + RxResult result = session.run("INVALID"); // When - Flux> keys = Flux.from( result.keys() ); - Mono summaryMono = Mono.from( result.consume() ); + Flux> keys = Flux.from(result.keys()); + Mono summaryMono = Mono.from(result.consume()); // Then - StepVerifier.create( keys ).expectNext( emptyList() ).verifyComplete(); + StepVerifier.create(keys).expectNext(emptyList()).verifyComplete(); - StepVerifier.create( summaryMono ).expectErrorSatisfies( error -> { - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), containsString( "Invalid input" ) ); - } ).verify(); + StepVerifier.create(summaryMono) + .expectErrorSatisfies(error -> { + assertThat(error, instanceOf(ClientException.class)); + assertThat(error.getMessage(), containsString("Invalid input")); + }) + .verify(); // The error stick with the summary forever - StepVerifier.create( summaryMono ).expectErrorSatisfies( error -> { - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), containsString( "Invalid input" ) ); - } ).verify(); + StepVerifier.create(summaryMono) + .expectErrorSatisfies(error -> { + assertThat(error, instanceOf(ClientException.class)); + assertThat(error.getMessage(), containsString("Invalid input")); + }) + .verify(); } @Test - void shouldDiscardRecords() - { + void shouldDiscardRecords() { // Given RxSession session = neo4j.driver().rxSession(); RxResult result = session.run("UNWIND [1,2] AS a RETURN a"); // When - StepVerifier.create( Flux.from( result.records() ) - .limitRate( 1 ) // PULL, N=1 - .take( 1 ) // DISCARD_ALL after 1 item - ) - .assertNext( record -> assertThat( record.get( "a" ).asInt(), equalTo( 1 ) ) ) + StepVerifier.create( + Flux.from(result.records()) + .limitRate(1) // PULL, N=1 + .take(1) // DISCARD_ALL after 1 item + ) + .assertNext(record -> assertThat(record.get("a").asInt(), equalTo(1))) .thenCancel() .verify(); - StepVerifier.create( result.consume() ) // I shall be able to receive summary - .assertNext( summary -> { + StepVerifier.create(result.consume()) // I shall be able to receive summary + .assertNext(summary -> { // Then - assertThat( summary, notNullValue() ); - assertThat( summary.queryType(), equalTo( QueryType.READ_ONLY ) ); - } ).expectComplete().verify(); + assertThat(summary, notNullValue()); + assertThat(summary.queryType(), equalTo(QueryType.READ_ONLY)); + }) + .expectComplete() + .verify(); } @Test - void shouldStreamCorrectRecordsBackBeforeError() - { + void shouldStreamCorrectRecordsBackBeforeError() { RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "CYPHER runtime=interpreted UNWIND range(5, 0, -1) AS x RETURN x / x" ); - StepVerifier.create( Flux.from( result.records() ).map( record -> record.get( 0 ).asInt() ) ) - .expectNext( 1 ) - .expectNext( 1 ) - .expectNext( 1 ) - .expectNext( 1 ) - .expectNext( 1 ) - .expectErrorSatisfies( error -> { - assertThat( error.getMessage(), containsString( "/ by zero" ) ); - } ) + RxResult result = session.run("CYPHER runtime=interpreted UNWIND range(5, 0, -1) AS x RETURN x / x"); + StepVerifier.create( + Flux.from(result.records()).map(record -> record.get(0).asInt())) + .expectNext(1) + .expectNext(1) + .expectNext(1) + .expectNext(1) + .expectNext(1) + .expectErrorSatisfies(error -> { + assertThat(error.getMessage(), containsString("/ by zero")); + }) .verify(); } @Test - void shouldErrorToAccessRecordAfterSessionClose() - { + void shouldErrorToAccessRecordAfterSessionClose() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "UNWIND [1,2] AS a RETURN a" ); + RxResult result = session.run("UNWIND [1,2] AS a RETURN a"); // When - StepVerifier.create( Flux.from( session.close() ).thenMany( result.records() ) ).expectErrorSatisfies( error -> { - assertThat( error.getMessage(), containsString( "session is already closed" ) ); - } ).verify(); + StepVerifier.create(Flux.from(session.close()).thenMany(result.records())) + .expectErrorSatisfies(error -> { + assertThat(error.getMessage(), containsString("session is already closed")); + }) + .verify(); } @Test - void shouldErrorToAccessKeysAfterSessionClose() - { + void shouldErrorToAccessKeysAfterSessionClose() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "UNWIND [1,2] AS a RETURN a" ); + RxResult result = session.run("UNWIND [1,2] AS a RETURN a"); // When - StepVerifier.create( Flux.from( session.close() ).thenMany( result.keys() ) ).expectErrorSatisfies( error -> { - assertThat( error.getMessage(), containsString( "session is already closed" ) ); - } ).verify(); + StepVerifier.create(Flux.from(session.close()).thenMany(result.keys())) + .expectErrorSatisfies(error -> { + assertThat(error.getMessage(), containsString("session is already closed")); + }) + .verify(); } @Test - void shouldErrorToAccessSummaryAfterSessionClose() - { + void shouldErrorToAccessSummaryAfterSessionClose() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "UNWIND [1,2] AS a RETURN a" ); + RxResult result = session.run("UNWIND [1,2] AS a RETURN a"); // When - StepVerifier.create( Flux.from( session.close() ).thenMany( result.consume() ) ).expectErrorSatisfies( error -> { - assertThat( error.getMessage(), containsString( "session is already closed" ) ); - } ).verify(); + StepVerifier.create(Flux.from(session.close()).thenMany(result.consume())) + .expectErrorSatisfies(error -> { + assertThat(error.getMessage(), containsString("session is already closed")); + }) + .verify(); } @Test - void shouldErrorToAccessRecordAfterTxClose() - { + void shouldErrorToAccessRecordAfterTxClose() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "UNWIND [1,2] AS a RETURN a" ); + RxResult result = session.run("UNWIND [1,2] AS a RETURN a"); // When - StepVerifier.create( - Flux.from( session.beginTransaction() ).single() - .flatMap( tx -> Flux.from( tx.rollback() ).singleOrEmpty().thenReturn( tx ) ) - .flatMapMany( tx -> tx.run( "UNWIND [1,2] AS a RETURN a" ).records() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), containsString( "Cannot run more queries" ) ) ) + StepVerifier.create(Flux.from(session.beginTransaction()) + .single() + .flatMap(tx -> Flux.from(tx.rollback()).singleOrEmpty().thenReturn(tx)) + .flatMapMany(tx -> tx.run("UNWIND [1,2] AS a RETURN a").records())) + .expectErrorSatisfies( + error -> assertThat(error.getMessage(), containsString("Cannot run more queries"))) .verify(); } @Test - void shouldErrorToAccessKeysAfterTxClose() - { + void shouldErrorToAccessKeysAfterTxClose() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "UNWIND [1,2] AS a RETURN a" ); + RxResult result = session.run("UNWIND [1,2] AS a RETURN a"); // When - StepVerifier.create( - Flux.from( session.beginTransaction() ).single() - .flatMap( tx -> Flux.from( tx.rollback() ).singleOrEmpty().thenReturn( tx ) ) - .flatMapMany( tx -> tx.run( "UNWIND [1,2] AS a RETURN a" ).keys() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), containsString( "Cannot run more queries" ) ) ) + StepVerifier.create(Flux.from(session.beginTransaction()) + .single() + .flatMap(tx -> Flux.from(tx.rollback()).singleOrEmpty().thenReturn(tx)) + .flatMapMany(tx -> tx.run("UNWIND [1,2] AS a RETURN a").keys())) + .expectErrorSatisfies( + error -> assertThat(error.getMessage(), containsString("Cannot run more queries"))) .verify(); } @Test - void shouldErrorToAccessSummaryAfterTxClose() - { + void shouldErrorToAccessSummaryAfterTxClose() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "UNWIND [1,2] AS a RETURN a" ); + RxResult result = session.run("UNWIND [1,2] AS a RETURN a"); // When - StepVerifier.create( - Flux.from( session.beginTransaction() ).single() - .flatMap( tx -> Flux.from( tx.rollback() ).singleOrEmpty().thenReturn( tx ) ) - .flatMapMany( tx -> tx.run( "UNWIND [1,2] AS a RETURN a" ).consume() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), containsString( "Cannot run more queries" ) ) ) + StepVerifier.create(Flux.from(session.beginTransaction()) + .single() + .flatMap(tx -> Flux.from(tx.rollback()).singleOrEmpty().thenReturn(tx)) + .flatMapMany(tx -> tx.run("UNWIND [1,2] AS a RETURN a").consume())) + .expectErrorSatisfies( + error -> assertThat(error.getMessage(), containsString("Cannot run more queries"))) .verify(); } @Test - void throwErrorAfterKeys() - { + void throwErrorAfterKeys() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "UNWIND [1,2] AS a RETURN a" ); + RxResult result = session.run("UNWIND [1,2] AS a RETURN a"); // When - StepVerifier.create( - Flux.from( session.beginTransaction() ).single() - .flatMap( tx -> Flux.from( tx.rollback() ).singleOrEmpty().thenReturn( tx ) ) - .flatMapMany( tx -> tx.run( "UNWIND [1,2] AS a RETURN a" ).consume() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), containsString( "Cannot run more queries" ) ) ) + StepVerifier.create(Flux.from(session.beginTransaction()) + .single() + .flatMap(tx -> Flux.from(tx.rollback()).singleOrEmpty().thenReturn(tx)) + .flatMapMany(tx -> tx.run("UNWIND [1,2] AS a RETURN a").consume())) + .expectErrorSatisfies( + error -> assertThat(error.getMessage(), containsString("Cannot run more queries"))) .verify(); } @Test - void throwTheSameErrorWhenCallingConsumeMultipleTimes() - { + void throwTheSameErrorWhenCallingConsumeMultipleTimes() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "Invalid" ); + RxResult result = session.run("Invalid"); // When - StepVerifier.create( Flux.from( result.consume() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), containsString( "Invalid" ) ) ) + StepVerifier.create(Flux.from(result.consume())) + .expectErrorSatisfies(error -> assertThat(error.getMessage(), containsString("Invalid"))) .verify(); - StepVerifier.create( Flux.from( result.consume() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), containsString( "Invalid" ) ) ) + StepVerifier.create(Flux.from(result.consume())) + .expectErrorSatisfies(error -> assertThat(error.getMessage(), containsString("Invalid"))) .verify(); } @Test - void keysShouldNotReportRunError() - { + void keysShouldNotReportRunError() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "Invalid" ); + RxResult result = session.run("Invalid"); // When - StepVerifier.create( Flux.from( result.keys() ) ).expectNext( EMPTY_LIST ).verifyComplete(); - StepVerifier.create( Flux.from( result.keys() ) ).expectNext( EMPTY_LIST ).verifyComplete(); + StepVerifier.create(Flux.from(result.keys())).expectNext(EMPTY_LIST).verifyComplete(); + StepVerifier.create(Flux.from(result.keys())).expectNext(EMPTY_LIST).verifyComplete(); } @Test - void throwResultConsumedErrorWhenCallingRecordsMultipleTimes() - { + void throwResultConsumedErrorWhenCallingRecordsMultipleTimes() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult result = session.run( "Invalid" ); + RxResult result = session.run("Invalid"); // When - StepVerifier.create( Flux.from( result.records() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), containsString( "Invalid" ) ) ) + StepVerifier.create(Flux.from(result.records())) + .expectErrorSatisfies(error -> assertThat(error.getMessage(), containsString("Invalid"))) .verify(); - verifyRecordsAlreadyDiscarded( result ); - verifyRecordsAlreadyDiscarded( result ); + verifyRecordsAlreadyDiscarded(result); + verifyRecordsAlreadyDiscarded(result); } - private void verifyCanAccessSummary( RxResult res ) - { - StepVerifier.create( res.consume() ).assertNext( summary -> { - assertThat( summary.query().text(), equalTo( "UNWIND [1,2,3,4] AS a RETURN a" ) ); - assertThat( summary.counters().nodesCreated(), equalTo( 0 ) ); - assertThat( summary.queryType(), equalTo( QueryType.READ_ONLY ) ); - } ).verifyComplete(); + private void verifyCanAccessSummary(RxResult res) { + StepVerifier.create(res.consume()) + .assertNext(summary -> { + assertThat(summary.query().text(), equalTo("UNWIND [1,2,3,4] AS a RETURN a")); + assertThat(summary.counters().nodesCreated(), equalTo(0)); + assertThat(summary.queryType(), equalTo(QueryType.READ_ONLY)); + }) + .verifyComplete(); } - private void verifyRecordsAlreadyDiscarded( RxResult res ) - { - StepVerifier.create( Flux.from( res.records() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), containsString( "has already been consumed" ) ) ) + private void verifyRecordsAlreadyDiscarded(RxResult res) { + StepVerifier.create(Flux.from(res.records())) + .expectErrorSatisfies( + error -> assertThat(error.getMessage(), containsString("has already been consumed"))) .verify(); } - private void verifyCanAccessFullRecords( RxResult res ) - { - StepVerifier.create( Flux.from( res.records() ).map( r -> r.get( "a" ).asInt() ) ).expectNext( 1 ).expectNext( 2 ).expectNext( 3 ).expectNext( - 4 ).expectComplete().verify(); + private void verifyCanAccessFullRecords(RxResult res) { + StepVerifier.create(Flux.from(res.records()).map(r -> r.get("a").asInt())) + .expectNext(1) + .expectNext(2) + .expectNext(3) + .expectNext(4) + .expectComplete() + .verify(); } - private void verifyCanAccessKeys( RxResult res ) - { - StepVerifier.create( res.keys() ).expectNext( singletonList( "a" ) ).verifyComplete(); + private void verifyCanAccessKeys(RxResult res) { + StepVerifier.create(res.keys()).expectNext(singletonList("a")).verifyComplete(); } - private RxResult sessionRunUnwind() - { + private RxResult sessionRunUnwind() { RxSession session = neo4j.driver().rxSession(); - return session.run( "UNWIND [1,2,3,4] AS a RETURN a" ); + return session.run("UNWIND [1,2,3,4] AS a RETURN a"); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/reactive/RxSessionIT.java b/driver/src/test/java/org/neo4j/driver/integration/reactive/RxSessionIT.java index 09b5095b78..ab8c8270ee 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/reactive/RxSessionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/reactive/RxSessionIT.java @@ -18,236 +18,220 @@ */ package org.neo4j.driver.integration.reactive; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +import static java.util.Collections.emptyIterator; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; import java.util.Arrays; import java.util.Iterator; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; - -import org.neo4j.driver.Session; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.DatabaseException; import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.exceptions.SessionExpiredException; import org.neo4j.driver.exceptions.TransientException; import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; -import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.reactive.RxResult; +import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.reactive.RxTransaction; import org.neo4j.driver.reactive.RxTransactionWork; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; -import static java.util.Collections.emptyIterator; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; - -@EnabledOnNeo4jWith( BOLT_V4 ) +@EnabledOnNeo4jWith(BOLT_V4) @ParallelizableIT -class RxSessionIT -{ +class RxSessionIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Test - void shouldAllowSessionRun() - { + void shouldAllowSessionRun() { // When RxSession session = neo4j.driver().rxSession(); - RxResult res = session.run( "UNWIND [1,2,3,4] AS a RETURN a" ); + RxResult res = session.run("UNWIND [1,2,3,4] AS a RETURN a"); // Then I should be able to iterate over the result - StepVerifier.create( Flux.from( res.records() ).map( r -> r.get( "a" ).asInt() ) ) - .expectNext( 1 ) - .expectNext( 2 ) - .expectNext( 3 ) - .expectNext( 4 ) + StepVerifier.create(Flux.from(res.records()).map(r -> r.get("a").asInt())) + .expectNext(1) + .expectNext(2) + .expectNext(3) + .expectNext(4) .expectComplete() .verify(); } @Test - void shouldBeAbleToReuseSessionAfterFailure() - { + void shouldBeAbleToReuseSessionAfterFailure() { // Given RxSession session = neo4j.driver().rxSession(); - RxResult res1 = session.run( "INVALID" ); + RxResult res1 = session.run("INVALID"); - StepVerifier.create( res1.records() ).expectError( ClientException.class ).verify(); + StepVerifier.create(res1.records()).expectError(ClientException.class).verify(); // When - RxResult res2 = session.run( "RETURN 1" ); + RxResult res2 = session.run("RETURN 1"); // Then - StepVerifier.create( res2.records() ).assertNext( record -> { - assertEquals( record.get("1").asLong(), 1L ); - } ).expectComplete().verify(); + StepVerifier.create(res2.records()) + .assertNext(record -> { + assertEquals(record.get("1").asLong(), 1L); + }) + .expectComplete() + .verify(); } @Test - void shouldRunAsyncTransactionWithoutRetries() - { + void shouldRunAsyncTransactionWithoutRetries() { RxSession session = neo4j.driver().rxSession(); - InvocationTrackingWork work = new InvocationTrackingWork( "CREATE (:Apa) RETURN 42" ); - Publisher publisher = session.writeTransaction( work ); + InvocationTrackingWork work = new InvocationTrackingWork("CREATE (:Apa) RETURN 42"); + Publisher publisher = session.writeTransaction(work); - StepVerifier.create( publisher ).expectNext( 42 ).verifyComplete(); + StepVerifier.create(publisher).expectNext(42).verifyComplete(); - assertEquals( 1, work.invocationCount() ); - assertEquals( 1, countNodesByLabel( "Apa" ) ); + assertEquals(1, work.invocationCount()); + assertEquals(1, countNodesByLabel("Apa")); } @Test - void shouldRunAsyncTransactionWithRetriesOnAsyncFailures() - { + void shouldRunAsyncTransactionWithRetriesOnAsyncFailures() { RxSession session = neo4j.driver().rxSession(); - InvocationTrackingWork work = new InvocationTrackingWork( "CREATE (:Node) RETURN 24" ).withAsyncFailures( - new ServiceUnavailableException( "Oh!" ), - new SessionExpiredException( "Ah!" ), - new TransientException( "Code", "Message" ) ); + InvocationTrackingWork work = new InvocationTrackingWork("CREATE (:Node) RETURN 24") + .withAsyncFailures( + new ServiceUnavailableException("Oh!"), + new SessionExpiredException("Ah!"), + new TransientException("Code", "Message")); - Publisher publisher = session.writeTransaction( work ); - StepVerifier.create( publisher ).expectNext( 24 ).verifyComplete(); + Publisher publisher = session.writeTransaction(work); + StepVerifier.create(publisher).expectNext(24).verifyComplete(); - assertEquals( 4, work.invocationCount() ); - assertEquals( 1, countNodesByLabel( "Node" ) ); + assertEquals(4, work.invocationCount()); + assertEquals(1, countNodesByLabel("Node")); assertNoParallelScheduler(); } @Test - void shouldRunAsyncTransactionWithRetriesOnSyncFailures() - { + void shouldRunAsyncTransactionWithRetriesOnSyncFailures() { RxSession session = neo4j.driver().rxSession(); - InvocationTrackingWork work = new InvocationTrackingWork( "CREATE (:Test) RETURN 12" ).withSyncFailures( - new TransientException( "Oh!", "Deadlock!" ), - new ServiceUnavailableException( "Oh! Network Failure" ) ); + InvocationTrackingWork work = new InvocationTrackingWork("CREATE (:Test) RETURN 12") + .withSyncFailures( + new TransientException("Oh!", "Deadlock!"), + new ServiceUnavailableException("Oh! Network Failure")); - Publisher publisher = session.writeTransaction( work ); - StepVerifier.create( publisher ).expectNext( 12 ).verifyComplete(); + Publisher publisher = session.writeTransaction(work); + StepVerifier.create(publisher).expectNext(12).verifyComplete(); - assertEquals( 3, work.invocationCount() ); - assertEquals( 1, countNodesByLabel( "Test" ) ); + assertEquals(3, work.invocationCount()); + assertEquals(1, countNodesByLabel("Test")); assertNoParallelScheduler(); } @Test - void shouldRunAsyncTransactionThatCanNotBeRetried() - { + void shouldRunAsyncTransactionThatCanNotBeRetried() { RxSession session = neo4j.driver().rxSession(); - InvocationTrackingWork work = new InvocationTrackingWork( "UNWIND [10, 5, 0] AS x CREATE (:Hi) RETURN 10/x" ); - Publisher publisher = session.writeTransaction( work ); + InvocationTrackingWork work = new InvocationTrackingWork("UNWIND [10, 5, 0] AS x CREATE (:Hi) RETURN 10/x"); + Publisher publisher = session.writeTransaction(work); - StepVerifier.create( publisher ) - .expectNext( 1 ).expectNext( 2 ) - .expectErrorSatisfies( error -> assertThat( error, instanceOf( ClientException.class ) ) ) + StepVerifier.create(publisher) + .expectNext(1) + .expectNext(2) + .expectErrorSatisfies(error -> assertThat(error, instanceOf(ClientException.class))) .verify(); - assertEquals( 1, work.invocationCount() ); - assertEquals( 0, countNodesByLabel( "Hi" ) ); + assertEquals(1, work.invocationCount()); + assertEquals(0, countNodesByLabel("Hi")); assertNoParallelScheduler(); } @Test - void shouldRunAsyncTransactionThatCanNotBeRetriedAfterATransientFailure() - { + void shouldRunAsyncTransactionThatCanNotBeRetriedAfterATransientFailure() { RxSession session = neo4j.driver().rxSession(); // first throw TransientException directly from work, retry can happen afterwards // then return a future failed with DatabaseException, retry can't happen afterwards - InvocationTrackingWork work = new InvocationTrackingWork( "CREATE (:Person) RETURN 1" ) - .withSyncFailures( new TransientException( "Oh!", "Deadlock!" ) ) - .withAsyncFailures( new DatabaseException( "Oh!", "OutOfMemory!" ) ); - Publisher publisher = session.writeTransaction( work ); - - StepVerifier.create( publisher ) - .expectErrorSatisfies( e -> { - assertThat( e, instanceOf( DatabaseException.class ) ); - assertEquals( 1, e.getSuppressed().length ); - assertThat( e.getSuppressed()[0], instanceOf( TransientException.class ) ); - } ) + InvocationTrackingWork work = new InvocationTrackingWork("CREATE (:Person) RETURN 1") + .withSyncFailures(new TransientException("Oh!", "Deadlock!")) + .withAsyncFailures(new DatabaseException("Oh!", "OutOfMemory!")); + Publisher publisher = session.writeTransaction(work); + + StepVerifier.create(publisher) + .expectErrorSatisfies(e -> { + assertThat(e, instanceOf(DatabaseException.class)); + assertEquals(1, e.getSuppressed().length); + assertThat(e.getSuppressed()[0], instanceOf(TransientException.class)); + }) .verify(); - assertEquals( 2, work.invocationCount() ); - assertEquals( 0, countNodesByLabel( "Person" ) ); + assertEquals(2, work.invocationCount()); + assertEquals(0, countNodesByLabel("Person")); assertNoParallelScheduler(); } - private void assertNoParallelScheduler() - { + private void assertNoParallelScheduler() { Set threadSet = Thread.getAllStackTraces().keySet(); - for ( Thread t : threadSet ) - { + for (Thread t : threadSet) { String name = t.getName(); - assertThat( name, not( startsWith( "parallel" ) ) ); + assertThat(name, not(startsWith("parallel"))); } } - private long countNodesByLabel( String label ) - { - try ( Session session = neo4j.driver().session() ) - { - Result result = session.run( "MATCH (n:" + label + ") RETURN count(n)" ); - return result.single().get( 0 ).asLong(); + private long countNodesByLabel(String label) { + try (Session session = neo4j.driver().session()) { + Result result = session.run("MATCH (n:" + label + ") RETURN count(n)"); + return result.single().get(0).asLong(); } } - private static class InvocationTrackingWork implements RxTransactionWork> - { + private static class InvocationTrackingWork implements RxTransactionWork> { final String query; final AtomicInteger invocationCount; Iterator asyncFailures = emptyIterator(); Iterator syncFailures = emptyIterator(); - InvocationTrackingWork( String query ) - { + InvocationTrackingWork(String query) { this.query = query; this.invocationCount = new AtomicInteger(); } - InvocationTrackingWork withAsyncFailures( RuntimeException... failures ) - { - asyncFailures = Arrays.asList( failures ).iterator(); + InvocationTrackingWork withAsyncFailures(RuntimeException... failures) { + asyncFailures = Arrays.asList(failures).iterator(); return this; } - InvocationTrackingWork withSyncFailures( RuntimeException... failures ) - { - syncFailures = Arrays.asList( failures ).iterator(); + InvocationTrackingWork withSyncFailures(RuntimeException... failures) { + syncFailures = Arrays.asList(failures).iterator(); return this; } - int invocationCount() - { + int invocationCount() { return invocationCount.get(); } @Override - public Publisher execute( RxTransaction tx ) - { + public Publisher execute(RxTransaction tx) { invocationCount.incrementAndGet(); - if ( syncFailures.hasNext() ) - { + if (syncFailures.hasNext()) { throw syncFailures.next(); } - if ( asyncFailures.hasNext() ) - { - return Mono.error( asyncFailures.next() ); + if (asyncFailures.hasNext()) { + return Mono.error(asyncFailures.next()); } - return Flux.from( tx.run( query ).records() ).map( r -> r.get( 0 ).asInt() ); + return Flux.from(tx.run(query).records()).map(r -> r.get(0).asInt()); } } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/reactive/RxTransactionIT.java b/driver/src/test/java/org/neo4j/driver/integration/reactive/RxTransactionIT.java index dab0451a32..5c5336a682 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/reactive/RxTransactionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/reactive/RxTransactionIT.java @@ -18,41 +18,6 @@ */ package org.neo4j.driver.integration.reactive; -import org.hamcrest.CoreMatchers; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; - -import org.neo4j.driver.Bookmark; -import org.neo4j.driver.Query; -import org.neo4j.driver.Record; -import org.neo4j.driver.Value; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.exceptions.ServiceUnavailableException; -import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; -import org.neo4j.driver.reactive.RxResult; -import org.neo4j.driver.reactive.RxSession; -import org.neo4j.driver.reactive.RxTransaction; -import org.neo4j.driver.summary.QueryType; -import org.neo4j.driver.summary.ResultSummary; -import org.neo4j.driver.types.Node; -import org.neo4j.driver.util.DatabaseExtension; -import org.neo4j.driver.util.ParallelizableIT; - import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static org.hamcrest.Matchers.containsString; @@ -77,837 +42,851 @@ import static org.neo4j.driver.internal.util.Neo4jFeature.BOLT_V4; import static org.neo4j.driver.util.TestUtil.await; -@EnabledOnNeo4jWith( BOLT_V4 ) +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; +import org.hamcrest.CoreMatchers; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.neo4j.driver.Bookmark; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; +import org.neo4j.driver.Value; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.exceptions.ServiceUnavailableException; +import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; +import org.neo4j.driver.reactive.RxResult; +import org.neo4j.driver.reactive.RxSession; +import org.neo4j.driver.reactive.RxTransaction; +import org.neo4j.driver.summary.QueryType; +import org.neo4j.driver.summary.ResultSummary; +import org.neo4j.driver.types.Node; +import org.neo4j.driver.util.DatabaseExtension; +import org.neo4j.driver.util.ParallelizableIT; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +@EnabledOnNeo4jWith(BOLT_V4) @ParallelizableIT -class RxTransactionIT -{ +class RxTransactionIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private RxSession session; @BeforeEach - void setUp() - { + void setUp() { session = neo4j.driver().rxSession(); } @Test - void shouldBePossibleToCommitEmptyTx() - { + void shouldBePossibleToCommitEmptyTx() { Bookmark bookmarkBefore = session.lastBookmark(); - Mono commit = Mono.from( session.beginTransaction() ).flatMap( tx -> Mono.from( tx.commit() ) ); - StepVerifier.create( commit ).verifyComplete(); + Mono commit = Mono.from(session.beginTransaction()).flatMap(tx -> Mono.from(tx.commit())); + StepVerifier.create(commit).verifyComplete(); Bookmark bookmarkAfter = session.lastBookmark(); - assertNotNull( bookmarkAfter ); - assertNotEquals( bookmarkBefore, bookmarkAfter ); + assertNotNull(bookmarkAfter); + assertNotEquals(bookmarkBefore, bookmarkAfter); } @Test - void shouldBePossibleToRollbackEmptyTx() - { + void shouldBePossibleToRollbackEmptyTx() { Bookmark bookmarkBefore = session.lastBookmark(); - Mono rollback = Mono.from( session.beginTransaction() ).flatMap( tx -> Mono.from( tx.rollback() ) ); - StepVerifier.create( rollback ).verifyComplete(); + Mono rollback = Mono.from(session.beginTransaction()).flatMap(tx -> Mono.from(tx.rollback())); + StepVerifier.create(rollback).verifyComplete(); Bookmark bookmarkAfter = session.lastBookmark(); - assertEquals( bookmarkBefore, bookmarkAfter ); + assertEquals(bookmarkBefore, bookmarkAfter); } @Test - void shouldBePossibleToRunSingleQueryAndCommit() - { - Flux ids = Flux.usingWhen( session.beginTransaction(), - tx -> Flux.from( tx.run( "CREATE (n:Node {id: 42}) RETURN n" ).records() ) - .map( record -> record.get( 0 ).asNode().get( "id" ).asInt() ), - RxTransaction::commit, ( tx, error ) -> tx.rollback(), null ); + void shouldBePossibleToRunSingleQueryAndCommit() { + Flux ids = Flux.usingWhen( + session.beginTransaction(), + tx -> Flux.from(tx.run("CREATE (n:Node {id: 42}) RETURN n").records()) + .map(record -> record.get(0).asNode().get("id").asInt()), + RxTransaction::commit, + (tx, error) -> tx.rollback(), + null); - StepVerifier.create( ids ).expectNext( 42 ).verifyComplete(); - assertEquals( 1, countNodes( 42 ) ); + StepVerifier.create(ids).expectNext(42).verifyComplete(); + assertEquals(1, countNodes(42)); } @Test - void shouldBePossibleToRunSingleQueryAndRollback() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertCanRunCreate( tx ); - assertCanRollback( tx ); - + void shouldBePossibleToRunSingleQueryAndRollback() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertCanRunCreate(tx); + assertCanRollback(tx); - assertEquals( 0, countNodes( 4242 ) ); + assertEquals(0, countNodes(4242)); } @ParameterizedTest - @MethodSource( "commit" ) - void shouldBePossibleToRunMultipleQueries(boolean commit ) - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + @MethodSource("commit") + void shouldBePossibleToRunMultipleQueries(boolean commit) { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - RxResult cursor1 = tx.run( "CREATE (n:Node {id: 1})" ); - await( cursor1.records() ); + RxResult cursor1 = tx.run("CREATE (n:Node {id: 1})"); + await(cursor1.records()); - RxResult cursor2 = tx.run( "CREATE (n:Node {id: 2})" ); - await( cursor2.records() ); + RxResult cursor2 = tx.run("CREATE (n:Node {id: 2})"); + await(cursor2.records()); - RxResult cursor3 = tx.run( "CREATE (n:Node {id: 1})" ); - await( cursor3.records() ); + RxResult cursor3 = tx.run("CREATE (n:Node {id: 1})"); + await(cursor3.records()); - assertCanCommitOrRollback( commit, tx ); + assertCanCommitOrRollback(commit, tx); - verifyCommittedOrRolledBack( commit ); + verifyCommittedOrRolledBack(commit); } @ParameterizedTest - @MethodSource( "commit" ) - void shouldBePossibleToRunMultipleQueriesWithoutWaiting(boolean commit ) - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + @MethodSource("commit") + void shouldBePossibleToRunMultipleQueriesWithoutWaiting(boolean commit) { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - RxResult cursor1 = tx.run( "CREATE (n:Node {id: 1})" ); - RxResult cursor2 = tx.run( "CREATE (n:Node {id: 2})" ); - RxResult cursor3 = tx.run( "CREATE (n:Node {id: 1})" ); + RxResult cursor1 = tx.run("CREATE (n:Node {id: 1})"); + RxResult cursor2 = tx.run("CREATE (n:Node {id: 2})"); + RxResult cursor3 = tx.run("CREATE (n:Node {id: 1})"); - await( Flux.from( cursor1.records() ).concatWith( cursor2.records() ).concatWith( cursor3.records() ) ); - assertCanCommitOrRollback( commit, tx ); + await(Flux.from(cursor1.records()).concatWith(cursor2.records()).concatWith(cursor3.records())); + assertCanCommitOrRollback(commit, tx); - verifyCommittedOrRolledBack( commit ); + verifyCommittedOrRolledBack(commit); } @ParameterizedTest - @MethodSource( "commit" ) - void shouldRunQueriesOnResultPublish(boolean commit ) - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + @MethodSource("commit") + void shouldRunQueriesOnResultPublish(boolean commit) { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - RxResult cursor1 = tx.run( "CREATE (n:Person {name: 'Alice'}) RETURN n.name" ); - RxResult cursor2 = tx.run( "CREATE (n:Person {name: 'Bob'}) RETURN n.name" ); + RxResult cursor1 = tx.run("CREATE (n:Person {name: 'Alice'}) RETURN n.name"); + RxResult cursor2 = tx.run("CREATE (n:Person {name: 'Bob'}) RETURN n.name"); // The execution order is the same as the record publishing order. - List records = await( Flux.from( cursor2.records() ).concatWith( cursor1.records() ) ); - assertThat( records.size(), equalTo( 2 ) ); - assertThat( records.get( 0 ).get( "n.name" ).asString(), equalTo( "Bob" ) ); - assertThat( records.get( 1 ).get( "n.name" ).asString(), equalTo( "Alice" ) ); + List records = await(Flux.from(cursor2.records()).concatWith(cursor1.records())); + assertThat(records.size(), equalTo(2)); + assertThat(records.get(0).get("n.name").asString(), equalTo("Bob")); + assertThat(records.get(1).get("n.name").asString(), equalTo("Alice")); - assertCanCommitOrRollback( commit, tx ); + assertCanCommitOrRollback(commit, tx); } @ParameterizedTest - @MethodSource( "commit" ) - void shouldDiscardOnCommitOrRollback( boolean commit ) - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult cursor = tx.run( "UNWIND [1,2,3,4] AS a RETURN a" ); + @MethodSource("commit") + void shouldDiscardOnCommitOrRollback(boolean commit) { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult cursor = tx.run("UNWIND [1,2,3,4] AS a RETURN a"); // We only perform run without any pull - await( Flux.from( cursor.keys() ) ); + await(Flux.from(cursor.keys())); // We shall perform a discard here and then commit/rollback - assertCanCommitOrRollback( commit, tx ); + assertCanCommitOrRollback(commit, tx); // As a result the records size shall be 0. - StepVerifier.create( Flux.from( cursor.records() ) ) - .expectErrorSatisfies( error -> assertThat( error.getMessage(), CoreMatchers.containsString( "has already been consumed" ) ) ) + StepVerifier.create(Flux.from(cursor.records())) + .expectErrorSatisfies(error -> + assertThat(error.getMessage(), CoreMatchers.containsString("has already been consumed"))) .verify(); } @ParameterizedTest - @MethodSource( "commit" ) - void shouldBePossibleToRunMultipleQueriesWithoutStreaming(boolean commit ) - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + @MethodSource("commit") + void shouldBePossibleToRunMultipleQueriesWithoutStreaming(boolean commit) { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - RxResult cursor1 = tx.run( "CREATE (n:Node {id: 1})" ); - RxResult cursor2 = tx.run( "CREATE (n:Node {id: 2})" ); - RxResult cursor3 = tx.run( "CREATE (n:Node {id: 1})" ); + RxResult cursor1 = tx.run("CREATE (n:Node {id: 1})"); + RxResult cursor2 = tx.run("CREATE (n:Node {id: 2})"); + RxResult cursor3 = tx.run("CREATE (n:Node {id: 1})"); - await( Flux.from( cursor1.keys() ).concatWith( cursor2.keys() ).concatWith( cursor3.keys() ) ); - assertCanCommitOrRollback( commit, tx ); + await(Flux.from(cursor1.keys()).concatWith(cursor2.keys()).concatWith(cursor3.keys())); + assertCanCommitOrRollback(commit, tx); - verifyCommittedOrRolledBack( commit ); + verifyCommittedOrRolledBack(commit); } @Test - void shouldFailToCommitAfterSingleWrongQuery() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertFailToRunWrongQuery( tx ); - assertThrows( ClientException.class, () -> await( tx.commit() ) ); + void shouldFailToCommitAfterSingleWrongQuery() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertFailToRunWrongQuery(tx); + assertThrows(ClientException.class, () -> await(tx.commit())); } @Test - void shouldAllowRollbackAfterSingleWrongQuery() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertFailToRunWrongQuery( tx ); - assertCanRollback( tx ); + void shouldAllowRollbackAfterSingleWrongQuery() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertFailToRunWrongQuery(tx); + assertCanRollback(tx); } @Test - void shouldFailToCommitAfterCoupleCorrectAndSingleWrongQuery() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + void shouldFailToCommitAfterCoupleCorrectAndSingleWrongQuery() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - assertCanRunCreate( tx ); - assertCanRunReturnOne( tx ); - assertFailToRunWrongQuery( tx ); + assertCanRunCreate(tx); + assertCanRunReturnOne(tx); + assertFailToRunWrongQuery(tx); - assertThrows( ClientException.class, () -> await( tx.commit() ) ); + assertThrows(ClientException.class, () -> await(tx.commit())); } @Test - void shouldAllowRollbackAfterCoupleCorrectAndSingleWrongQuery() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertCanRunCreate( tx ); - assertCanRunReturnOne( tx ); - assertFailToRunWrongQuery( tx ); + void shouldAllowRollbackAfterCoupleCorrectAndSingleWrongQuery() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertCanRunCreate(tx); + assertCanRunReturnOne(tx); + assertFailToRunWrongQuery(tx); - assertCanRollback( tx ); + assertCanRollback(tx); } @Test - void shouldNotAllowNewQueriesAfterAnIncorrectQuery() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertFailToRunWrongQuery( tx ); + void shouldNotAllowNewQueriesAfterAnIncorrectQuery() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertFailToRunWrongQuery(tx); - RxResult result = tx.run( "CREATE ()" ); - Exception e = assertThrows( Exception.class, () -> await( result.records() ) ); - assertThat( e.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); + RxResult result = tx.run("CREATE ()"); + Exception e = assertThrows(Exception.class, () -> await(result.records())); + assertThat(e.getMessage(), startsWith("Cannot run more queries in this transaction")); - assertCanRollback( tx ); + assertCanRollback(tx); } @Test - void shouldFailBoBeginTxWithInvalidBookmark() - { - RxSession session = neo4j.driver().rxSession( builder().withBookmarks( parse( "InvalidBookmark" ) ).build() ); + void shouldFailBoBeginTxWithInvalidBookmark() { + RxSession session = neo4j.driver() + .rxSession(builder().withBookmarks(parse("InvalidBookmark")).build()); - ClientException e = assertThrows( ClientException.class, () -> await( session.beginTransaction() ) ); - assertThat( e.getMessage(), containsString( "InvalidBookmark" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(session.beginTransaction())); + assertThat(e.getMessage(), containsString("InvalidBookmark")); } @Test - void shouldFailToCommitWhenCommitted() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertCanRunCreate( tx ); - assertCanCommit( tx ); + void shouldFailToCommitWhenCommitted() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertCanRunCreate(tx); + assertCanCommit(tx); - Mono secondCommit = Mono.from( tx.commit() ); + Mono secondCommit = Mono.from(tx.commit()); // second commit should wrap around a completed future - StepVerifier.create( secondCommit ).expectErrorSatisfies( error -> { - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), startsWith( "Can't commit, transaction has been committed" ) ); - } ).verify(); - + StepVerifier.create(secondCommit) + .expectErrorSatisfies(error -> { + assertThat(error, instanceOf(ClientException.class)); + assertThat(error.getMessage(), startsWith("Can't commit, transaction has been committed")); + }) + .verify(); } @Test - void shouldFailToRollbackWhenRolledBack() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertCanRunCreate( tx ); - assertCanRollback( tx ); + void shouldFailToRollbackWhenRolledBack() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertCanRunCreate(tx); + assertCanRollback(tx); - Mono secondRollback = Mono.from( tx.rollback() ); + Mono secondRollback = Mono.from(tx.rollback()); // second rollback should wrap around a completed future - StepVerifier.create( secondRollback ).expectErrorSatisfies( error -> { - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), startsWith( "Can't rollback, transaction has been rolled back" ) ); - } ).verify(); + StepVerifier.create(secondRollback) + .expectErrorSatisfies(error -> { + assertThat(error, instanceOf(ClientException.class)); + assertThat(error.getMessage(), startsWith("Can't rollback, transaction has been rolled back")); + }) + .verify(); } @Test - void shouldFailToCommitWhenRolledBack() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertCanRunCreate( tx ); - assertCanRollback( tx ); + void shouldFailToCommitWhenRolledBack() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertCanRunCreate(tx); + assertCanRollback(tx); // should not be possible to commit after rollback - ClientException e = assertThrows( ClientException.class, () -> await( tx.commit() ) ); - assertThat( e.getMessage(), containsString( "transaction has been rolled back" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commit())); + assertThat(e.getMessage(), containsString("transaction has been rolled back")); } @Test - void shouldFailToRollbackWhenCommitted() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertCanRunCreate( tx ); - assertCanCommit( tx ); + void shouldFailToRollbackWhenCommitted() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertCanRunCreate(tx); + assertCanCommit(tx); // should not be possible to rollback after commit - ClientException e = assertThrows( ClientException.class, () -> await( tx.rollback() ) ); - assertThat( e.getMessage(), containsString( "transaction has been committed" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.rollback())); + assertThat(e.getMessage(), containsString("transaction has been committed")); } @Test - void shouldAllowRollbackAfterFailedCommit() - { - Flux records = Flux.usingWhen( session.beginTransaction(), - tx -> Flux.from( tx.run( "WRONG" ).records() ), - RxTransaction::commit, ( tx, error ) -> tx.rollback(), null ); + void shouldAllowRollbackAfterFailedCommit() { + Flux records = Flux.usingWhen( + session.beginTransaction(), + tx -> Flux.from(tx.run("WRONG").records()), + RxTransaction::commit, + (tx, error) -> tx.rollback(), + null); - StepVerifier.create( records ).verifyErrorSatisfies( error -> - assertThat( error.getMessage(), containsString( "Invalid input" ) ) ); + StepVerifier.create(records) + .verifyErrorSatisfies(error -> assertThat(error.getMessage(), containsString("Invalid input"))); } @Test - void shouldExposeQueryKeysForColumnsWithAliases() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "RETURN 1 AS one, 2 AS two, 3 AS three, 4 AS five" ); + void shouldExposeQueryKeysForColumnsWithAliases() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("RETURN 1 AS one, 2 AS two, 3 AS three, 4 AS five"); - List keys = await( Mono.from( result.keys() ) ); - assertEquals( Arrays.asList( "one", "two", "three", "five" ), keys ); + List keys = await(Mono.from(result.keys())); + assertEquals(Arrays.asList("one", "two", "three", "five"), keys); - assertCanRollback( tx ); // you still need to rollback the tx as tx will not automatically closed + assertCanRollback(tx); // you still need to rollback the tx as tx will not automatically closed } @Test - void shouldExposeQueryKeysForColumnsWithoutAliases() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "RETURN 1, 2, 3, 5" ); + void shouldExposeQueryKeysForColumnsWithoutAliases() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("RETURN 1, 2, 3, 5"); - List keys = await( Mono.from( result.keys() ) ); - assertEquals( Arrays.asList( "1", "2", "3", "5" ), keys ); + List keys = await(Mono.from(result.keys())); + assertEquals(Arrays.asList("1", "2", "3", "5"), keys); - assertCanRollback( tx ); // you still need to rollback the tx as tx will not automatically closed + assertCanRollback(tx); // you still need to rollback the tx as tx will not automatically closed } @Test - void shouldExposeResultSummaryForSimpleQuery() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + void shouldExposeResultSummaryForSimpleQuery() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); String query = "CREATE (p1:Person {name: $name1})-[:KNOWS]->(p2:Person {name: $name2}) RETURN p1, p2"; - Value params = parameters( "name1", "Bob", "name2", "John" ); + Value params = parameters("name1", "Bob", "name2", "John"); - RxResult result = tx.run( query, params ); - await( result.records() ); // we run and stream + RxResult result = tx.run(query, params); + await(result.records()); // we run and stream - ResultSummary summary = await( Mono.from( result.consume() ) ); + ResultSummary summary = await(Mono.from(result.consume())); - assertEquals( new Query( query, params ), summary.query() ); - assertEquals( 2, summary.counters().nodesCreated() ); - assertEquals( 2, summary.counters().labelsAdded() ); - assertEquals( 2, summary.counters().propertiesSet() ); - assertEquals( 1, summary.counters().relationshipsCreated() ); - assertEquals( QueryType.READ_WRITE, summary.queryType() ); - assertFalse( summary.hasPlan() ); - assertFalse( summary.hasProfile() ); - assertNull( summary.plan() ); - assertNull( summary.profile() ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); - - assertCanRollback( tx ); // you still need to rollback the tx as tx will not automatically closed + assertEquals(new Query(query, params), summary.query()); + assertEquals(2, summary.counters().nodesCreated()); + assertEquals(2, summary.counters().labelsAdded()); + assertEquals(2, summary.counters().propertiesSet()); + assertEquals(1, summary.counters().relationshipsCreated()); + assertEquals(QueryType.READ_WRITE, summary.queryType()); + assertFalse(summary.hasPlan()); + assertFalse(summary.hasProfile()); + assertNull(summary.plan()); + assertNull(summary.profile()); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); + assertCanRollback(tx); // you still need to rollback the tx as tx will not automatically closed } @Test - void shouldExposeResultSummaryForExplainQuery() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + void shouldExposeResultSummaryForExplainQuery() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); String query = "EXPLAIN MATCH (n) RETURN n"; - RxResult result = tx.run( query ); - await( result.records() ); // we run and stream + RxResult result = tx.run(query); + await(result.records()); // we run and stream - ResultSummary summary = await( Mono.from( result.consume() ) ); + ResultSummary summary = await(Mono.from(result.consume())); - assertEquals( new Query( query ), summary.query() ); - assertEquals( 0, summary.counters().nodesCreated() ); - assertEquals( 0, summary.counters().propertiesSet() ); - assertEquals( QueryType.READ_ONLY, summary.queryType() ); - assertTrue( summary.hasPlan() ); - assertFalse( summary.hasProfile() ); - assertNotNull( summary.plan() ); + assertEquals(new Query(query), summary.query()); + assertEquals(0, summary.counters().nodesCreated()); + assertEquals(0, summary.counters().propertiesSet()); + assertEquals(QueryType.READ_ONLY, summary.queryType()); + assertTrue(summary.hasPlan()); + assertFalse(summary.hasProfile()); + assertNotNull(summary.plan()); // asserting on plan is a bit fragile and can break when server side changes or with different // server versions; that is why do fuzzy assertions in this test based on string content - assertThat( summary.plan().toString().toLowerCase(), containsString( "scan" ) ); - assertNull( summary.profile() ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); + assertThat(summary.plan().toString().toLowerCase(), containsString("scan")); + assertNull(summary.profile()); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); - assertCanRollback( tx ); // you still need to rollback the tx as tx will not automatically closed + assertCanRollback(tx); // you still need to rollback the tx as tx will not automatically closed } @Test - void shouldExposeResultSummaryForProfileQuery() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - String query = "PROFILE MERGE (n {name: $name}) " + - "ON CREATE SET n.created = timestamp() " + - "ON MATCH SET n.counter = coalesce(n.counter, 0) + 1"; + void shouldExposeResultSummaryForProfileQuery() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + String query = "PROFILE MERGE (n {name: $name}) " + "ON CREATE SET n.created = timestamp() " + + "ON MATCH SET n.counter = coalesce(n.counter, 0) + 1"; - Value params = parameters( "name", "Bob" ); + Value params = parameters("name", "Bob"); - RxResult result = tx.run( query, params ); - await( result.records() ); // we run and stream + RxResult result = tx.run(query, params); + await(result.records()); // we run and stream - ResultSummary summary = await( Mono.from( result.consume() ) ); + ResultSummary summary = await(Mono.from(result.consume())); - assertEquals( new Query( query, params ), summary.query() ); - assertEquals( 1, summary.counters().nodesCreated() ); - assertEquals( 2, summary.counters().propertiesSet() ); - assertEquals( 0, summary.counters().relationshipsCreated() ); - assertEquals( QueryType.WRITE_ONLY, summary.queryType() ); - assertTrue( summary.hasPlan() ); - assertTrue( summary.hasProfile() ); - assertNotNull( summary.plan() ); - assertNotNull( summary.profile() ); + assertEquals(new Query(query, params), summary.query()); + assertEquals(1, summary.counters().nodesCreated()); + assertEquals(2, summary.counters().propertiesSet()); + assertEquals(0, summary.counters().relationshipsCreated()); + assertEquals(QueryType.WRITE_ONLY, summary.queryType()); + assertTrue(summary.hasPlan()); + assertTrue(summary.hasProfile()); + assertNotNull(summary.plan()); + assertNotNull(summary.profile()); // asserting on profile is a bit fragile and can break when server side changes or with different // server versions; that is why do fuzzy assertions in this test based on string content String profileAsString = summary.profile().toString().toLowerCase(); - assertThat( profileAsString, containsString( "hits" ) ); - assertEquals( 0, summary.notifications().size() ); - assertThat( summary, containsResultAvailableAfterAndResultConsumedAfter() ); + assertThat(profileAsString, containsString("hits")); + assertEquals(0, summary.notifications().size()); + assertThat(summary, containsResultAvailableAfterAndResultConsumedAfter()); - assertCanRollback( tx ); // you still need to rollback the tx as tx will not automatically closed + assertCanRollback(tx); // you still need to rollback the tx as tx will not automatically closed } @Test - void shouldCancelRecordStream() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "UNWIND ['a', 'b', 'c'] AS x RETURN x" ); + void shouldCancelRecordStream() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("UNWIND ['a', 'b', 'c'] AS x RETURN x"); - Flux abc = Flux.from( result.records() ).limitRate( 1 ).take( 1 ).map( record -> record.get( 0 ).asString() ); - StepVerifier.create( abc ).expectNext( "a" ).verifyComplete(); + Flux abc = Flux.from(result.records()).limitRate(1).take(1).map(record -> record.get(0) + .asString()); + StepVerifier.create(abc).expectNext("a").verifyComplete(); - assertCanRollback( tx ); // you still need to rollback the tx as tx will not automatically closed + assertCanRollback(tx); // you still need to rollback the tx as tx will not automatically closed } @Test - void shouldForEachWithEmptyCursor() - { - testForEach( "MATCH (n:SomeReallyStrangeLabel) RETURN n", 0 ); + void shouldForEachWithEmptyCursor() { + testForEach("MATCH (n:SomeReallyStrangeLabel) RETURN n", 0); } @Test - void shouldForEachWithNonEmptyCursor() - { - testForEach( "UNWIND range(1, 12555) AS x CREATE (n:Node {id: x}) RETURN n", 12555 ); + void shouldForEachWithNonEmptyCursor() { + testForEach("UNWIND range(1, 12555) AS x CREATE (n:Node {id: x}) RETURN n", 12555); } @Test - void shouldFailForEachWhenActionFails() - { + void shouldFailForEachWhenActionFails() { RuntimeException e = new RuntimeException(); - Flux records = Flux.usingWhen( session.beginTransaction(), - tx -> Flux.from( tx.run( "RETURN 'Hi!'" ).records() ).doOnNext( record -> { throw e; } ), + Flux records = Flux.usingWhen( + session.beginTransaction(), + tx -> Flux.from(tx.run("RETURN 'Hi!'").records()).doOnNext(record -> { + throw e; + }), RxTransaction::commit, - ( tx, error ) -> tx.rollback(), null ); + (tx, error) -> tx.rollback(), + null); - StepVerifier.create( records ).expectErrorSatisfies( error -> assertEquals( e, error ) ).verify(); + StepVerifier.create(records) + .expectErrorSatisfies(error -> assertEquals(e, error)) + .verify(); } @Test - void shouldConvertToListWithEmptyCursor() - { - testList( "CREATE (:Person)-[:KNOWS]->(:Person)", emptyList() ); + void shouldConvertToListWithEmptyCursor() { + testList("CREATE (:Person)-[:KNOWS]->(:Person)", emptyList()); } @Test - void shouldConvertToListWithNonEmptyCursor() - { - testList( "UNWIND [1, '1', 2, '2', 3, '3'] AS x RETURN x", Arrays.asList( 1L, "1", 2L, "2", 3L, "3" ) ); + void shouldConvertToListWithNonEmptyCursor() { + testList("UNWIND [1, '1', 2, '2', 3, '3'] AS x RETURN x", Arrays.asList(1L, "1", 2L, "2", 3L, "3")); } @Test - void shouldConvertToTransformedListWithEmptyCursor() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "CREATE ()" ); - List> maps = await( Flux.from( result.records() ).map( record -> record.get( 0 ).asMap() ) ); - assertEquals( 0, maps.size() ); - assertCanRollback( tx ); + void shouldConvertToTransformedListWithEmptyCursor() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("CREATE ()"); + List> maps = + await(Flux.from(result.records()).map(record -> record.get(0).asMap())); + assertEquals(0, maps.size()); + assertCanRollback(tx); } @Test - void shouldConvertToTransformedListWithNonEmptyCursor() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "UNWIND ['a', 'b', 'c'] AS x RETURN x" ); - List strings = await( Flux.from( result.records() ).map( record -> record.get( 0 ).asString() + "!" ) ); + void shouldConvertToTransformedListWithNonEmptyCursor() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("UNWIND ['a', 'b', 'c'] AS x RETURN x"); + List strings = + await(Flux.from(result.records()).map(record -> record.get(0).asString() + "!")); - assertEquals( Arrays.asList( "a!", "b!", "c!" ), strings ); - assertCanRollback( tx ); + assertEquals(Arrays.asList("a!", "b!", "c!"), strings); + assertCanRollback(tx); } @Test - void shouldFailWhenListTransformationFunctionFails() - { + void shouldFailWhenListTransformationFunctionFails() { RuntimeException e = new RuntimeException(); - Flux records = Flux.usingWhen( session.beginTransaction(), - tx -> Flux.from( tx.run( "RETURN 'Hi!'" ).records() ).map( record -> { throw e; } ), - RxTransaction::commit, ( tx, error ) -> tx.rollback(), null ); + Flux records = Flux.usingWhen( + session.beginTransaction(), + tx -> Flux.from(tx.run("RETURN 'Hi!'").records()).map(record -> { + throw e; + }), + RxTransaction::commit, + (tx, error) -> tx.rollback(), + null); - StepVerifier.create( records ).expectErrorSatisfies( error -> { - assertEquals( e, error ); - } ).verify(); + StepVerifier.create(records) + .expectErrorSatisfies(error -> { + assertEquals(e, error); + }) + .verify(); } @Test - void shouldFailToCommitWhenServerIsRestarted() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "RETURN 1" ); + void shouldFailToCommitWhenServerIsRestarted() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("RETURN 1"); - assertThrows( ServiceUnavailableException.class, () -> { - await( Flux.from( result.records() ).doOnSubscribe( subscription -> { + assertThrows(ServiceUnavailableException.class, () -> { + await(Flux.from(result.records()).doOnSubscribe(subscription -> { neo4j.stopDb(); - } ) ); - await( tx.commit() ); - } ); + })); + await(tx.commit()); + }); - assertCanRollback( tx ); + assertCanRollback(tx); } @Test - void shouldFailSingleWithEmptyCursor() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "MATCH (n:NoSuchLabel) RETURN n" ); + void shouldFailSingleWithEmptyCursor() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("MATCH (n:NoSuchLabel) RETURN n"); - NoSuchElementException e = assertThrows( NoSuchElementException.class, () -> await( Flux.from( result.records() ).single() ) ); - assertThat( e.getMessage(), containsString( "Source was empty" ) ); - assertCanRollback( tx ); + NoSuchElementException e = assertThrows( + NoSuchElementException.class, + () -> await(Flux.from(result.records()).single())); + assertThat(e.getMessage(), containsString("Source was empty")); + assertCanRollback(tx); } @Test - void shouldFailSingleWithMultiRecordCursor() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "UNWIND ['a', 'b'] AS x RETURN x" ); + void shouldFailSingleWithMultiRecordCursor() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("UNWIND ['a', 'b'] AS x RETURN x"); - IndexOutOfBoundsException e = assertThrows( IndexOutOfBoundsException.class, () -> await( Flux.from( result.records() ).single() ) ); - assertThat( e.getMessage(), startsWith( "Source emitted more than one item" ) ); - assertCanRollback( tx ); + IndexOutOfBoundsException e = assertThrows( + IndexOutOfBoundsException.class, + () -> await(Flux.from(result.records()).single())); + assertThat(e.getMessage(), startsWith("Source emitted more than one item")); + assertCanRollback(tx); } @Test - void shouldReturnSingleWithSingleRecordCursor() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "RETURN 'Hello!'" ); + void shouldReturnSingleWithSingleRecordCursor() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("RETURN 'Hello!'"); - Record record = await( Flux.from( result.records() ).single() ); - assertEquals( "Hello!", record.get( 0 ).asString() ); - assertCanRollback( tx ); + Record record = await(Flux.from(result.records()).single()); + assertEquals("Hello!", record.get(0).asString()); + assertCanRollback(tx); } @Test - void shouldPropagateFailureFromFirstRecordInSingleAsync() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "UNWIND [0] AS x RETURN 10 / x" ); + void shouldPropagateFailureFromFirstRecordInSingleAsync() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("UNWIND [0] AS x RETURN 10 / x"); - ClientException e = assertThrows( ClientException.class, () -> await( Flux.from( result.records() ).single() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); - assertCanRollback( tx ); + ClientException e = assertThrows( + ClientException.class, () -> await(Flux.from(result.records()).single())); + assertThat(e.getMessage(), containsString("/ by zero")); + assertCanRollback(tx); } @Test - void shouldPropagateFailureFromSecondRecordInSingleAsync() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "UNWIND [1, 0] AS x RETURN 10 / x" ); + void shouldPropagateFailureFromSecondRecordInSingleAsync() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("UNWIND [1, 0] AS x RETURN 10 / x"); - ClientException e = assertThrows( ClientException.class, () -> await( Flux.from( result.records() ).single() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); - assertCanRollback( tx ); + ClientException e = assertThrows( + ClientException.class, () -> await(Flux.from(result.records()).single())); + assertThat(e.getMessage(), containsString("/ by zero")); + assertCanRollback(tx); } @Test - void shouldConsumeEmptyCursor() - { - testConsume( "MATCH (n:NoSuchLabel) RETURN n" ); + void shouldConsumeEmptyCursor() { + testConsume("MATCH (n:NoSuchLabel) RETURN n"); } @Test - void shouldConsumeNonEmptyCursor() - { - testConsume( "RETURN 42" ); + void shouldConsumeNonEmptyCursor() { + testConsume("RETURN 42"); } @ParameterizedTest - @MethodSource( "commit" ) - void shouldFailToRunQueryAfterCommit( boolean commit ) - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "CREATE (:MyLabel)" ); - await( result.records() ); - - assertCanCommitOrRollback( commit, tx ); - - Record record = await( Flux.from( session.run( "MATCH (n:MyLabel) RETURN count(n)" ).records() ).single() ); - if( commit ) - { - assertEquals( 1, record.get( 0 ).asInt() ); - } - else - { - assertEquals( 0, record.get( 0 ).asInt() ); + @MethodSource("commit") + void shouldFailToRunQueryAfterCommit(boolean commit) { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("CREATE (:MyLabel)"); + await(result.records()); + + assertCanCommitOrRollback(commit, tx); + + Record record = + await(Flux.from(session.run("MATCH (n:MyLabel) RETURN count(n)").records()) + .single()); + if (commit) { + assertEquals(1, record.get(0).asInt()); + } else { + assertEquals(0, record.get(0).asInt()); } - ClientException e = assertThrows( ClientException.class, () -> await( tx.run( "CREATE (:MyOtherLabel)" ).records() ) ); - assertThat( e.getMessage(), containsString( "Cannot run more queries in this transaction, it has been " ) ); + ClientException e = assertThrows( + ClientException.class, + () -> await(tx.run("CREATE (:MyOtherLabel)").records())); + assertThat(e.getMessage(), containsString("Cannot run more queries in this transaction, it has been ")); } @Test - void shouldFailToRunQueryWhenTerminated() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - assertFailToRunWrongQuery( tx ); + void shouldFailToRunQueryWhenTerminated() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + assertFailToRunWrongQuery(tx); - ClientException e = assertThrows( ClientException.class, () -> await( tx.run( "CREATE (:MyOtherLabel)" ).records() ) ); - assertThat( e.getMessage(), startsWith( "Cannot run more queries in this transaction" ) ); + ClientException e = assertThrows( + ClientException.class, + () -> await(tx.run("CREATE (:MyOtherLabel)").records())); + assertThat(e.getMessage(), startsWith("Cannot run more queries in this transaction")); - assertCanRollback( tx ); + assertCanRollback(tx); } @Test - void shouldUpdateSessionBookmarkAfterCommit() - { + void shouldUpdateSessionBookmarkAfterCommit() { Bookmark bookmarkBefore = session.lastBookmark(); - await( Flux.usingWhen( session.beginTransaction(), - tx -> tx.run( "CREATE (:MyNode)" ).records(), + await(Flux.usingWhen( + session.beginTransaction(), + tx -> tx.run("CREATE (:MyNode)").records(), RxTransaction::commit, - ( tx, error ) -> tx.rollback(), null ) ); + (tx, error) -> tx.rollback(), + null)); Bookmark bookmarkAfter = session.lastBookmark(); - assertNotNull( bookmarkAfter ); - assertNotEquals( bookmarkBefore, bookmarkAfter ); + assertNotNull(bookmarkAfter); + assertNotEquals(bookmarkBefore, bookmarkAfter); } @Test - void shouldFailToCommitWhenQueriesFailAndErrorNotConsumed() throws InterruptedException - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + void shouldFailToCommitWhenQueriesFailAndErrorNotConsumed() throws InterruptedException { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - RxResult result1 = tx.run( "CREATE (:TestNode)" ); - RxResult result2 = tx.run( "CREATE (:TestNode)" ); - RxResult result3 = tx.run( "RETURN 10 / 0" ); - RxResult result4 = tx.run( "CREATE (:TestNode)" ); + RxResult result1 = tx.run("CREATE (:TestNode)"); + RxResult result2 = tx.run("CREATE (:TestNode)"); + RxResult result3 = tx.run("RETURN 10 / 0"); + RxResult result4 = tx.run("CREATE (:TestNode)"); - Flux records = - Flux.from( result1.records() ).concatWith( result2.records() ).concatWith( result3.records() ).concatWith( result4.records() ); - ClientException e = assertThrows( ClientException.class, () -> await( records ) ); - assertEquals( "/ by zero", e.getMessage() ); - assertCanRollback( tx ); + Flux records = Flux.from(result1.records()) + .concatWith(result2.records()) + .concatWith(result3.records()) + .concatWith(result4.records()); + ClientException e = assertThrows(ClientException.class, () -> await(records)); + assertEquals("/ by zero", e.getMessage()); + assertCanRollback(tx); } @Test - void shouldNotRunUntilPublisherIsConnected() throws Throwable - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + void shouldNotRunUntilPublisherIsConnected() throws Throwable { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - RxResult result1 = tx.run( "RETURN 1" ); - RxResult result2 = tx.run( "RETURN 2" ); - RxResult result3 = tx.run( "RETURN 3" ); - RxResult result4 = tx.run( "RETURN 4" ); + RxResult result1 = tx.run("RETURN 1"); + RxResult result2 = tx.run("RETURN 2"); + RxResult result3 = tx.run("RETURN 3"); + RxResult result4 = tx.run("RETURN 4"); - Flux records = - Flux.from( result4.records() ).concatWith( result3.records() ).concatWith( result2.records() ).concatWith( result1.records() ); - StepVerifier.create( records.map( record -> record.get( 0 ).asInt() ) ) - .expectNext( 4 ) - .expectNext( 3 ) - .expectNext( 2 ) - .expectNext( 1 ) + Flux records = Flux.from(result4.records()) + .concatWith(result3.records()) + .concatWith(result2.records()) + .concatWith(result1.records()); + StepVerifier.create(records.map(record -> record.get(0).asInt())) + .expectNext(4) + .expectNext(3) + .expectNext(2) + .expectNext(1) .verifyComplete(); - assertCanRollback( tx ); + assertCanRollback(tx); } @ParameterizedTest - @MethodSource( "commit" ) - void shouldNotPropagateRunFailureIfNotExecuted( boolean commit ) - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + @MethodSource("commit") + void shouldNotPropagateRunFailureIfNotExecuted(boolean commit) { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - tx.run( "RETURN ILLEGAL" ); // no actually executed + tx.run("RETURN ILLEGAL"); // no actually executed - assertCanCommitOrRollback( commit, tx ); + assertCanCommitOrRollback(commit, tx); } @Test - void shouldPropagateRunFailureOnRecord() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "RETURN 42 / 0" ); - await( result.keys() ); // always returns keys + void shouldPropagateRunFailureOnRecord() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("RETURN 42 / 0"); + await(result.keys()); // always returns keys - ClientException e = assertThrows( ClientException.class, () -> await( result.records() ) ); - assertThat( e.getMessage(), containsString( "/ by zero" ) ); - assertCanRollback( tx ); + ClientException e = assertThrows(ClientException.class, () -> await(result.records())); + assertThat(e.getMessage(), containsString("/ by zero")); + assertCanRollback(tx); } @Test - void shouldFailToCommitWhenPullAllFailureIsConsumed() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "FOREACH (value IN [1,2, 'aaa'] | CREATE (:Person {name: 10 / value}))" ); + void shouldFailToCommitWhenPullAllFailureIsConsumed() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("FOREACH (value IN [1,2, 'aaa'] | CREATE (:Person {name: 10 / value}))"); - ClientException e1 = assertThrows( ClientException.class, () -> await( result.records() ) ); - assertThat( e1.code(), containsString( "TypeError" ) ); + ClientException e1 = assertThrows(ClientException.class, () -> await(result.records())); + assertThat(e1.code(), containsString("TypeError")); - ClientException e2 = assertThrows( ClientException.class, () -> await( tx.commit() ) ); - assertThat( e2.getMessage(), startsWith( "Transaction can't be committed" ) ); + ClientException e2 = assertThrows(ClientException.class, () -> await(tx.commit())); + assertThat(e2.getMessage(), startsWith("Transaction can't be committed")); } @Test - void shouldBeAbleToRollbackWhenPullAllFailureIsConsumed() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); - RxResult result = tx.run( "FOREACH (value IN [1,2, 'aaa'] | CREATE (:Person {name: 10 / value}))" ); + void shouldBeAbleToRollbackWhenPullAllFailureIsConsumed() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); + RxResult result = tx.run("FOREACH (value IN [1,2, 'aaa'] | CREATE (:Person {name: 10 / value}))"); - ClientException e1 = assertThrows( ClientException.class, () -> await( result.records() ) ); - assertThat( e1.code(), containsString( "TypeError" ) ); + ClientException e1 = assertThrows(ClientException.class, () -> await(result.records())); + assertThat(e1.code(), containsString("TypeError")); - assertCanRollback( tx ); + assertCanRollback(tx); } @Test - void shouldNotPropagateRunFailureFromSummary() - { - RxTransaction tx = await( Mono.from( session.beginTransaction() ) ); + void shouldNotPropagateRunFailureFromSummary() { + RxTransaction tx = await(Mono.from(session.beginTransaction())); - RxResult result = tx.run( "RETURN Wrong" ); - ClientException e = assertThrows( ClientException.class, () -> await( result.records() ) ); - assertThat( e.code(), containsString( "SyntaxError" ) ); + RxResult result = tx.run("RETURN Wrong"); + ClientException e = assertThrows(ClientException.class, () -> await(result.records())); + assertThat(e.code(), containsString("SyntaxError")); - await( result.consume() ); - assertCanRollback( tx ); + await(result.consume()); + assertCanRollback(tx); } - private int countNodes( Object id ) - { - RxResult result = session.run( "MATCH (n:Node {id: $id}) RETURN count(n)", parameters( "id", id ) ); - return await( Flux.from( result.records() ).single().map( record -> record.get( 0 ).asInt() ) ); + private int countNodes(Object id) { + RxResult result = session.run("MATCH (n:Node {id: $id}) RETURN count(n)", parameters("id", id)); + return await( + Flux.from(result.records()).single().map(record -> record.get(0).asInt())); } - private void testForEach( String query, int expectedSeenRecords ) - { - Flux summary = Flux.usingWhen( session.beginTransaction(), tx -> { - RxResult result = tx.run( query ); - AtomicInteger recordsSeen = new AtomicInteger(); - return Flux.from( result.records() ) - .doOnNext( record -> recordsSeen.incrementAndGet() ) - .then( Mono.from( result.consume() ) ) - .doOnSuccess( s -> { - assertNotNull( s ); - assertEquals( query, s.query().text() ); - assertEquals( emptyMap(), s.query().parameters().asMap() ); - assertEquals( expectedSeenRecords, recordsSeen.get() ); - } ); - }, RxTransaction::commit, ( tx, error ) -> tx.rollback(), null ); + private void testForEach(String query, int expectedSeenRecords) { + Flux summary = Flux.usingWhen( + session.beginTransaction(), + tx -> { + RxResult result = tx.run(query); + AtomicInteger recordsSeen = new AtomicInteger(); + return Flux.from(result.records()) + .doOnNext(record -> recordsSeen.incrementAndGet()) + .then(Mono.from(result.consume())) + .doOnSuccess(s -> { + assertNotNull(s); + assertEquals(query, s.query().text()); + assertEquals(emptyMap(), s.query().parameters().asMap()); + assertEquals(expectedSeenRecords, recordsSeen.get()); + }); + }, + RxTransaction::commit, + (tx, error) -> tx.rollback(), + null); - StepVerifier.create( summary ).expectNextCount( 1 ).verifyComplete(); // we indeed get a summary. + StepVerifier.create(summary).expectNextCount(1).verifyComplete(); // we indeed get a summary. } - private void testList( String query, List expectedList ) - { + private void testList(String query, List expectedList) { List actualList = new ArrayList<>(); - Flux> records = Flux.usingWhen( session.beginTransaction(), - tx -> Flux.from( tx.run( query ).records() ).collectList(), + Flux> records = Flux.usingWhen( + session.beginTransaction(), + tx -> Flux.from(tx.run(query).records()).collectList(), RxTransaction::commit, - ( tx, error ) -> tx.rollback(), null ); - - StepVerifier.create( records.single() ).consumeNextWith( allRecords -> { - for ( Record record : allRecords ) - { - actualList.add( record.get( 0 ).asObject() ); - } - } ).verifyComplete(); + (tx, error) -> tx.rollback(), + null); + + StepVerifier.create(records.single()) + .consumeNextWith(allRecords -> { + for (Record record : allRecords) { + actualList.add(record.get(0).asObject()); + } + }) + .verifyComplete(); - assertEquals( expectedList, actualList ); + assertEquals(expectedList, actualList); } - private void testConsume( String query ) - { - Flux summary = Flux.usingWhen( session.beginTransaction(), tx -> - tx.run( query ).consume(), - RxTransaction::commit, ( tx, error ) -> tx.rollback(), null ); + private void testConsume(String query) { + Flux summary = Flux.usingWhen( + session.beginTransaction(), + tx -> tx.run(query).consume(), + RxTransaction::commit, + (tx, error) -> tx.rollback(), + null); - StepVerifier.create( summary.single() ).consumeNextWith( Assertions::assertNotNull ).verifyComplete(); + StepVerifier.create(summary.single()) + .consumeNextWith(Assertions::assertNotNull) + .verifyComplete(); } - private void verifyCommittedOrRolledBack( boolean commit ) - { - if( commit ) - { - assertEquals( 2, countNodes( 1 ) ); - assertEquals( 1, countNodes( 2 ) ); - } - else - { - assertEquals( 0, countNodes( 1 ) ); - assertEquals( 0, countNodes( 2 ) ); + private void verifyCommittedOrRolledBack(boolean commit) { + if (commit) { + assertEquals(2, countNodes(1)); + assertEquals(1, countNodes(2)); + } else { + assertEquals(0, countNodes(1)); + assertEquals(0, countNodes(2)); } } - private void assertCanCommitOrRollback( boolean commit, RxTransaction tx ) - { - if( commit ) - { - assertCanCommit( tx ); - } - else - { - assertCanRollback( tx ); + private void assertCanCommitOrRollback(boolean commit, RxTransaction tx) { + if (commit) { + assertCanCommit(tx); + } else { + assertCanRollback(tx); } } - private void assertCanCommit( RxTransaction tx ) - { - assertThat( await( tx.commit() ), equalTo( emptyList() ) ); + private void assertCanCommit(RxTransaction tx) { + assertThat(await(tx.commit()), equalTo(emptyList())); } - private void assertCanRollback( RxTransaction tx ) - { - assertThat( await( tx.rollback() ), equalTo( emptyList() ) ); + private void assertCanRollback(RxTransaction tx) { + assertThat(await(tx.rollback()), equalTo(emptyList())); } - private static Stream commit() - { - return Stream.of( true, false ); + private static Stream commit() { + return Stream.of(true, false); } - private static void assertCanRunCreate( RxTransaction tx ) - { - RxResult result = tx.run( "CREATE (n:Node {id: 4242}) RETURN n" ); + private static void assertCanRunCreate(RxTransaction tx) { + RxResult result = tx.run("CREATE (n:Node {id: 4242}) RETURN n"); - Record record = await( Flux.from(result.records()).single() ); + Record record = await(Flux.from(result.records()).single()); - Node node = record.get( 0 ).asNode(); - assertEquals( "Node", single( node.labels() ) ); - assertEquals( 4242, node.get( "id" ).asInt() ); + Node node = record.get(0).asNode(); + assertEquals("Node", single(node.labels())); + assertEquals(4242, node.get("id").asInt()); } - private static void assertFailToRunWrongQuery(RxTransaction tx ) - { - RxResult result = tx.run( "RETURN" ); - Exception e = assertThrows( Exception.class, () -> await( result.records() ) ); - assertThat( e, is( syntaxError() ) ); + private static void assertFailToRunWrongQuery(RxTransaction tx) { + RxResult result = tx.run("RETURN"); + Exception e = assertThrows(Exception.class, () -> await(result.records())); + assertThat(e, is(syntaxError())); } - private void assertCanRunReturnOne( RxTransaction tx ) - { - RxResult result = tx.run( "RETURN 42" ); - List records = await( result.records() ); - assertThat( records.size(), equalTo( 1 ) ); - Record record = records.get( 0 ); - assertEquals( 42, record.get( 0 ).asInt() ); + private void assertCanRunReturnOne(RxTransaction tx) { + RxResult result = tx.run("RETURN 42"); + List records = await(result.records()); + assertThat(records.size(), equalTo(1)); + Record record = records.get(0); + assertEquals(42, record.get(0).asInt()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/CustomSecurityPlanTest.java b/driver/src/test/java/org/neo4j/driver/internal/CustomSecurityPlanTest.java index b470953687..765c36163a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/CustomSecurityPlanTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/CustomSecurityPlanTest.java @@ -18,13 +18,15 @@ */ package org.neo4j.driver.internal; -import io.netty.bootstrap.Bootstrap; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import io.netty.bootstrap.Bootstrap; import java.net.URI; import java.util.ArrayList; import java.util.List; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; @@ -35,51 +37,51 @@ import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.spi.ConnectionPool; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; - -class CustomSecurityPlanTest -{ +class CustomSecurityPlanTest { @Test - void testCustomSecurityPlanUsed() - { + void testCustomSecurityPlanUsed() { SecurityPlanCapturingDriverFactory driverFactory = new SecurityPlanCapturingDriverFactory(); - SecurityPlan securityPlan = mock( SecurityPlan.class ); + SecurityPlan securityPlan = mock(SecurityPlan.class); - driverFactory.newInstance( - URI.create( "neo4j://somewhere:1234" ), + driverFactory.newInstance( + URI.create("neo4j://somewhere:1234"), AuthTokens.none(), RoutingSettings.DEFAULT, RetrySettings.DEFAULT, Config.defaultConfig(), null, - securityPlan - ); + securityPlan); - assertFalse( driverFactory.capturedSecurityPlans.isEmpty() ); - assertTrue( driverFactory.capturedSecurityPlans.stream().allMatch( capturePlan -> capturePlan == securityPlan ) ); + assertFalse(driverFactory.capturedSecurityPlans.isEmpty()); + assertTrue(driverFactory.capturedSecurityPlans.stream().allMatch(capturePlan -> capturePlan == securityPlan)); } - - private static class SecurityPlanCapturingDriverFactory extends DriverFactory - { + + private static class SecurityPlanCapturingDriverFactory extends DriverFactory { List capturedSecurityPlans = new ArrayList<>(); @Override - protected InternalDriver createDriver( SecurityPlan securityPlan, SessionFactory sessionFactory, MetricsProvider metricsProvider, Config config ) - { - capturedSecurityPlans.add( securityPlan ); - return super.createDriver( securityPlan, sessionFactory, metricsProvider, config ); + protected InternalDriver createDriver( + SecurityPlan securityPlan, + SessionFactory sessionFactory, + MetricsProvider metricsProvider, + Config config) { + capturedSecurityPlans.add(securityPlan); + return super.createDriver(securityPlan, sessionFactory, metricsProvider, config); } @Override - protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, - MetricsProvider metricsProvider, Config config, boolean ownsEventLoopGroup, - RoutingContext routingContext ) - { - capturedSecurityPlans.add( securityPlan ); - return super.createConnectionPool( authToken, securityPlan, bootstrap, metricsProvider, config, ownsEventLoopGroup, routingContext ); + protected ConnectionPool createConnectionPool( + AuthToken authToken, + SecurityPlan securityPlan, + Bootstrap bootstrap, + MetricsProvider metricsProvider, + Config config, + boolean ownsEventLoopGroup, + RoutingContext routingContext) { + capturedSecurityPlans.add(securityPlan); + return super.createConnectionPool( + authToken, securityPlan, bootstrap, metricsProvider, config, ownsEventLoopGroup, routingContext); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/DatabaseNameUtilTest.java b/driver/src/test/java/org/neo4j/driver/internal/DatabaseNameUtilTest.java index 0932401476..8b849dac38 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DatabaseNameUtilTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DatabaseNameUtilTest.java @@ -18,8 +18,6 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.neo4j.driver.internal.DatabaseNameUtil.DEFAULT_DATABASE_NAME; import static org.neo4j.driver.internal.DatabaseNameUtil.SYSTEM_DATABASE_NAME; @@ -27,27 +25,26 @@ import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; import static org.neo4j.driver.internal.DatabaseNameUtil.systemDatabase; -class DatabaseNameUtilTest -{ +import org.junit.jupiter.api.Test; + +class DatabaseNameUtilTest { @Test - void shouldDatabaseNameBeEqual() throws Throwable - { - assertEquals( defaultDatabase(), defaultDatabase() ); - assertEquals( defaultDatabase(), database( null ) ); - assertEquals( defaultDatabase(), database( DEFAULT_DATABASE_NAME ) ); + void shouldDatabaseNameBeEqual() throws Throwable { + assertEquals(defaultDatabase(), defaultDatabase()); + assertEquals(defaultDatabase(), database(null)); + assertEquals(defaultDatabase(), database(DEFAULT_DATABASE_NAME)); - assertEquals( systemDatabase(), systemDatabase() ); - assertEquals( systemDatabase(), database( "system" ) ); - assertEquals( systemDatabase(), database( SYSTEM_DATABASE_NAME ) ); + assertEquals(systemDatabase(), systemDatabase()); + assertEquals(systemDatabase(), database("system")); + assertEquals(systemDatabase(), database(SYSTEM_DATABASE_NAME)); - assertEquals( database( "hello" ), database( "hello" ) ); + assertEquals(database("hello"), database("hello")); } @Test - void shouldReturnDatabaseNameInDescription() throws Throwable - { - assertEquals( "", defaultDatabase().description() ); - assertEquals( "system", systemDatabase().description() ); - assertEquals( "hello", database( "hello" ).description() ); + void shouldReturnDatabaseNameInDescription() throws Throwable { + assertEquals("", defaultDatabase().description()); + assertEquals("system", systemDatabase().description()); + assertEquals("hello", database("hello").description()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/DefaultBookmarkHolderTest.java b/driver/src/test/java/org/neo4j/driver/internal/DefaultBookmarkHolderTest.java index 2d4c6c089e..ec374425e6 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DefaultBookmarkHolderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DefaultBookmarkHolderTest.java @@ -18,73 +18,67 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; import org.neo4j.driver.Bookmark; -import static org.junit.jupiter.api.Assertions.assertEquals; - -class DefaultBookmarkHolderTest -{ +class DefaultBookmarkHolderTest { @Test - void shouldAllowToGetAndSetBookmarks() - { + void shouldAllowToGetAndSetBookmarks() { BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(); - assertEquals( InternalBookmark.empty(), bookmarkHolder.getBookmark() ); + assertEquals(InternalBookmark.empty(), bookmarkHolder.getBookmark()); - bookmarkHolder.setBookmark( null ); - assertEquals( InternalBookmark.empty(), bookmarkHolder.getBookmark() ); + bookmarkHolder.setBookmark(null); + assertEquals(InternalBookmark.empty(), bookmarkHolder.getBookmark()); - bookmarkHolder.setBookmark( InternalBookmark.empty() ); - assertEquals( InternalBookmark.empty(), bookmarkHolder.getBookmark() ); + bookmarkHolder.setBookmark(InternalBookmark.empty()); + assertEquals(InternalBookmark.empty(), bookmarkHolder.getBookmark()); - Bookmark bookmark1 = InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ); - bookmarkHolder.setBookmark( bookmark1 ); - assertEquals( bookmark1, bookmarkHolder.getBookmark() ); + Bookmark bookmark1 = InternalBookmark.parse("neo4j:bookmark:v1:tx1"); + bookmarkHolder.setBookmark(bookmark1); + assertEquals(bookmark1, bookmarkHolder.getBookmark()); - bookmarkHolder.setBookmark( null ); - assertEquals( bookmark1, bookmarkHolder.getBookmark() ); + bookmarkHolder.setBookmark(null); + assertEquals(bookmark1, bookmarkHolder.getBookmark()); - bookmarkHolder.setBookmark( InternalBookmark.empty() ); - assertEquals( bookmark1, bookmarkHolder.getBookmark() ); + bookmarkHolder.setBookmark(InternalBookmark.empty()); + assertEquals(bookmark1, bookmarkHolder.getBookmark()); - Bookmark bookmark2 = InternalBookmark.parse( "neo4j:bookmark:v1:tx2" ); - bookmarkHolder.setBookmark( bookmark2 ); - assertEquals( bookmark2, bookmarkHolder.getBookmark() ); + Bookmark bookmark2 = InternalBookmark.parse("neo4j:bookmark:v1:tx2"); + bookmarkHolder.setBookmark(bookmark2); + assertEquals(bookmark2, bookmarkHolder.getBookmark()); - Bookmark bookmark3 = InternalBookmark.parse( "neo4j:bookmark:v1:tx42" ); - bookmarkHolder.setBookmark( bookmark3 ); - assertEquals( bookmark3, bookmarkHolder.getBookmark() ); + Bookmark bookmark3 = InternalBookmark.parse("neo4j:bookmark:v1:tx42"); + bookmarkHolder.setBookmark(bookmark3); + assertEquals(bookmark3, bookmarkHolder.getBookmark()); } @Test - void bookmarkCanBeSet() - { + void bookmarkCanBeSet() { BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx100" ); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx100"); - bookmarkHolder.setBookmark( bookmark ); + bookmarkHolder.setBookmark(bookmark); - assertEquals( bookmark, bookmarkHolder.getBookmark() ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); } @Test - void shouldNotOverwriteBookmarkWithNull() - { - Bookmark initBookmark = InternalBookmark.parse( "Cat" ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( initBookmark ); - assertEquals( initBookmark, bookmarkHolder.getBookmark() ); - bookmarkHolder.setBookmark( null ); - assertEquals( initBookmark, bookmarkHolder.getBookmark() ); + void shouldNotOverwriteBookmarkWithNull() { + Bookmark initBookmark = InternalBookmark.parse("Cat"); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(initBookmark); + assertEquals(initBookmark, bookmarkHolder.getBookmark()); + bookmarkHolder.setBookmark(null); + assertEquals(initBookmark, bookmarkHolder.getBookmark()); } @Test - void shouldNotOverwriteBookmarkWithEmptyBookmark() - { - Bookmark initBookmark = InternalBookmark.parse( "Cat" ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( initBookmark ); - assertEquals( initBookmark, bookmarkHolder.getBookmark() ); - bookmarkHolder.setBookmark( InternalBookmark.empty() ); - assertEquals( initBookmark, bookmarkHolder.getBookmark() ); + void shouldNotOverwriteBookmarkWithEmptyBookmark() { + Bookmark initBookmark = InternalBookmark.parse("Cat"); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(initBookmark); + assertEquals(initBookmark, bookmarkHolder.getBookmark()); + bookmarkHolder.setBookmark(InternalBookmark.empty()); + assertEquals(initBookmark, bookmarkHolder.getBookmark()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/DirectConnectionProviderTest.java b/driver/src/test/java/org/neo4j/driver/internal/DirectConnectionProviderTest.java index b746554e42..3c36e8e189 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DirectConnectionProviderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DirectConnectionProviderTest.java @@ -18,21 +18,6 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.ValueSource; -import org.mockito.InOrder; - -import java.util.concurrent.CompletableFuture; -import java.util.stream.Stream; - -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.internal.async.ConnectionContext; -import org.neo4j.driver.internal.async.connection.DirectConnection; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionPool; - import static java.util.concurrent.CompletableFuture.completedFuture; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.junit.MatcherAssert.assertThat; @@ -49,123 +34,128 @@ import static org.neo4j.driver.internal.cluster.RediscoveryUtil.contextWithMode; import static org.neo4j.driver.util.TestUtil.await; -class DirectConnectionProviderTest -{ +import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InOrder; +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.internal.async.ConnectionContext; +import org.neo4j.driver.internal.async.connection.DirectConnection; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionPool; + +class DirectConnectionProviderTest { @Test - void acquiresConnectionsFromThePool() - { + void acquiresConnectionsFromThePool() { BoltServerAddress address = BoltServerAddress.LOCAL_DEFAULT; - Connection connection1 = mock( Connection.class ); - Connection connection2 = mock( Connection.class ); + Connection connection1 = mock(Connection.class); + Connection connection2 = mock(Connection.class); - ConnectionPool pool = poolMock( address, connection1, connection2 ); - DirectConnectionProvider provider = new DirectConnectionProvider( address, pool ); + ConnectionPool pool = poolMock(address, connection1, connection2); + DirectConnectionProvider provider = new DirectConnectionProvider(address, pool); - Connection acquired1 = await( provider.acquireConnection( contextWithMode( READ ) ) ); - assertThat( acquired1, instanceOf( DirectConnection.class ) ); - assertSame( connection1, ((DirectConnection) acquired1).connection() ); + Connection acquired1 = await(provider.acquireConnection(contextWithMode(READ))); + assertThat(acquired1, instanceOf(DirectConnection.class)); + assertSame(connection1, ((DirectConnection) acquired1).connection()); - Connection acquired2 = await( provider.acquireConnection( contextWithMode( WRITE ) ) ); - assertThat( acquired2, instanceOf( DirectConnection.class ) ); - assertSame( connection2, ((DirectConnection) acquired2).connection() ); + Connection acquired2 = await(provider.acquireConnection(contextWithMode(WRITE))); + assertThat(acquired2, instanceOf(DirectConnection.class)); + assertSame(connection2, ((DirectConnection) acquired2).connection()); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void returnsCorrectAccessMode( AccessMode mode ) - { + @EnumSource(AccessMode.class) + void returnsCorrectAccessMode(AccessMode mode) { BoltServerAddress address = BoltServerAddress.LOCAL_DEFAULT; - ConnectionPool pool = poolMock( address, mock( Connection.class ) ); - DirectConnectionProvider provider = new DirectConnectionProvider( address, pool ); + ConnectionPool pool = poolMock(address, mock(Connection.class)); + DirectConnectionProvider provider = new DirectConnectionProvider(address, pool); - Connection acquired = await( provider.acquireConnection( contextWithMode( mode ) ) ); + Connection acquired = await(provider.acquireConnection(contextWithMode(mode))); - assertEquals( mode, acquired.mode() ); + assertEquals(mode, acquired.mode()); } @Test - void closesPool() - { + void closesPool() { BoltServerAddress address = BoltServerAddress.LOCAL_DEFAULT; - ConnectionPool pool = poolMock( address, mock( Connection.class ) ); - DirectConnectionProvider provider = new DirectConnectionProvider( address, pool ); + ConnectionPool pool = poolMock(address, mock(Connection.class)); + DirectConnectionProvider provider = new DirectConnectionProvider(address, pool); provider.close(); - verify( pool ).close(); + verify(pool).close(); } @Test - void returnsCorrectAddress() - { - BoltServerAddress address = new BoltServerAddress( "server-1", 25000 ); + void returnsCorrectAddress() { + BoltServerAddress address = new BoltServerAddress("server-1", 25000); - DirectConnectionProvider provider = new DirectConnectionProvider( address, mock( ConnectionPool.class ) ); + DirectConnectionProvider provider = new DirectConnectionProvider(address, mock(ConnectionPool.class)); - assertEquals( address, provider.getAddress() ); + assertEquals(address, provider.getAddress()); } @Test - void shouldIgnoreDatabaseNameAndAccessModeWhenObtainConnectionFromPool() throws Throwable - { + void shouldIgnoreDatabaseNameAndAccessModeWhenObtainConnectionFromPool() throws Throwable { BoltServerAddress address = BoltServerAddress.LOCAL_DEFAULT; - Connection connection = mock( Connection.class ); + Connection connection = mock(Connection.class); - ConnectionPool pool = poolMock( address, connection ); - DirectConnectionProvider provider = new DirectConnectionProvider( address, pool ); + ConnectionPool pool = poolMock(address, connection); + DirectConnectionProvider provider = new DirectConnectionProvider(address, pool); - Connection acquired1 = await( provider.acquireConnection( contextWithMode( READ ) ) ); - assertThat( acquired1, instanceOf( DirectConnection.class ) ); - assertSame( connection, ((DirectConnection) acquired1).connection() ); + Connection acquired1 = await(provider.acquireConnection(contextWithMode(READ))); + assertThat(acquired1, instanceOf(DirectConnection.class)); + assertSame(connection, ((DirectConnection) acquired1).connection()); - verify( pool ).acquire( address ); + verify(pool).acquire(address); } - @ParameterizedTest - @ValueSource( strings = {"", "foo", "data"} ) - void shouldObtainDatabaseNameOnConnection( String databaseName ) throws Throwable - { + @ValueSource(strings = {"", "foo", "data"}) + void shouldObtainDatabaseNameOnConnection(String databaseName) throws Throwable { BoltServerAddress address = BoltServerAddress.LOCAL_DEFAULT; - ConnectionPool pool = poolMock( address, mock( Connection.class ) ); - DirectConnectionProvider provider = new DirectConnectionProvider( address, pool ); + ConnectionPool pool = poolMock(address, mock(Connection.class)); + DirectConnectionProvider provider = new DirectConnectionProvider(address, pool); - Connection acquired = await( provider.acquireConnection( contextWithDatabase( databaseName ) ) ); + Connection acquired = await(provider.acquireConnection(contextWithDatabase(databaseName))); - assertEquals( databaseName, acquired.databaseName().description() ); + assertEquals(databaseName, acquired.databaseName().description()); } @ParameterizedTest - @ValueSource( booleans = {true, false} ) - void ensuresCompletedDatabaseNameBeforeAccessingValue( boolean completed ) - { + @ValueSource(booleans = {true, false}) + void ensuresCompletedDatabaseNameBeforeAccessingValue(boolean completed) { BoltServerAddress address = BoltServerAddress.LOCAL_DEFAULT; - ConnectionPool pool = poolMock( address, mock( Connection.class ) ); - DirectConnectionProvider provider = new DirectConnectionProvider( address, pool ); - ConnectionContext context = mock( ConnectionContext.class ); - CompletableFuture databaseNameFuture = - spy( completed ? CompletableFuture.completedFuture( DatabaseNameUtil.systemDatabase() ) : new CompletableFuture<>() ); - when( context.databaseNameFuture() ).thenReturn( databaseNameFuture ); - when( context.mode() ).thenReturn( WRITE ); - - await( provider.acquireConnection( context ) ); - - InOrder inOrder = inOrder( context, databaseNameFuture ); - inOrder.verify( context ).databaseNameFuture(); - inOrder.verify( databaseNameFuture ).complete( DatabaseNameUtil.defaultDatabase() ); - inOrder.verify( databaseNameFuture ).isDone(); - inOrder.verify( databaseNameFuture ).join(); + ConnectionPool pool = poolMock(address, mock(Connection.class)); + DirectConnectionProvider provider = new DirectConnectionProvider(address, pool); + ConnectionContext context = mock(ConnectionContext.class); + CompletableFuture databaseNameFuture = spy( + completed + ? CompletableFuture.completedFuture(DatabaseNameUtil.systemDatabase()) + : new CompletableFuture<>()); + when(context.databaseNameFuture()).thenReturn(databaseNameFuture); + when(context.mode()).thenReturn(WRITE); + + await(provider.acquireConnection(context)); + + InOrder inOrder = inOrder(context, databaseNameFuture); + inOrder.verify(context).databaseNameFuture(); + inOrder.verify(databaseNameFuture).complete(DatabaseNameUtil.defaultDatabase()); + inOrder.verify(databaseNameFuture).isDone(); + inOrder.verify(databaseNameFuture).join(); } - @SuppressWarnings( "unchecked" ) - private static ConnectionPool poolMock( BoltServerAddress address, Connection connection, - Connection... otherConnections ) - { - ConnectionPool pool = mock( ConnectionPool.class ); - CompletableFuture[] otherConnectionFutures = Stream.of( otherConnections ) - .map( CompletableFuture::completedFuture ) - .toArray( CompletableFuture[]::new ); - when( pool.acquire( address ) ).thenReturn( completedFuture( connection ), otherConnectionFutures ); + @SuppressWarnings("unchecked") + private static ConnectionPool poolMock( + BoltServerAddress address, Connection connection, Connection... otherConnections) { + ConnectionPool pool = mock(ConnectionPool.class); + CompletableFuture[] otherConnectionFutures = Stream.of(otherConnections) + .map(CompletableFuture::completedFuture) + .toArray(CompletableFuture[]::new); + when(pool.acquire(address)).thenReturn(completedFuture(connection), otherConnectionFutures); return pool; } } 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 9f4c77c002..145a2b36d6 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java @@ -18,17 +18,33 @@ */ package org.neo4j.driver.internal; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Config.defaultConfig; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; +import static org.neo4j.driver.internal.util.Matchers.clusterDriver; +import static org.neo4j.driver.internal.util.Matchers.directDriver; + import io.netty.bootstrap.Bootstrap; import io.netty.util.concurrent.EventExecutorGroup; +import java.net.URI; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; - -import java.net.URI; -import java.util.Optional; -import java.util.stream.Stream; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; @@ -55,274 +71,264 @@ import org.neo4j.driver.internal.spi.ConnectionProvider; import org.neo4j.driver.internal.util.Clock; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Config.defaultConfig; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; -import static org.neo4j.driver.internal.util.Matchers.clusterDriver; -import static org.neo4j.driver.internal.util.Matchers.directDriver; - -class DriverFactoryTest -{ - private static Stream testUris() - { - return Stream.of( "bolt://localhost:7687", "neo4j://localhost:7687" ); +class DriverFactoryTest { + private static Stream testUris() { + return Stream.of("bolt://localhost:7687", "neo4j://localhost:7687"); } @ParameterizedTest - @MethodSource( "testUris" ) - void connectionPoolClosedWhenDriverCreationFails( String uri ) - { + @MethodSource("testUris") + void connectionPoolClosedWhenDriverCreationFails(String uri) { ConnectionPool connectionPool = connectionPoolMock(); - DriverFactory factory = new ThrowingDriverFactory( connectionPool ); + DriverFactory factory = new ThrowingDriverFactory(connectionPool); - assertThrows( UnsupportedOperationException.class, () -> createDriver( uri, factory ) ); - verify( connectionPool ).close(); + assertThrows(UnsupportedOperationException.class, () -> createDriver(uri, factory)); + verify(connectionPool).close(); } @ParameterizedTest - @MethodSource( "testUris" ) - void connectionPoolCloseExceptionIsSuppressedWhenDriverCreationFails( String uri ) - { + @MethodSource("testUris") + void connectionPoolCloseExceptionIsSuppressedWhenDriverCreationFails(String uri) { ConnectionPool connectionPool = connectionPoolMock(); - RuntimeException poolCloseError = new RuntimeException( "Pool close error" ); - when( connectionPool.close() ).thenReturn( failedFuture( poolCloseError ) ); + RuntimeException poolCloseError = new RuntimeException("Pool close error"); + when(connectionPool.close()).thenReturn(failedFuture(poolCloseError)); - DriverFactory factory = new ThrowingDriverFactory( connectionPool ); + DriverFactory factory = new ThrowingDriverFactory(connectionPool); - UnsupportedOperationException e = assertThrows( UnsupportedOperationException.class, () -> createDriver( uri, factory ) ); - assertArrayEquals( new Throwable[]{poolCloseError}, e.getSuppressed() ); - verify( connectionPool ).close(); + UnsupportedOperationException e = + assertThrows(UnsupportedOperationException.class, () -> createDriver(uri, factory)); + assertArrayEquals(new Throwable[] {poolCloseError}, e.getSuppressed()); + verify(connectionPool).close(); } @ParameterizedTest - @MethodSource( "testUris" ) - void usesStandardSessionFactoryWhenNothingConfigured( String uri ) - { + @MethodSource("testUris") + void usesStandardSessionFactoryWhenNothingConfigured(String uri) { Config config = defaultConfig(); SessionFactoryCapturingDriverFactory factory = new SessionFactoryCapturingDriverFactory(); - createDriver( uri, factory, config ); + createDriver(uri, factory, config); SessionFactory capturedFactory = factory.capturedSessionFactory; - assertThat( capturedFactory.newInstance( SessionConfig.defaultConfig() ), instanceOf( NetworkSession.class ) ); + assertThat(capturedFactory.newInstance(SessionConfig.defaultConfig()), instanceOf(NetworkSession.class)); } @ParameterizedTest - @MethodSource( "testUris" ) - void usesLeakLoggingSessionFactoryWhenConfigured( String uri ) - { + @MethodSource("testUris") + void usesLeakLoggingSessionFactoryWhenConfigured(String uri) { Config config = Config.builder().withLeakedSessionsLogging().build(); SessionFactoryCapturingDriverFactory factory = new SessionFactoryCapturingDriverFactory(); - createDriver( uri, factory, config ); + createDriver(uri, factory, config); SessionFactory capturedFactory = factory.capturedSessionFactory; - assertThat( capturedFactory.newInstance( SessionConfig.defaultConfig() ), instanceOf( LeakLoggingNetworkSession.class ) ); + assertThat( + capturedFactory.newInstance(SessionConfig.defaultConfig()), + instanceOf(LeakLoggingNetworkSession.class)); } @ParameterizedTest - @MethodSource( "testUris" ) - void shouldNotVerifyConnectivity( String uri ) - { - SessionFactory sessionFactory = mock( SessionFactory.class ); - when( sessionFactory.verifyConnectivity() ).thenReturn( completedWithNull() ); - when( sessionFactory.close() ).thenReturn( completedWithNull() ); - DriverFactoryWithSessions driverFactory = new DriverFactoryWithSessions( sessionFactory ); - - try ( Driver driver = createDriver( uri, driverFactory ) ) - { - assertNotNull( driver ); - verify( sessionFactory, never() ).verifyConnectivity(); + @MethodSource("testUris") + void shouldNotVerifyConnectivity(String uri) { + SessionFactory sessionFactory = mock(SessionFactory.class); + when(sessionFactory.verifyConnectivity()).thenReturn(completedWithNull()); + when(sessionFactory.close()).thenReturn(completedWithNull()); + DriverFactoryWithSessions driverFactory = new DriverFactoryWithSessions(sessionFactory); + + try (Driver driver = createDriver(uri, driverFactory)) { + assertNotNull(driver); + verify(sessionFactory, never()).verifyConnectivity(); } } @Test - void shouldNotCreateDriverMetrics() - { + void shouldNotCreateDriverMetrics() { // Given - Config config = mock( Config.class ); - when( config.isMetricsEnabled() ).thenReturn( false ); + Config config = mock(Config.class); + when(config.isMetricsEnabled()).thenReturn(false); // When - MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider( config, Clock.SYSTEM ); + MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.SYSTEM); // Then - assertThat( provider, is(equalTo( DevNullMetricsProvider.INSTANCE ) ) ); + assertThat(provider, is(equalTo(DevNullMetricsProvider.INSTANCE))); } @Test - void shouldCreateDriverMetricsIfMonitoringEnabled() - { + void shouldCreateDriverMetricsIfMonitoringEnabled() { // Given - Config config = mock( Config.class ); - when( config.isMetricsEnabled() ).thenReturn( true ); - when( config.logging() ).thenReturn( Logging.none() ); + Config config = mock(Config.class); + when(config.isMetricsEnabled()).thenReturn(true); + when(config.logging()).thenReturn(Logging.none()); // When - MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider( config, Clock.SYSTEM ); + MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.SYSTEM); // Then - assertThat( provider instanceof InternalMetricsProvider, is( true ) ); + assertThat(provider instanceof InternalMetricsProvider, is(true)); } @Test - void shouldCreateMicrometerDriverMetricsIfMonitoringEnabled() - { + void shouldCreateMicrometerDriverMetricsIfMonitoringEnabled() { // Given - Config config = mock( Config.class ); - when( config.isMetricsEnabled() ).thenReturn( true ); - when( config.metricsAdapter() ).thenReturn( MetricsAdapter.MICROMETER ); - when( config.logging() ).thenReturn( Logging.none() ); + Config config = mock(Config.class); + when(config.isMetricsEnabled()).thenReturn(true); + when(config.metricsAdapter()).thenReturn(MetricsAdapter.MICROMETER); + when(config.logging()).thenReturn(Logging.none()); // When - MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider( config, Clock.SYSTEM ); + MetricsProvider provider = DriverFactory.getOrCreateMetricsProvider(config, Clock.SYSTEM); // Then - assertThat( provider instanceof MicrometerMetricsProvider, is( true ) ); + assertThat(provider instanceof MicrometerMetricsProvider, is(true)); } @ParameterizedTest - @MethodSource( "testUris" ) - void shouldCreateAppropriateDriverType( String uri ) - { + @MethodSource("testUris") + void shouldCreateAppropriateDriverType(String uri) { DriverFactory driverFactory = new DriverFactory(); - Driver driver = createDriver( uri, driverFactory ); - - if ( uri.startsWith( "bolt://" ) ) - { - assertThat( driver, is( directDriver() ) ); - } - else if ( uri.startsWith( "neo4j://" ) ) - { - assertThat( driver, is( clusterDriver() ) ); - } - else - { - fail( "Unexpected scheme provided in argument" ); + Driver driver = createDriver(uri, driverFactory); + + if (uri.startsWith("bolt://")) { + assertThat(driver, is(directDriver())); + } else if (uri.startsWith("neo4j://")) { + assertThat(driver, is(clusterDriver())); + } else { + fail("Unexpected scheme provided in argument"); } } - private Driver createDriver( String uri, DriverFactory driverFactory ) - { - return createDriver( uri, driverFactory, defaultConfig() ); + private Driver createDriver(String uri, DriverFactory driverFactory) { + return createDriver(uri, driverFactory, defaultConfig()); } - private Driver createDriver( String uri, DriverFactory driverFactory, Config config ) - { + private Driver createDriver(String uri, DriverFactory driverFactory, Config config) { AuthToken auth = AuthTokens.none(); - return driverFactory.newInstance( URI.create( uri ), auth, RoutingSettings.DEFAULT, RetrySettings.DEFAULT, config, SecurityPlanImpl.insecure() ); + return driverFactory.newInstance( + URI.create(uri), + auth, + RoutingSettings.DEFAULT, + RetrySettings.DEFAULT, + config, + SecurityPlanImpl.insecure()); } - private static ConnectionPool connectionPoolMock() - { - ConnectionPool pool = mock( ConnectionPool.class ); - Connection connection = mock( Connection.class ); - when( pool.acquire( any( BoltServerAddress.class ) ) ).thenReturn( completedFuture( connection ) ); - when( pool.close() ).thenReturn( completedWithNull() ); + private static ConnectionPool connectionPoolMock() { + ConnectionPool pool = mock(ConnectionPool.class); + Connection connection = mock(Connection.class); + when(pool.acquire(any(BoltServerAddress.class))).thenReturn(completedFuture(connection)); + when(pool.close()).thenReturn(completedWithNull()); return pool; } - private static class ThrowingDriverFactory extends DriverFactory - { + private static class ThrowingDriverFactory extends DriverFactory { final ConnectionPool connectionPool; - ThrowingDriverFactory( ConnectionPool connectionPool ) - { + ThrowingDriverFactory(ConnectionPool connectionPool) { this.connectionPool = connectionPool; } @Override - protected InternalDriver createDriver( SecurityPlan securityPlan, SessionFactory sessionFactory, MetricsProvider metricsProvider, Config config ) - { - throw new UnsupportedOperationException( "Can't create direct driver" ); + protected InternalDriver createDriver( + SecurityPlan securityPlan, + SessionFactory sessionFactory, + MetricsProvider metricsProvider, + Config config) { + throw new UnsupportedOperationException("Can't create direct driver"); } @Override - protected InternalDriver createRoutingDriver( SecurityPlan securityPlan, BoltServerAddress address, ConnectionPool connectionPool, - EventExecutorGroup eventExecutorGroup, RoutingSettings routingSettings, RetryLogic retryLogic, MetricsProvider metricsProvider, Config config ) - { - throw new UnsupportedOperationException( "Can't create routing driver" ); + protected InternalDriver createRoutingDriver( + SecurityPlan securityPlan, + BoltServerAddress address, + ConnectionPool connectionPool, + EventExecutorGroup eventExecutorGroup, + RoutingSettings routingSettings, + RetryLogic retryLogic, + MetricsProvider metricsProvider, + Config config) { + throw new UnsupportedOperationException("Can't create routing driver"); } @Override - protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, - MetricsProvider metricsProvider, Config config, boolean ownsEventLoopGroup, - RoutingContext routingContext ) - { + protected ConnectionPool createConnectionPool( + AuthToken authToken, + SecurityPlan securityPlan, + Bootstrap bootstrap, + MetricsProvider metricsProvider, + Config config, + boolean ownsEventLoopGroup, + RoutingContext routingContext) { return connectionPool; } } - private static class SessionFactoryCapturingDriverFactory extends DriverFactory - { + private static class SessionFactoryCapturingDriverFactory extends DriverFactory { SessionFactory capturedSessionFactory; @Override - protected InternalDriver createDriver( SecurityPlan securityPlan, SessionFactory sessionFactory, MetricsProvider metricsProvider, Config config ) - { - InternalDriver driver = mock( InternalDriver.class ); - when( driver.verifyConnectivityAsync() ).thenReturn( completedWithNull() ); + protected InternalDriver createDriver( + SecurityPlan securityPlan, + SessionFactory sessionFactory, + MetricsProvider metricsProvider, + Config config) { + InternalDriver driver = mock(InternalDriver.class); + when(driver.verifyConnectivityAsync()).thenReturn(completedWithNull()); return driver; } @Override - protected LoadBalancer createLoadBalancer( BoltServerAddress address, ConnectionPool connectionPool, - EventExecutorGroup eventExecutorGroup, Config config, RoutingSettings routingSettings ) - { + protected LoadBalancer createLoadBalancer( + BoltServerAddress address, + ConnectionPool connectionPool, + EventExecutorGroup eventExecutorGroup, + Config config, + RoutingSettings routingSettings) { return null; } @Override - protected SessionFactory createSessionFactory( ConnectionProvider connectionProvider, - RetryLogic retryLogic, Config config ) - { - SessionFactory sessionFactory = super.createSessionFactory( connectionProvider, retryLogic, config ); + protected SessionFactory createSessionFactory( + ConnectionProvider connectionProvider, RetryLogic retryLogic, Config config) { + SessionFactory sessionFactory = super.createSessionFactory(connectionProvider, retryLogic, config); capturedSessionFactory = sessionFactory; return sessionFactory; } @Override - protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, - MetricsProvider metricsProvider, Config config, boolean ownsEventLoopGroup, RoutingContext routingContext ) - { + protected ConnectionPool createConnectionPool( + AuthToken authToken, + SecurityPlan securityPlan, + Bootstrap bootstrap, + MetricsProvider metricsProvider, + Config config, + boolean ownsEventLoopGroup, + RoutingContext routingContext) { return connectionPoolMock(); } } - private static class DriverFactoryWithSessions extends DriverFactory - { + private static class DriverFactoryWithSessions extends DriverFactory { final SessionFactory sessionFactory; - DriverFactoryWithSessions( SessionFactory sessionFactory ) - { + DriverFactoryWithSessions(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override - protected Bootstrap createBootstrap( int ignored ) - { - return BootstrapFactory.newBootstrap( 1 ); + protected Bootstrap createBootstrap(int ignored) { + return BootstrapFactory.newBootstrap(1); } @Override - protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, - MetricsProvider metricsProvider, Config config, boolean ownsEventLoopGroup, RoutingContext routingContext ) - { + protected ConnectionPool createConnectionPool( + AuthToken authToken, + SecurityPlan securityPlan, + Bootstrap bootstrap, + MetricsProvider metricsProvider, + Config config, + boolean ownsEventLoopGroup, + RoutingContext routingContext) { return connectionPoolMock(); } @Override - protected SessionFactory createSessionFactory( ConnectionProvider connectionProvider, RetryLogic retryLogic, - Config config ) - { + protected SessionFactory createSessionFactory( + ConnectionProvider connectionProvider, RetryLogic retryLogic, Config config) { return sessionFactory; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/ExtractTest.java b/driver/src/test/java/org/neo4j/driver/internal/ExtractTest.java index 6f64c1fb0a..aa21f8ebcd 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/ExtractTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/ExtractTest.java @@ -18,23 +18,6 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; - -import java.time.LocalDate; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.neo4j.driver.internal.util.Extract; -import org.neo4j.driver.internal.util.Iterables; -import org.neo4j.driver.Value; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.util.Pair; - import static java.util.Arrays.asList; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; @@ -49,139 +32,143 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.neo4j.driver.Values.value; -class ExtractTest -{ +import java.time.LocalDate; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.internal.util.Extract; +import org.neo4j.driver.internal.util.Iterables; +import org.neo4j.driver.util.Pair; + +class ExtractTest { @Test - void extractEmptyArrayShouldNotBeModifiable() - { - List list = Extract.list( new Value[]{} ); + void extractEmptyArrayShouldNotBeModifiable() { + List list = Extract.list(new Value[] {}); - assertThat( list, empty() ); - assertThrows( UnsupportedOperationException.class, () -> list.add( null ) ); + assertThat(list, empty()); + assertThrows(UnsupportedOperationException.class, () -> list.add(null)); } @Test - void extractSingletonShouldNotBeModifiable() - { - List list = Extract.list( new Value[]{value( 42 )} ); + void extractSingletonShouldNotBeModifiable() { + List list = Extract.list(new Value[] {value(42)}); - assertThat( list, equalTo( singletonList( value( 42 ) ) ) ); - assertThrows( UnsupportedOperationException.class, () -> list.add( null ) ); + assertThat(list, equalTo(singletonList(value(42)))); + assertThrows(UnsupportedOperationException.class, () -> list.add(null)); } @Test - void extractMultipleShouldNotBeModifiable() - { - List list = Extract.list( new Value[]{value( 42 ), value( 43 )} ); + void extractMultipleShouldNotBeModifiable() { + List list = Extract.list(new Value[] {value(42), value(43)}); - assertThat( list, equalTo( asList( value( 42 ), value( 43 ) ) ) ); - assertThrows( UnsupportedOperationException.class, () -> list.add( null ) ); + assertThat(list, equalTo(asList(value(42), value(43)))); + assertThrows(UnsupportedOperationException.class, () -> list.add(null)); } @Test - void testMapOverList() - { - List mapped = Extract.list( new Value[]{value( 42 ), value( 43 )}, Value::asInt ); + void testMapOverList() { + List mapped = Extract.list(new Value[] {value(42), value(43)}, Value::asInt); - assertThat( mapped, equalTo( Arrays.asList( 42, 43 ) ) ); + assertThat(mapped, equalTo(Arrays.asList(42, 43))); } @Test - void testMapValues() - { + void testMapValues() { // GIVEN - Map map = new HashMap<>(); - map.put( "k1", value( 43 ) ); - map.put( "k2", value( 42 ) ); + Map map = new HashMap<>(); + map.put("k1", value(43)); + map.put("k2", value(42)); // WHEN - Map mappedMap = Extract.map( map, Value::asInt ); + Map mappedMap = Extract.map(map, Value::asInt); // THEN Collection values = mappedMap.values(); - assertThat( values, containsInAnyOrder( 43, 42 ) ); - + assertThat(values, containsInAnyOrder(43, 42)); } @Test - void testShouldPreserveMapOrderMapValues() - { + void testShouldPreserveMapOrderMapValues() { // GIVEN - Map map = Iterables.newLinkedHashMapWithSize( 2 ); - map.put( "k2", value( 43 ) ); - map.put( "k1", value( 42 ) ); + Map map = Iterables.newLinkedHashMapWithSize(2); + map.put("k2", value(43)); + map.put("k1", value(42)); // WHEN - Map mappedMap = Extract.map( map, Value::asInt ); + Map mappedMap = Extract.map(map, Value::asInt); // THEN Collection values = mappedMap.values(); - assertThat( values, contains( 43, 42) ); - + assertThat(values, contains(43, 42)); } @Test - void testProperties() - { + void testProperties() { // GIVEN - Map props = new HashMap<>(); - props.put( "k1", value( 43 ) ); - props.put( "k2", value( 42 ) ); - InternalNode node = new InternalNode( 42L, Collections.singletonList( "L" ), props ); + Map props = new HashMap<>(); + props.put("k1", value(43)); + props.put("k2", value(42)); + InternalNode node = new InternalNode(42L, Collections.singletonList("L"), props); // WHEN - Iterable> properties = Extract.properties( node, Value::asInt ); + Iterable> properties = Extract.properties(node, Value::asInt); // THEN Iterator> iterator = properties.iterator(); - assertThat( iterator.next(), equalTo( InternalPair.of( "k1", 43 ) ) ); - assertThat( iterator.next(), equalTo( InternalPair.of( "k2", 42 ) ) ); - assertFalse( iterator.hasNext() ); + assertThat(iterator.next(), equalTo(InternalPair.of("k1", 43))); + assertThat(iterator.next(), equalTo(InternalPair.of("k2", 42))); + assertFalse(iterator.hasNext()); } @Test - void testFields() - { + void testFields() { // GIVEN - InternalRecord record = new InternalRecord( Arrays.asList( "k1" ), new Value[]{value( 42 )} ); + InternalRecord record = new InternalRecord(Arrays.asList("k1"), new Value[] {value(42)}); // WHEN - List> fields = Extract.fields( record, Value::asInt ); - + List> fields = Extract.fields(record, Value::asInt); // THEN - assertThat( fields, equalTo( Collections.singletonList( InternalPair.of( "k1", 42 ) ) ) ); + assertThat(fields, equalTo(Collections.singletonList(InternalPair.of("k1", 42)))); } @Test - void shouldExtractMapOfValuesFromNullOrEmptyMap() - { - assertEquals( emptyMap(), Extract.mapOfValues( null ) ); - assertEquals( emptyMap(), Extract.mapOfValues( emptyMap() ) ); + void shouldExtractMapOfValuesFromNullOrEmptyMap() { + assertEquals(emptyMap(), Extract.mapOfValues(null)); + assertEquals(emptyMap(), Extract.mapOfValues(emptyMap())); } @Test - void shouldExtractMapOfValues() - { - Map map = new HashMap<>(); - map.put( "key1", "value1" ); - map.put( "key2", 42L ); - map.put( "key3", LocalDate.now() ); - map.put( "key4", new byte[]{1, 2, 3} ); - - Map mapOfValues = Extract.mapOfValues( map ); - - assertEquals( 4, map.size() ); - assertEquals( value( "value1" ), mapOfValues.get( "key1" ) ); - assertEquals( value( 42L ), mapOfValues.get( "key2" ) ); - assertEquals( value( LocalDate.now() ), mapOfValues.get( "key3" ) ); - assertEquals( value( new byte[]{1, 2, 3} ), mapOfValues.get( "key4" ) ); + void shouldExtractMapOfValues() { + Map map = new HashMap<>(); + map.put("key1", "value1"); + map.put("key2", 42L); + map.put("key3", LocalDate.now()); + map.put("key4", new byte[] {1, 2, 3}); + + Map mapOfValues = Extract.mapOfValues(map); + + assertEquals(4, map.size()); + assertEquals(value("value1"), mapOfValues.get("key1")); + assertEquals(value(42L), mapOfValues.get("key2")); + assertEquals(value(LocalDate.now()), mapOfValues.get("key3")); + assertEquals(value(new byte[] {1, 2, 3}), mapOfValues.get("key4")); } @Test - void shouldFailToExtractMapOfValuesFromUnsupportedValues() - { - assertThrows( ClientException.class, () -> Extract.mapOfValues( singletonMap( "key", new InternalNode( 1 ) ) ) ); - assertThrows( ClientException.class, () -> Extract.mapOfValues( singletonMap( "key", new InternalRelationship( 1, 1, 1, "HI" ) ) ) ); - assertThrows( ClientException.class, () -> Extract.mapOfValues( singletonMap( "key", new InternalPath( new InternalNode( 1 ) ) ) ) ); + void shouldFailToExtractMapOfValuesFromUnsupportedValues() { + assertThrows(ClientException.class, () -> Extract.mapOfValues(singletonMap("key", new InternalNode(1)))); + assertThrows( + ClientException.class, + () -> Extract.mapOfValues(singletonMap("key", new InternalRelationship(1, 1, 1, "HI")))); + assertThrows( + ClientException.class, + () -> Extract.mapOfValues(singletonMap("key", new InternalPath(new InternalNode(1))))); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalBookmarkTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalBookmarkTest.java index 7c217b204b..c533e1df48 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalBookmarkTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalBookmarkTest.java @@ -18,13 +18,6 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Set; - -import org.neo4j.driver.Bookmark; - import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; import static java.util.Collections.singleton; @@ -40,133 +33,123 @@ import static org.neo4j.driver.internal.InternalBookmark.parse; import static org.neo4j.driver.util.TestUtil.asSet; -class InternalBookmarkTest -{ +import java.util.Arrays; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Bookmark; + +class InternalBookmarkTest { @Test - void isEmptyForEmptyBookmark() - { + void isEmptyForEmptyBookmark() { Bookmark bookmark = InternalBookmark.empty(); - assertTrue( bookmark.isEmpty() ); - assertEquals( emptySet(), bookmark.values() ); + assertTrue(bookmark.isEmpty()); + assertEquals(emptySet(), bookmark.values()); } @Test - void shouldSetToEmptyForNullBookmark() throws Throwable - { - Bookmark bookmark = InternalBookmark.from( null ); - assertEquals( InternalBookmark.empty(), bookmark ); + void shouldSetToEmptyForNullBookmark() throws Throwable { + Bookmark bookmark = InternalBookmark.from(null); + assertEquals(InternalBookmark.empty(), bookmark); } @Test - void shouldSetToEmptyForEmptyBookmarkIterator() throws Throwable - { - Bookmark bookmark = InternalBookmark.from( emptyList() ); - assertEquals( InternalBookmark.empty(), bookmark ); + void shouldSetToEmptyForEmptyBookmarkIterator() throws Throwable { + Bookmark bookmark = InternalBookmark.from(emptyList()); + assertEquals(InternalBookmark.empty(), bookmark); } @Test - void shouldSetToEmptyForNullBookmarkList() throws Throwable - { - Bookmark bookmark = InternalBookmark.from( singletonList( null ) ); - assertEquals( InternalBookmark.empty(), bookmark ); + void shouldSetToEmptyForNullBookmarkList() throws Throwable { + Bookmark bookmark = InternalBookmark.from(singletonList(null)); + assertEquals(InternalBookmark.empty(), bookmark); } @Test - void shouldIgnoreNullAndEmptyInBookmarkList() throws Throwable - { - Bookmark bookmark = InternalBookmark.from( Arrays.asList( InternalBookmark.empty(), null, null ) ); - assertEquals( InternalBookmark.empty(), bookmark ); + void shouldIgnoreNullAndEmptyInBookmarkList() throws Throwable { + Bookmark bookmark = InternalBookmark.from(Arrays.asList(InternalBookmark.empty(), null, null)); + assertEquals(InternalBookmark.empty(), bookmark); } @Test - void shouldReserveBookmarkValuesCorrectly() throws Throwable - { - Bookmark one = parse( "one" ); - Bookmark two = parse( "two" ); + void shouldReserveBookmarkValuesCorrectly() throws Throwable { + Bookmark one = parse("one"); + Bookmark two = parse("two"); Bookmark empty = InternalBookmark.empty(); - Bookmark bookmark = InternalBookmark.from( Arrays.asList( one, two, null, empty ) ); - verifyValues( bookmark, "one", "two" ); + Bookmark bookmark = InternalBookmark.from(Arrays.asList(one, two, null, empty)); + verifyValues(bookmark, "one", "two"); } @Test - void isNotEmptyForNonEmptyBookmark() - { - Bookmark bookmark = InternalBookmark.parse( "SomeBookmark" ); - assertFalse( bookmark.isEmpty() ); + void isNotEmptyForNonEmptyBookmark() { + Bookmark bookmark = InternalBookmark.parse("SomeBookmark"); + assertFalse(bookmark.isEmpty()); } @Test - void asBeginTransactionParametersForNonEmptyBookmark() - { - Bookmark bookmark = InternalBookmark.parse( "SomeBookmark" ); - verifyValues( bookmark, "SomeBookmark" ); + void asBeginTransactionParametersForNonEmptyBookmark() { + Bookmark bookmark = InternalBookmark.parse("SomeBookmark"); + verifyValues(bookmark, "SomeBookmark"); } @Test - void bookmarkFromString() - { - Bookmark bookmark = InternalBookmark.parse( "Cat" ); - assertEquals( singleton( "Cat" ), bookmark.values() ); - verifyValues( bookmark, "Cat" ); + void bookmarkFromString() { + Bookmark bookmark = InternalBookmark.parse("Cat"); + assertEquals(singleton("Cat"), bookmark.values()); + verifyValues(bookmark, "Cat"); } @Test - void bookmarkFromNullString() - { - Bookmark bookmark = InternalBookmark.parse( (String) null ); - assertTrue( bookmark.isEmpty() ); + void bookmarkFromNullString() { + Bookmark bookmark = InternalBookmark.parse((String) null); + assertTrue(bookmark.isEmpty()); } @Test - void bookmarkFromSet() - { - Set input = asSet( "neo4j:bookmark:v1:tx42", "neo4j:bookmark:v1:tx10", "neo4j:bookmark:v1:tx12" ); - Bookmark bookmark = InternalBookmark.parse( input ); - verifyValues( bookmark, "neo4j:bookmark:v1:tx42", "neo4j:bookmark:v1:tx10", "neo4j:bookmark:v1:tx12" ); + void bookmarkFromSet() { + Set input = asSet("neo4j:bookmark:v1:tx42", "neo4j:bookmark:v1:tx10", "neo4j:bookmark:v1:tx12"); + Bookmark bookmark = InternalBookmark.parse(input); + verifyValues(bookmark, "neo4j:bookmark:v1:tx42", "neo4j:bookmark:v1:tx10", "neo4j:bookmark:v1:tx12"); } @Test - void bookmarkFromNullIterable() - { - Bookmark bookmark = InternalBookmark.parse( (Set) null ); - assertTrue( bookmark.isEmpty() ); + void bookmarkFromNullIterable() { + Bookmark bookmark = InternalBookmark.parse((Set) null); + assertTrue(bookmark.isEmpty()); } @Test - void bookmarkFromEmptyIterable() - { - Bookmark bookmark = InternalBookmark.parse( emptySet() ); - assertTrue( bookmark.isEmpty() ); + void bookmarkFromEmptyIterable() { + Bookmark bookmark = InternalBookmark.parse(emptySet()); + assertTrue(bookmark.isEmpty()); } @Test - void asBeginTransactionParametersForBookmarkWithInvalidValue() - { - Bookmark bookmark = InternalBookmark.parse( asSet( "neo4j:bookmark:v1:tx1", "neo4j:bookmark:v1:txcat", "neo4j:bookmark:v1:tx3" ) ); - verifyValues( bookmark, "neo4j:bookmark:v1:tx1", "neo4j:bookmark:v1:txcat", "neo4j:bookmark:v1:tx3" ); + void asBeginTransactionParametersForBookmarkWithInvalidValue() { + Bookmark bookmark = InternalBookmark.parse( + asSet("neo4j:bookmark:v1:tx1", "neo4j:bookmark:v1:txcat", "neo4j:bookmark:v1:tx3")); + verifyValues(bookmark, "neo4j:bookmark:v1:tx1", "neo4j:bookmark:v1:txcat", "neo4j:bookmark:v1:tx3"); } @Test - void shouldReturnAllBookmarks() - { - assertIterableEquals( emptyList(), InternalBookmark.empty().values() ); - assertIterableEquals( singleton( "neo4j:bookmark:v1:tx42" ), InternalBookmark.parse( "neo4j:bookmark:v1:tx42" ).values() ); + void shouldReturnAllBookmarks() { + assertIterableEquals(emptyList(), InternalBookmark.empty().values()); + assertIterableEquals( + singleton("neo4j:bookmark:v1:tx42"), + InternalBookmark.parse("neo4j:bookmark:v1:tx42").values()); - Set bookmarks = asSet( "neo4j:bookmark:v1:tx1", "neo4j:bookmark:v1:tx2", "neo4j:bookmark:v1:tx3" ); - assertIterableEquals( bookmarks, InternalBookmark.parse( bookmarks ).values() ); + Set bookmarks = asSet("neo4j:bookmark:v1:tx1", "neo4j:bookmark:v1:tx2", "neo4j:bookmark:v1:tx3"); + assertIterableEquals(bookmarks, InternalBookmark.parse(bookmarks).values()); } @Test - void valueShouldBeReadOnly() throws Throwable - { - Bookmark bookmark = InternalBookmark.parse( asSet( "first", "second" ) ); + void valueShouldBeReadOnly() throws Throwable { + Bookmark bookmark = InternalBookmark.parse(asSet("first", "second")); Set values = bookmark.values(); - assertThrows( UnsupportedOperationException.class, () -> values.add( "third" ) ); + assertThrows(UnsupportedOperationException.class, () -> values.add("third")); } - private static void verifyValues( Bookmark bookmark, String... expectedValues ) - { - assertThat( bookmark.values().size(), equalTo( expectedValues.length ) ); - assertThat( bookmark.values(), hasItems( expectedValues ) ); + private static void verifyValues(Bookmark bookmark, String... expectedValues) { + assertThat(bookmark.values().size(), equalTo(expectedValues.length)); + assertThat(bookmark.values(), hasItems(expectedValues)); } } 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 4893526544..7604191919 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java @@ -18,19 +18,6 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.CompletableFuture; - -import org.neo4j.driver.Config; -import org.neo4j.driver.Metrics; -import org.neo4j.driver.internal.metrics.DevNullMetricsProvider; -import org.neo4j.driver.internal.metrics.MetricsProvider; -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 static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -44,103 +31,105 @@ import static org.neo4j.driver.internal.util.Futures.failedFuture; import static org.neo4j.driver.util.TestUtil.await; -class InternalDriverTest -{ +import java.util.concurrent.CompletableFuture; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Config; +import org.neo4j.driver.Metrics; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.exceptions.ServiceUnavailableException; +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 - void shouldCloseSessionFactory() - { + void shouldCloseSessionFactory() { SessionFactory sessionFactory = sessionFactoryMock(); - InternalDriver driver = newDriver( sessionFactory ); + InternalDriver driver = newDriver(sessionFactory); - assertNull( await( driver.closeAsync() ) ); - verify( sessionFactory ).close(); + assertNull(await(driver.closeAsync())); + verify(sessionFactory).close(); } @Test - void shouldNotCloseSessionFactoryMultipleTimes() - { + void shouldNotCloseSessionFactoryMultipleTimes() { SessionFactory sessionFactory = sessionFactoryMock(); - InternalDriver driver = newDriver( sessionFactory ); + InternalDriver driver = newDriver(sessionFactory); - assertNull( await( driver.closeAsync() ) ); - assertNull( await( driver.closeAsync() ) ); - assertNull( await( driver.closeAsync() ) ); + assertNull(await(driver.closeAsync())); + assertNull(await(driver.closeAsync())); + assertNull(await(driver.closeAsync())); - verify( sessionFactory ).close(); + verify(sessionFactory).close(); } @Test - void shouldVerifyConnectivity() - { + void shouldVerifyConnectivity() { SessionFactory sessionFactory = sessionFactoryMock(); CompletableFuture connectivityStage = completedWithNull(); - when( sessionFactory.verifyConnectivity() ).thenReturn( connectivityStage ); + when(sessionFactory.verifyConnectivity()).thenReturn(connectivityStage); - InternalDriver driver = newDriver( sessionFactory ); + InternalDriver driver = newDriver(sessionFactory); - assertEquals( connectivityStage, driver.verifyConnectivityAsync() ); + assertEquals(connectivityStage, driver.verifyConnectivityAsync()); } @Test - void shouldThrowWhenUnableToVerifyConnectivity() - { - SessionFactory sessionFactory = mock( SessionFactory.class ); - ServiceUnavailableException error = new ServiceUnavailableException( "Hello" ); - when( sessionFactory.verifyConnectivity() ).thenReturn( failedFuture( error ) ); - InternalDriver driver = newDriver( sessionFactory ); - - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, () -> await( driver.verifyConnectivityAsync() ) ); - assertEquals( e.getMessage(), "Hello" ); + void shouldThrowWhenUnableToVerifyConnectivity() { + SessionFactory sessionFactory = mock(SessionFactory.class); + ServiceUnavailableException error = new ServiceUnavailableException("Hello"); + when(sessionFactory.verifyConnectivity()).thenReturn(failedFuture(error)); + InternalDriver driver = newDriver(sessionFactory); + + ServiceUnavailableException e = + assertThrows(ServiceUnavailableException.class, () -> await(driver.verifyConnectivityAsync())); + assertEquals(e.getMessage(), "Hello"); } @Test - void shouldThrowClientExceptionIfMetricsNotEnabled() throws Throwable - { + void shouldThrowClientExceptionIfMetricsNotEnabled() throws Throwable { // Given - InternalDriver driver = newDriver( false ); + InternalDriver driver = newDriver(false); // When - ClientException error = assertThrows( ClientException.class, driver::metrics ); + ClientException error = assertThrows(ClientException.class, driver::metrics); // Then - assertTrue( error.getMessage().contains( "Driver metrics are not enabled." ) ); + assertTrue(error.getMessage().contains("Driver metrics are not enabled.")); } @Test - void shouldReturnMetricsIfMetricsEnabled() - { + void shouldReturnMetricsIfMetricsEnabled() { // Given - InternalDriver driver = newDriver( true ); + InternalDriver driver = newDriver(true); // When Metrics metrics = driver.metrics(); // Then we shall have no problem to get the metrics - assertNotNull( metrics ); + assertNotNull(metrics); } - private static InternalDriver newDriver( SessionFactory sessionFactory ) - { - return new InternalDriver( SecurityPlanImpl.insecure(), sessionFactory, DevNullMetricsProvider.INSTANCE, DEV_NULL_LOGGING ); + private static InternalDriver newDriver(SessionFactory sessionFactory) { + return new InternalDriver( + SecurityPlanImpl.insecure(), sessionFactory, DevNullMetricsProvider.INSTANCE, DEV_NULL_LOGGING); } - private static SessionFactory sessionFactoryMock() - { - SessionFactory sessionFactory = mock( SessionFactory.class ); - when( sessionFactory.close() ).thenReturn( completedWithNull() ); + private static SessionFactory sessionFactoryMock() { + SessionFactory sessionFactory = mock(SessionFactory.class); + when(sessionFactory.close()).thenReturn(completedWithNull()); return sessionFactory; } - private static InternalDriver newDriver( boolean isMetricsEnabled ) - { + private static InternalDriver newDriver(boolean isMetricsEnabled) { SessionFactory sessionFactory = sessionFactoryMock(); Config config = Config.defaultConfig(); - if ( isMetricsEnabled ) - { + if (isMetricsEnabled) { config = Config.builder().withDriverMetrics().build(); } - MetricsProvider metricsProvider = DriverFactory.getOrCreateMetricsProvider( config, Clock.SYSTEM ); - return new InternalDriver( SecurityPlanImpl.insecure(), sessionFactory, metricsProvider, DEV_NULL_LOGGING ); + MetricsProvider metricsProvider = DriverFactory.getOrCreateMetricsProvider(config, Clock.SYSTEM); + return new InternalDriver(SecurityPlanImpl.insecure(), sessionFactory, metricsProvider, DEV_NULL_LOGGING); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalIsoDurationTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalIsoDurationTest.java index 42e9511e6a..c44d0cb415 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalIsoDurationTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalIsoDurationTest.java @@ -18,16 +18,6 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; - -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.Period; -import java.time.temporal.Temporal; -import java.time.temporal.UnsupportedTemporalTypeException; - -import org.neo4j.driver.types.IsoDuration; - import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.MONTHS; import static java.time.temporal.ChronoUnit.NANOS; @@ -39,148 +29,144 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -class InternalIsoDurationTest -{ +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.Period; +import java.time.temporal.Temporal; +import java.time.temporal.UnsupportedTemporalTypeException; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.types.IsoDuration; + +class InternalIsoDurationTest { @Test - void shouldExposeMonths() - { - IsoDuration duration = newDuration( 42, 1, 2, 3 ); - assertEquals( 42, duration.months() ); - assertEquals( 42, duration.get( MONTHS ) ); + void shouldExposeMonths() { + IsoDuration duration = newDuration(42, 1, 2, 3); + assertEquals(42, duration.months()); + assertEquals(42, duration.get(MONTHS)); } @Test - void shouldExposeDays() - { - IsoDuration duration = newDuration( 1, 42, 2, 3 ); - assertEquals( 42, duration.days() ); - assertEquals( 42, duration.get( DAYS ) ); + void shouldExposeDays() { + IsoDuration duration = newDuration(1, 42, 2, 3); + assertEquals(42, duration.days()); + assertEquals(42, duration.get(DAYS)); } @Test - void shouldExposeSeconds() - { - IsoDuration duration = newDuration( 1, 2, 42, 3 ); - assertEquals( 42, duration.seconds() ); - assertEquals( 42, duration.get( SECONDS ) ); + void shouldExposeSeconds() { + IsoDuration duration = newDuration(1, 2, 42, 3); + assertEquals(42, duration.seconds()); + assertEquals(42, duration.get(SECONDS)); } @Test - void shouldExposeNanoseconds() - { - IsoDuration duration = newDuration( 1, 2, 3, 42 ); - assertEquals( 42, duration.nanoseconds() ); - assertEquals( 42, duration.get( NANOS ) ); + void shouldExposeNanoseconds() { + IsoDuration duration = newDuration(1, 2, 3, 42); + assertEquals(42, duration.nanoseconds()); + assertEquals(42, duration.get(NANOS)); } @Test - void shouldFailToGetUnsupportedTemporalUnit() - { - IsoDuration duration = newDuration( 1, 2, 3, 4 ); + void shouldFailToGetUnsupportedTemporalUnit() { + IsoDuration duration = newDuration(1, 2, 3, 4); - assertThrows( UnsupportedTemporalTypeException.class, () -> duration.get( YEARS ) ); + assertThrows(UnsupportedTemporalTypeException.class, () -> duration.get(YEARS)); } @Test - void shouldExposeSupportedTemporalUnits() - { - IsoDuration duration = newDuration( 1, 2, 3, 4 ); - assertEquals( asList( MONTHS, DAYS, SECONDS, NANOS ), duration.getUnits() ); + void shouldExposeSupportedTemporalUnits() { + IsoDuration duration = newDuration(1, 2, 3, 4); + assertEquals(asList(MONTHS, DAYS, SECONDS, NANOS), duration.getUnits()); } @Test - void shouldAddTo() - { - IsoDuration duration = newDuration( 1, 2, 3, 4 ); - LocalDateTime dateTime = LocalDateTime.of( 1990, 1, 1, 0, 0, 0, 0 ); + void shouldAddTo() { + IsoDuration duration = newDuration(1, 2, 3, 4); + LocalDateTime dateTime = LocalDateTime.of(1990, 1, 1, 0, 0, 0, 0); - Temporal result = duration.addTo( dateTime ); + Temporal result = duration.addTo(dateTime); - assertEquals( LocalDateTime.of( 1990, 2, 3, 0, 0, 3, 4 ), result ); + assertEquals(LocalDateTime.of(1990, 2, 3, 0, 0, 3, 4), result); } @Test - void shouldSubtractFrom() - { - IsoDuration duration = newDuration( 4, 3, 2, 1 ); - LocalDateTime dateTime = LocalDateTime.of( 1990, 7, 19, 0, 0, 59, 999 ); + void shouldSubtractFrom() { + IsoDuration duration = newDuration(4, 3, 2, 1); + LocalDateTime dateTime = LocalDateTime.of(1990, 7, 19, 0, 0, 59, 999); - Temporal result = duration.subtractFrom( dateTime ); + Temporal result = duration.subtractFrom(dateTime); - assertEquals( LocalDateTime.of( 1990, 3, 16, 0, 0, 57, 998 ), result ); + assertEquals(LocalDateTime.of(1990, 3, 16, 0, 0, 57, 998), result); } @Test - void shouldImplementEqualsAndHashCode() - { - IsoDuration duration1 = newDuration( 1, 2, 3, 4 ); - IsoDuration duration2 = newDuration( 1, 2, 3, 4 ); + void shouldImplementEqualsAndHashCode() { + IsoDuration duration1 = newDuration(1, 2, 3, 4); + IsoDuration duration2 = newDuration(1, 2, 3, 4); - assertEquals( duration1, duration2 ); - assertEquals( duration1.hashCode(), duration2.hashCode() ); + assertEquals(duration1, duration2); + assertEquals(duration1.hashCode(), duration2.hashCode()); } @Test - void shouldCreateFromPeriod() - { - Period period = Period.of( 3, 5, 12 ); + void shouldCreateFromPeriod() { + Period period = Period.of(3, 5, 12); - InternalIsoDuration duration = new InternalIsoDuration( period ); + InternalIsoDuration duration = new InternalIsoDuration(period); - assertEquals( period.toTotalMonths(), duration.months() ); - assertEquals( period.getDays(), duration.days() ); - assertEquals( 0, duration.seconds() ); - assertEquals( 0, duration.nanoseconds() ); + assertEquals(period.toTotalMonths(), duration.months()); + assertEquals(period.getDays(), duration.days()); + assertEquals(0, duration.seconds()); + assertEquals(0, duration.nanoseconds()); } @Test - void shouldCreateFromDuration() - { - Duration duration = Duration.ofSeconds( 391784, 4879173 ); + void shouldCreateFromDuration() { + Duration duration = Duration.ofSeconds(391784, 4879173); - InternalIsoDuration isoDuration = new InternalIsoDuration( duration ); + InternalIsoDuration isoDuration = new InternalIsoDuration(duration); - assertEquals( 0, isoDuration.months() ); - assertEquals( 0, isoDuration.days() ); - assertEquals( duration.getSeconds(), isoDuration.seconds() ); - assertEquals( duration.getNano(), isoDuration.nanoseconds() ); + assertEquals(0, isoDuration.months()); + assertEquals(0, isoDuration.days()); + assertEquals(duration.getSeconds(), isoDuration.seconds()); + assertEquals(duration.getNano(), isoDuration.nanoseconds()); } @Test - void toStringShouldPrintInIsoStandardFormat() - { - assertThat( newDuration( 0, 0, 0, 0 ).toString(), equalTo( "P0M0DT0S" ) ); - assertThat( newDuration( 2, 45, 59, 11 ).toString(), equalTo( "P2M45DT59.000000011S" ) ); - assertThat( newDuration( 4, -101, 1, 999 ).toString(), equalTo( "P4M-101DT1.000000999S" ) ); - assertThat( newDuration( -1, 12, -19, 1 ).toString(), equalTo( "P-1M12DT-18.999999999S" ) ); - assertThat( newDuration( 0, 0, -1, 1 ).toString(), equalTo( "P0M0DT-0.999999999S" ) ); - - assertThat( new InternalIsoDuration( Period.parse( "P356D" ) ).toString(), equalTo( "P0M356DT0S" ) ); - assertThat( new InternalIsoDuration( Duration.parse( "PT45S" ) ).toString(), equalTo( "P0M0DT45S" ) ); - - assertThat( new InternalIsoDuration( 0, 14, Duration.parse( "PT16H12M" ) ).toString(), equalTo( "P0M14DT58320S" ) ); - assertThat( new InternalIsoDuration( 5, 1, Duration.parse( "PT12H" ) ).toString(), equalTo( "P5M1DT43200S" ) ); - assertThat( new InternalIsoDuration( 0, 17, Duration.parse( "PT2H0.111222333S" ) ).toString(), equalTo( "P0M17DT7200.111222333S" ) ); - - assertThat( newDuration( 42, 42, 42, 0 ).toString(), equalTo( "P42M42DT42S" ) ); - assertThat( newDuration( 42, 42, -42, 0 ).toString(), equalTo( "P42M42DT-42S" ) ); - - assertThat( newDuration( 42, 42, 0, 5 ).toString(), equalTo( "P42M42DT0.000000005S" ) ); - assertThat( newDuration( 42, 42, 0, -5 ).toString(), equalTo( "P42M42DT-0.000000005S" ) ); - - assertThat( newDuration( 42, 42, 1, 5 ).toString(), equalTo( "P42M42DT1.000000005S" ) ); - assertThat( newDuration( 42, 42, -1, 5 ).toString(), equalTo( "P42M42DT-0.999999995S" ) ); - assertThat( newDuration( 42, 42, 1, -5 ).toString(), equalTo( "P42M42DT0.999999995S" ) ); - assertThat( newDuration( 42, 42, -1, -5 ).toString(), equalTo( "P42M42DT-1.000000005S" ) ); - - assertThat( newDuration( 42, 42, 28, 9 ).toString(), equalTo( "P42M42DT28.000000009S" ) ); - assertThat( newDuration( 42, 42, -28, 9 ).toString(), equalTo( "P42M42DT-27.999999991S" ) ); - assertThat( newDuration( 42, 42, 28, -9 ).toString(), equalTo( "P42M42DT27.999999991S" ) ); - assertThat( newDuration( 42, 42, -28, -9 ).toString(), equalTo( "P42M42DT-28.000000009S" ) ); + void toStringShouldPrintInIsoStandardFormat() { + assertThat(newDuration(0, 0, 0, 0).toString(), equalTo("P0M0DT0S")); + assertThat(newDuration(2, 45, 59, 11).toString(), equalTo("P2M45DT59.000000011S")); + assertThat(newDuration(4, -101, 1, 999).toString(), equalTo("P4M-101DT1.000000999S")); + assertThat(newDuration(-1, 12, -19, 1).toString(), equalTo("P-1M12DT-18.999999999S")); + assertThat(newDuration(0, 0, -1, 1).toString(), equalTo("P0M0DT-0.999999999S")); + + assertThat(new InternalIsoDuration(Period.parse("P356D")).toString(), equalTo("P0M356DT0S")); + assertThat(new InternalIsoDuration(Duration.parse("PT45S")).toString(), equalTo("P0M0DT45S")); + + assertThat(new InternalIsoDuration(0, 14, Duration.parse("PT16H12M")).toString(), equalTo("P0M14DT58320S")); + assertThat(new InternalIsoDuration(5, 1, Duration.parse("PT12H")).toString(), equalTo("P5M1DT43200S")); + assertThat( + new InternalIsoDuration(0, 17, Duration.parse("PT2H0.111222333S")).toString(), + equalTo("P0M17DT7200.111222333S")); + + assertThat(newDuration(42, 42, 42, 0).toString(), equalTo("P42M42DT42S")); + assertThat(newDuration(42, 42, -42, 0).toString(), equalTo("P42M42DT-42S")); + + assertThat(newDuration(42, 42, 0, 5).toString(), equalTo("P42M42DT0.000000005S")); + assertThat(newDuration(42, 42, 0, -5).toString(), equalTo("P42M42DT-0.000000005S")); + + assertThat(newDuration(42, 42, 1, 5).toString(), equalTo("P42M42DT1.000000005S")); + assertThat(newDuration(42, 42, -1, 5).toString(), equalTo("P42M42DT-0.999999995S")); + assertThat(newDuration(42, 42, 1, -5).toString(), equalTo("P42M42DT0.999999995S")); + assertThat(newDuration(42, 42, -1, -5).toString(), equalTo("P42M42DT-1.000000005S")); + + assertThat(newDuration(42, 42, 28, 9).toString(), equalTo("P42M42DT28.000000009S")); + assertThat(newDuration(42, 42, -28, 9).toString(), equalTo("P42M42DT-27.999999991S")); + assertThat(newDuration(42, 42, 28, -9).toString(), equalTo("P42M42DT27.999999991S")); + assertThat(newDuration(42, 42, -28, -9).toString(), equalTo("P42M42DT-28.000000009S")); } - private static IsoDuration newDuration( long months, long days, long seconds, int nanoseconds ) - { - return new InternalIsoDuration( months, days, seconds, nanoseconds ); + private static IsoDuration newDuration(long months, long days, long seconds, int nanoseconds) { + return new InternalIsoDuration(months, days, seconds, nanoseconds); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalMapAccessorWithDefaultValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalMapAccessorWithDefaultValueTest.java index 406f2f6d1e..b5989997f9 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalMapAccessorWithDefaultValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalMapAccessorWithDefaultValueTest.java @@ -18,14 +18,18 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.neo4j.driver.Values.ofInteger; +import static org.neo4j.driver.Values.value; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Record; import org.neo4j.driver.Value; import org.neo4j.driver.Values; @@ -44,280 +48,246 @@ import org.neo4j.driver.types.Path; import org.neo4j.driver.types.Relationship; -import static java.util.Arrays.asList; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.neo4j.driver.Values.ofInteger; -import static org.neo4j.driver.Values.value; - -class InternalMapAccessorWithDefaultValueTest -{ +class InternalMapAccessorWithDefaultValueTest { private static final String wrongKey = "wrong_key"; @Test - void shouldGetValueFromRecord() - { + void shouldGetValueFromRecord() { Record record = createRecord(); // Scalar Values - assertThat( record.get( "NullValue", NullValue.NULL ), equalTo( NullValue.NULL ) ); - assertThat( record.get( wrongKey, NullValue.NULL ), equalTo( NullValue.NULL ) ); + assertThat(record.get("NullValue", NullValue.NULL), equalTo(NullValue.NULL)); + assertThat(record.get(wrongKey, NullValue.NULL), equalTo(NullValue.NULL)); - assertThat( record.get( "BooleanValue", BooleanValue.FALSE ), equalTo( ( Value ) BooleanValue.TRUE ) ); - assertThat( record.get( wrongKey, BooleanValue.FALSE ), equalTo( ( Value ) BooleanValue.FALSE ) ); + assertThat(record.get("BooleanValue", BooleanValue.FALSE), equalTo((Value) BooleanValue.TRUE)); + assertThat(record.get(wrongKey, BooleanValue.FALSE), equalTo((Value) BooleanValue.FALSE)); - assertThat( record.get( "StringValue", new StringValue( "" ) ), - equalTo( ( Value ) new StringValue( "hello world" ) ) ); - assertThat( record.get( wrongKey, new StringValue( "" ) ), equalTo( ( Value ) new StringValue( "" ) ) ); + assertThat(record.get("StringValue", new StringValue("")), equalTo((Value) new StringValue("hello world"))); + assertThat(record.get(wrongKey, new StringValue("")), equalTo((Value) new StringValue(""))); - assertThat( record.get( "IntegerValue", new IntegerValue( -1 ) ), equalTo( ( Value ) new IntegerValue( 11 ) ) ); - assertThat( record.get( wrongKey, new IntegerValue( -1 ) ), equalTo( ( Value ) new IntegerValue( -1 ) ) ); + assertThat(record.get("IntegerValue", new IntegerValue(-1)), equalTo((Value) new IntegerValue(11))); + assertThat(record.get(wrongKey, new IntegerValue(-1)), equalTo((Value) new IntegerValue(-1))); - assertThat( record.get( "FloatValue", new FloatValue( 1.1 ) ), equalTo( ( Value ) new FloatValue( 2.2 ) ) ); - assertThat( record.get( wrongKey, new FloatValue( 1.1 ) ), equalTo( ( Value ) new FloatValue( 1.1 ) ) ); + assertThat(record.get("FloatValue", new FloatValue(1.1)), equalTo((Value) new FloatValue(2.2))); + assertThat(record.get(wrongKey, new FloatValue(1.1)), equalTo((Value) new FloatValue(1.1))); // List - assertThat( record.get( "ListValue", new ListValue() ), - equalTo( (Value) new ListValue( new IntegerValue( 1 ), new IntegerValue( 2 ) ) ) ); - assertThat( record.get( wrongKey, new ListValue() ), equalTo( (Value) new ListValue() ) ); + assertThat(record.get("ListValue", new ListValue()), equalTo((Value) + new ListValue(new IntegerValue(1), new IntegerValue(2)))); + assertThat(record.get(wrongKey, new ListValue()), equalTo((Value) new ListValue())); // Map - Value defaultMapValue = new MapValue( new HashMap() ); - Value realMapValue = new MapValue( createMap() ); - assertThat( record.get( "MapValue", defaultMapValue ), equalTo( realMapValue ) ); - assertThat( record.get( wrongKey, defaultMapValue ), equalTo( defaultMapValue ) ); + Value defaultMapValue = new MapValue(new HashMap()); + Value realMapValue = new MapValue(createMap()); + assertThat(record.get("MapValue", defaultMapValue), equalTo(realMapValue)); + assertThat(record.get(wrongKey, defaultMapValue), equalTo(defaultMapValue)); // Path - Value defaultPathValue = new PathValue( new InternalPath( - new InternalNode( 0L ), - new InternalRelationship( 0L, 0L, 1L, "T" ), - new InternalNode( 1L ) ) ); - Value realPathValue = new PathValue( createPath() ); - assertThat( record.get( "PathValue", defaultPathValue ), equalTo( realPathValue ) ); - assertThat( record.get( wrongKey, defaultPathValue ), equalTo( defaultPathValue ) ); + Value defaultPathValue = new PathValue(new InternalPath( + new InternalNode(0L), new InternalRelationship(0L, 0L, 1L, "T"), new InternalNode(1L))); + Value realPathValue = new PathValue(createPath()); + assertThat(record.get("PathValue", defaultPathValue), equalTo(realPathValue)); + assertThat(record.get(wrongKey, defaultPathValue), equalTo(defaultPathValue)); // Node - Value defaultNodeValue = new NodeValue( new InternalNode( 0L ) ); - Value realNodeValue = new NodeValue( createNode() ); - assertThat( record.get( "NodeValue", defaultNodeValue ), equalTo( realNodeValue ) ); - assertThat( record.get( wrongKey, defaultNodeValue ), equalTo( defaultNodeValue ) ); + Value defaultNodeValue = new NodeValue(new InternalNode(0L)); + Value realNodeValue = new NodeValue(createNode()); + assertThat(record.get("NodeValue", defaultNodeValue), equalTo(realNodeValue)); + assertThat(record.get(wrongKey, defaultNodeValue), equalTo(defaultNodeValue)); // Rel - Value defaultRelValue = new RelationshipValue( new InternalRelationship( 0L, 0L, 1L, "T" ) ); - Value realRelValue = new RelationshipValue( createRel() ); - assertThat( record.get( "RelValue", defaultRelValue ), equalTo( realRelValue ) ); - assertThat( record.get( wrongKey, defaultRelValue ), equalTo( defaultRelValue ) ); + Value defaultRelValue = new RelationshipValue(new InternalRelationship(0L, 0L, 1L, "T")); + Value realRelValue = new RelationshipValue(createRel()); + assertThat(record.get("RelValue", defaultRelValue), equalTo(realRelValue)); + assertThat(record.get(wrongKey, defaultRelValue), equalTo(defaultRelValue)); } @Test - void shouldGetObjectFromRecord() - { + void shouldGetObjectFromRecord() { Record record = createRecord(); // IntegerValue.asObject returns Long - assertThat( record.get( "IntegerValue", (Object) 3 ), equalTo( 11L ) ); - assertThat( record.get( wrongKey, (Object) 3 ), equalTo( 3 ) ); + assertThat(record.get("IntegerValue", (Object) 3), equalTo(11L)); + assertThat(record.get(wrongKey, (Object) 3), equalTo(3)); } @Test - void shouldGetNumberFromRecord() - { + void shouldGetNumberFromRecord() { Record record = createRecord(); // IntegerValue.asNumber returns Long - assertThat( record.get( "IntegerValue", (Number) 3 ), equalTo( (Object) 11L ) ); - assertThat( record.get( wrongKey, (Number) 3 ), equalTo( (Object) 3 ) ); + assertThat(record.get("IntegerValue", (Number) 3), equalTo((Object) 11L)); + assertThat(record.get(wrongKey, (Number) 3), equalTo((Object) 3)); } @Test - void shouldGetEntityFromRecord() - { + void shouldGetEntityFromRecord() { Record record = createRecord(); - Entity defaultNodeEntity = new InternalNode( 0L ); - assertThat( record.get( "NodeValue", defaultNodeEntity ), equalTo( (Entity) createNode() ) ); - assertThat( record.get( wrongKey, defaultNodeEntity ), equalTo( defaultNodeEntity ) ); + Entity defaultNodeEntity = new InternalNode(0L); + assertThat(record.get("NodeValue", defaultNodeEntity), equalTo((Entity) createNode())); + assertThat(record.get(wrongKey, defaultNodeEntity), equalTo(defaultNodeEntity)); - Entity defaultRelEntity = new InternalRelationship( 0L, 0L, 1L, "T" ); - assertThat( record.get( "RelValue", defaultRelEntity ), equalTo( (Entity) createRel() ) ); - assertThat( record.get( wrongKey, defaultRelEntity ), equalTo( defaultRelEntity ) ); + Entity defaultRelEntity = new InternalRelationship(0L, 0L, 1L, "T"); + assertThat(record.get("RelValue", defaultRelEntity), equalTo((Entity) createRel())); + assertThat(record.get(wrongKey, defaultRelEntity), equalTo(defaultRelEntity)); } @Test - void shouldGetNodeFromRecord() - { + void shouldGetNodeFromRecord() { Record record = createRecord(); - Node defaultNode = new InternalNode( 0L ); - assertThat( record.get( "NodeValue", defaultNode ), equalTo( createNode() ) ); - assertThat( record.get( wrongKey, defaultNode ), equalTo( defaultNode ) ); + Node defaultNode = new InternalNode(0L); + assertThat(record.get("NodeValue", defaultNode), equalTo(createNode())); + assertThat(record.get(wrongKey, defaultNode), equalTo(defaultNode)); } @Test - void shouldGetRelFromRecord() - { + void shouldGetRelFromRecord() { Record record = createRecord(); - Relationship defaultRel = new InternalRelationship( 0L, 0L, 1L, "T" ); - assertThat( record.get( "RelValue", defaultRel ), equalTo( createRel() ) ); - assertThat( record.get( wrongKey, defaultRel ), equalTo( defaultRel ) ); + Relationship defaultRel = new InternalRelationship(0L, 0L, 1L, "T"); + assertThat(record.get("RelValue", defaultRel), equalTo(createRel())); + assertThat(record.get(wrongKey, defaultRel), equalTo(defaultRel)); } @Test - void shouldGetPathFromRecord() - { + void shouldGetPathFromRecord() { Record record = createRecord(); - Path defaultPath = new InternalPath( - new InternalNode( 0L ), - new InternalRelationship( 0L, 0L, 1L, "T" ), - new InternalNode( 1L ) ); - assertThat( record.get( "PathValue", defaultPath ), equalTo( createPath() ) ); - assertThat( record.get( wrongKey, defaultPath ), equalTo( defaultPath ) ); + Path defaultPath = + new InternalPath(new InternalNode(0L), new InternalRelationship(0L, 0L, 1L, "T"), new InternalNode(1L)); + assertThat(record.get("PathValue", defaultPath), equalTo(createPath())); + assertThat(record.get(wrongKey, defaultPath), equalTo(defaultPath)); } @Test - void shouldGetListOfObjectsFromRecord() - { + void shouldGetListOfObjectsFromRecord() { Record record = createRecord(); List defaultValue = new ArrayList<>(); // List of java objects, therefore IntegerValue will be converted to Long - assertThat( record.get( "ListValue", defaultValue ), equalTo( asList( (Object) 1L, 2L ) ) ); - assertThat( record.get( wrongKey, defaultValue ), equalTo( defaultValue ) ); + assertThat(record.get("ListValue", defaultValue), equalTo(asList((Object) 1L, 2L))); + assertThat(record.get(wrongKey, defaultValue), equalTo(defaultValue)); } @Test - void shouldGetListOfTFromRecord() - { + void shouldGetListOfTFromRecord() { Record record = createRecord(); List defaultValue = new ArrayList<>(); - assertThat( record.get( "ListValue", defaultValue, ofInteger() ), equalTo( asList( 1, 2 ) ) ); - assertThat( record.get( wrongKey, defaultValue, ofInteger() ), equalTo( defaultValue ) ); + assertThat(record.get("ListValue", defaultValue, ofInteger()), equalTo(asList(1, 2))); + assertThat(record.get(wrongKey, defaultValue, ofInteger()), equalTo(defaultValue)); } @Test - void shouldGetMapOfStringObjectFromRecord() - { + void shouldGetMapOfStringObjectFromRecord() { Record record = createRecord(); Map expected = new HashMap<>(); - expected.put( "key1", 1L ); - expected.put( "key2", 2L ); - Map defaultValue = new HashMap<>(); + expected.put("key1", 1L); + expected.put("key2", 2L); + Map defaultValue = new HashMap<>(); - assertThat( record.get( "MapValue", defaultValue ), equalTo( expected ) ); - assertThat( record.get( wrongKey, defaultValue ), equalTo( defaultValue ) ); + assertThat(record.get("MapValue", defaultValue), equalTo(expected)); + assertThat(record.get(wrongKey, defaultValue), equalTo(defaultValue)); } @Test - void shouldGetMapOfStringTFromRecord() - { + void shouldGetMapOfStringTFromRecord() { Record record = createRecord(); Map expected = new HashMap<>(); - expected.put( "key1", 1 ); - expected.put( "key2", 2 ); - Map defaultValue = new HashMap<>(); + expected.put("key1", 1); + expected.put("key2", 2); + Map defaultValue = new HashMap<>(); - assertThat( record.get( "MapValue", defaultValue, ofInteger() ), equalTo( expected ) ); - assertThat( record.get( wrongKey, defaultValue, ofInteger() ), equalTo( defaultValue ) ); + assertThat(record.get("MapValue", defaultValue, ofInteger()), equalTo(expected)); + assertThat(record.get(wrongKey, defaultValue, ofInteger()), equalTo(defaultValue)); } @Test - void shouldGetPrimitiveTypesFromRecord() - { + void shouldGetPrimitiveTypesFromRecord() { Record record = createRecord(); // boolean - assertThat( record.get( "BooleanValue", false ), equalTo( true ) ); - assertThat( record.get( wrongKey, false ), equalTo( false ) ); + assertThat(record.get("BooleanValue", false), equalTo(true)); + assertThat(record.get(wrongKey, false), equalTo(false)); // string - assertThat( record.get( "StringValue", "" ), equalTo( "hello world" ) ); - assertThat( record.get( wrongKey, "" ), equalTo( "" ) ); + assertThat(record.get("StringValue", ""), equalTo("hello world")); + assertThat(record.get(wrongKey, ""), equalTo("")); // int - assertThat( record.get( "IntegerValue", 3 ), equalTo( 11 ) ); - assertThat( record.get( wrongKey, 3 ), equalTo( 3 ) ); + assertThat(record.get("IntegerValue", 3), equalTo(11)); + assertThat(record.get(wrongKey, 3), equalTo(3)); // long - assertThat( record.get( "IntegerValue", 4L ), equalTo( 11L ) ); - assertThat( record.get( wrongKey, 4L ), equalTo( 4L ) ); + assertThat(record.get("IntegerValue", 4L), equalTo(11L)); + assertThat(record.get(wrongKey, 4L), equalTo(4L)); // float - assertThat( record.get( "float", 1F ), equalTo( 0.1F ) ); - assertThat( record.get( wrongKey, 1F ), equalTo( 1F ) ); + assertThat(record.get("float", 1F), equalTo(0.1F)); + assertThat(record.get(wrongKey, 1F), equalTo(1F)); // double - assertThat( record.get( "FloatValue", 1.1 ), equalTo( 2.2 ) ); - assertThat( record.get( wrongKey, 1.1 ), equalTo( 1.1 ) ); + assertThat(record.get("FloatValue", 1.1), equalTo(2.2)); + assertThat(record.get(wrongKey, 1.1), equalTo(1.1)); } @Test - void shouldGetFromMap() - { - MapValue mapValue = new MapValue( createMap() ); - assertThat( mapValue.get( "key1", 0L ), equalTo( 1L ) ); - assertThat( mapValue.get( "key2", 0 ), equalTo( 2 ) ); - assertThat( mapValue.get( wrongKey, "" ), equalTo( "" ) ); + void shouldGetFromMap() { + MapValue mapValue = new MapValue(createMap()); + assertThat(mapValue.get("key1", 0L), equalTo(1L)); + assertThat(mapValue.get("key2", 0), equalTo(2)); + assertThat(mapValue.get(wrongKey, ""), equalTo("")); } @Test - void shouldGetFromNode() - { - Map props = new HashMap<>(); - props.put( "k1", value( 43 ) ); - props.put( "k2", value( "hello world" ) ); - NodeValue nodeValue = new NodeValue( new InternalNode( 42L, Collections.singletonList( "L" ), props ) ); - - assertThat( nodeValue.get( "k1", 0 ), equalTo( 43 ) ); - assertThat( nodeValue.get( "k2", "" ), equalTo( "hello world" ) ); - assertThat( nodeValue.get( wrongKey, 0L ), equalTo( 0L ) ); + void shouldGetFromNode() { + Map props = new HashMap<>(); + props.put("k1", value(43)); + props.put("k2", value("hello world")); + NodeValue nodeValue = new NodeValue(new InternalNode(42L, Collections.singletonList("L"), props)); + + assertThat(nodeValue.get("k1", 0), equalTo(43)); + assertThat(nodeValue.get("k2", ""), equalTo("hello world")); + assertThat(nodeValue.get(wrongKey, 0L), equalTo(0L)); } @Test - void shouldGetFromRel() - { - Map props = new HashMap<>(); - props.put( "k1", value( 43 ) ); - props.put( "k2", value( "hello world" ) ); - RelationshipValue relValue = new RelationshipValue( new InternalRelationship( 0L, 0L, 1L, "T", props ) ); - - assertThat( relValue.get( "k1", 0 ), equalTo( 43 ) ); - assertThat( relValue.get( "k2", "" ), equalTo( "hello world" ) ); - assertThat( relValue.get( wrongKey, 0L ), equalTo( 0L ) ); + void shouldGetFromRel() { + Map props = new HashMap<>(); + props.put("k1", value(43)); + props.put("k2", value("hello world")); + RelationshipValue relValue = new RelationshipValue(new InternalRelationship(0L, 0L, 1L, "T", props)); + + assertThat(relValue.get("k1", 0), equalTo(43)); + assertThat(relValue.get("k2", ""), equalTo("hello world")); + assertThat(relValue.get(wrongKey, 0L), equalTo(0L)); } - private Path createPath() - { + private Path createPath() { return new InternalPath( - new InternalNode( 42L ), - new InternalRelationship( 43L, 42L, 44L, "T" ), - new InternalNode( 44L ) ); + new InternalNode(42L), new InternalRelationship(43L, 42L, 44L, "T"), new InternalNode(44L)); } - private Node createNode() - { - return new InternalNode( 1L ); + private Node createNode() { + return new InternalNode(1L); } - private Relationship createRel() - { - return new InternalRelationship( 1L, 1L, 2L, "T" ); + private Relationship createRel() { + return new InternalRelationship(1L, 1L, 2L, "T"); } - private Map createMap() - { + private Map createMap() { Map map = new HashMap<>(); - map.put( "key1", new IntegerValue( 1 ) ); - map.put( "key2", new IntegerValue( 2 ) ); + map.put("key1", new IntegerValue(1)); + map.put("key2", new IntegerValue(2)); return map; } - private Record createRecord() - { + private Record createRecord() { Map map = createMap(); Path path = createPath(); Node node = createNode(); @@ -334,23 +304,21 @@ private Record createRecord() "PathValue", "NodeValue", "RelValue", - "float" - ); - Value[] values = new Value[]{ - NullValue.NULL, - BooleanValue.TRUE, - new StringValue( "hello world" ), - new IntegerValue( 11 ), - new FloatValue( 2.2 ), - new ListValue( new IntegerValue( 1 ), new IntegerValue( 2 ) ), - new MapValue( map ), - new PathValue( path ), - new NodeValue( node ), - new RelationshipValue( rel ), - Values.value( 0.1F ) + "float"); + Value[] values = new Value[] { + NullValue.NULL, + BooleanValue.TRUE, + new StringValue("hello world"), + new IntegerValue(11), + new FloatValue(2.2), + new ListValue(new IntegerValue(1), new IntegerValue(2)), + new MapValue(map), + new PathValue(path), + new NodeValue(node), + new RelationshipValue(rel), + Values.value(0.1F) }; - Record record = new InternalRecord( keys, values ); + Record record = new InternalRecord(keys, values); return record; } - } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalNodeTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalNodeTest.java index ecccef961e..2a14a50ef9 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalNodeTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalNodeTest.java @@ -18,57 +18,50 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.neo4j.driver.Values.NULL; +import static org.neo4j.driver.Values.value; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; - -import org.neo4j.driver.Value; import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.neo4j.driver.Values.NULL; -import static org.neo4j.driver.Values.value; - -class InternalNodeTest -{ +class InternalNodeTest { @Test - void extractValuesFromNode() - { + void extractValuesFromNode() { // GIVEN InternalNode node = createNode(); - Function extractor = Value::asInt; + Function extractor = Value::asInt; - //WHEN - Iterable values = node.values( extractor ); + // WHEN + Iterable values = node.values(extractor); - //THEN + // THEN Iterator iterator = values.iterator(); - assertThat( iterator.next(), equalTo( 1 ) ); - assertThat( iterator.next(), equalTo( 2 ) ); - assertFalse( iterator.hasNext() ); + assertThat(iterator.next(), equalTo(1)); + assertThat(iterator.next(), equalTo(2)); + assertFalse(iterator.hasNext()); } @Test - void accessUnknownKeyShouldBeNull() - { + void accessUnknownKeyShouldBeNull() { InternalNode node = createNode(); - assertThat( node.get( "k1" ), equalTo( value( 1 ) ) ); - assertThat( node.get( "k2" ), equalTo( value( 2 ) ) ); - assertThat( node.get( "k3" ), equalTo( NULL ) ); + assertThat(node.get("k1"), equalTo(value(1))); + assertThat(node.get("k2"), equalTo(value(2))); + assertThat(node.get("k3"), equalTo(NULL)); } - private InternalNode createNode() - { - Map props = new HashMap<>(); - props.put( "k1", value( 1 ) ); - props.put( "k2", value( 2 ) ); - return new InternalNode( 42L, Collections.singletonList( "L" ), props ); + private InternalNode createNode() { + Map props = new HashMap<>(); + props.put("k1", value(1)); + props.put("k2", value(2)); + return new InternalNode(42L, Collections.singletonList("L"), props); } - } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalPairTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalPairTest.java index 047f3797ac..c988408bac 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalPairTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalPairTest.java @@ -18,22 +18,19 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.Value; -import org.neo4j.driver.util.Pair; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.neo4j.driver.Values.value; -class InternalPairTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.util.Pair; + +class InternalPairTest { @Test - void testMethods() - { - Pair pair = InternalPair.of( "k", value( "v" ) ); - assertThat( pair.key(), equalTo("k")); - assertThat( pair.value(), equalTo(value("v"))); + void testMethods() { + Pair pair = InternalPair.of("k", value("v")); + assertThat(pair.key(), equalTo("k")); + assertThat(pair.value(), equalTo(value("v"))); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalPathTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalPathTest.java index f8eec384b8..c466067604 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalPathTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalPathTest.java @@ -18,160 +18,135 @@ */ package org.neo4j.driver.internal; -import org.hamcrest.MatcherAssert; -import org.junit.jupiter.api.Test; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Arrays; import java.util.List; - +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.util.Iterables; import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Path; import org.neo4j.driver.types.Relationship; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class InternalPathTest -{ +class InternalPathTest { // (A)-[AB:KNOWS]->(B)<-[CB:KNOWS]-(C)-[CD:KNOWS]->(D) - private InternalPath testPath() - { + private InternalPath testPath() { return new InternalPath( - new InternalNode( 1 ), - new InternalRelationship( -1, 1, 2, "KNOWS" ), - new InternalNode( 2 ), - new InternalRelationship( -2, 3, 2, "KNOWS" ), - new InternalNode( 3 ), - new InternalRelationship( -3, 3, 4, "KNOWS" ), - new InternalNode( 4 ) - ); + new InternalNode(1), + new InternalRelationship(-1, 1, 2, "KNOWS"), + new InternalNode(2), + new InternalRelationship(-2, 3, 2, "KNOWS"), + new InternalNode(3), + new InternalRelationship(-3, 3, 4, "KNOWS"), + new InternalNode(4)); } @Test - void pathSizeShouldReturnNumberOfRelationships() - { + void pathSizeShouldReturnNumberOfRelationships() { // When InternalPath path = testPath(); // Then - assertThat( path.length(), equalTo( 3 ) ); + assertThat(path.length(), equalTo(3)); } @Test - void shouldBeAbleToCreatePathWithSingleNode() - { + void shouldBeAbleToCreatePathWithSingleNode() { // When - InternalPath path = new InternalPath( new InternalNode( 1 ) ); + InternalPath path = new InternalPath(new InternalNode(1)); // Then - assertThat( path.length(), equalTo( 0 ) ); + assertThat(path.length(), equalTo(0)); } @Test - void shouldBeAbleToIterateOverPathAsSegments() - { + void shouldBeAbleToIterateOverPathAsSegments() { // Given InternalPath path = testPath(); // When - List segments = Iterables.asList( path ); + List segments = Iterables.asList(path); // Then - MatcherAssert.assertThat( segments, equalTo( Arrays.asList( (Path.Segment) - new InternalPath.SelfContainedSegment( - new InternalNode( 1 ), - new InternalRelationship( -1, 1, 2, "KNOWS" ), - new InternalNode( 2 ) - ), + MatcherAssert.assertThat( + segments, + equalTo(Arrays.asList( + (Path.Segment) new InternalPath.SelfContainedSegment( + new InternalNode(1), new InternalRelationship(-1, 1, 2, "KNOWS"), new InternalNode(2)), new InternalPath.SelfContainedSegment( - new InternalNode( 2 ), - new InternalRelationship( -2, 3, 2, "KNOWS" ), - new InternalNode( 3 ) - ), + new InternalNode(2), new InternalRelationship(-2, 3, 2, "KNOWS"), new InternalNode(3)), new InternalPath.SelfContainedSegment( - new InternalNode( 3 ), - new InternalRelationship( -3, 3, 4, "KNOWS" ), - new InternalNode( 4 ) - ) - ) - ) ); + new InternalNode(3), + new InternalRelationship(-3, 3, 4, "KNOWS"), + new InternalNode(4))))); } @Test - void shouldBeAbleToIterateOverPathNodes() - { + void shouldBeAbleToIterateOverPathNodes() { // Given InternalPath path = testPath(); // When - List segments = Iterables.asList( path.nodes() ); + List segments = Iterables.asList(path.nodes()); // Then - assertThat( segments, equalTo( Arrays.asList( (Node) - new InternalNode( 1 ), - new InternalNode( 2 ), - new InternalNode( 3 ), - new InternalNode( 4 ) ) ) ); + assertThat( + segments, + equalTo(Arrays.asList( + (Node) new InternalNode(1), new InternalNode(2), new InternalNode(3), new InternalNode(4)))); } @Test - void shouldBeAbleToIterateOverPathRelationships() - { + void shouldBeAbleToIterateOverPathRelationships() { // Given InternalPath path = testPath(); // When - List segments = Iterables.asList( path.relationships() ); + List segments = Iterables.asList(path.relationships()); // Then - assertThat( segments, equalTo( Arrays.asList( (Relationship) - new InternalRelationship( -1, 1, 2, "KNOWS" ), - new InternalRelationship( -2, 3, 2, "KNOWS" ), - new InternalRelationship( -3, 3, 4, "KNOWS" ) ) ) ); + assertThat( + segments, + equalTo(Arrays.asList( + (Relationship) new InternalRelationship(-1, 1, 2, "KNOWS"), + new InternalRelationship(-2, 3, 2, "KNOWS"), + new InternalRelationship(-3, 3, 4, "KNOWS")))); } @Test - void shouldNotBeAbleToCreatePathWithNoEntities() - { - assertThrows( IllegalArgumentException.class, InternalPath::new ); + void shouldNotBeAbleToCreatePathWithNoEntities() { + assertThrows(IllegalArgumentException.class, InternalPath::new); } @Test - void shouldNotBeAbleToCreatePathWithEvenNumberOfEntities() - { - assertThrows( IllegalArgumentException.class, - () -> new InternalPath( - new InternalNode( 1 ), - new InternalRelationship( 2, 3, 4, "KNOWS" ) ) ); + void shouldNotBeAbleToCreatePathWithEvenNumberOfEntities() { + assertThrows( + IllegalArgumentException.class, + () -> new InternalPath(new InternalNode(1), new InternalRelationship(2, 3, 4, "KNOWS"))); } @Test - void shouldNotBeAbleToCreatePathWithNullEntities() - { + void shouldNotBeAbleToCreatePathWithNullEntities() { InternalNode nullNode = null; - assertThrows( IllegalArgumentException.class, () -> new InternalPath( nullNode ) ); + assertThrows(IllegalArgumentException.class, () -> new InternalPath(nullNode)); } @Test - void shouldNotBeAbleToCreatePathWithNodeThatDoesNotConnect() - { - assertThrows( IllegalArgumentException.class, + void shouldNotBeAbleToCreatePathWithNodeThatDoesNotConnect() { + assertThrows( + IllegalArgumentException.class, () -> new InternalPath( - new InternalNode( 1 ), - new InternalRelationship( 2, 1, 3, "KNOWS" ), - new InternalNode( 4 ) ) ); + new InternalNode(1), new InternalRelationship(2, 1, 3, "KNOWS"), new InternalNode(4))); } @Test - void shouldNotBeAbleToCreatePathWithRelationshipThatDoesNotConnect() - { - assertThrows( IllegalArgumentException.class, + void shouldNotBeAbleToCreatePathWithRelationshipThatDoesNotConnect() { + assertThrows( + IllegalArgumentException.class, () -> new InternalPath( - new InternalNode( 1 ), - new InternalRelationship( 2, 3, 4, "KNOWS" ), - new InternalNode( 3 ) ) ); + new InternalNode(1), new InternalRelationship(2, 3, 4, "KNOWS"), new InternalNode(3))); } - } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalRecordTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalRecordTest.java index a47f307714..6adb7f0079 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalRecordTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalRecordTest.java @@ -18,7 +18,14 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.Values.value; import java.util.Arrays; import java.util.Collections; @@ -26,204 +33,177 @@ import java.util.List; import java.util.Map; import java.util.NoSuchElementException; - +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.util.Extract; import org.neo4j.driver.internal.value.NullValue; -import org.neo4j.driver.Value; -import java.util.function.Function; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.Values.value; -class InternalRecordTest -{ +class InternalRecordTest { @Test - void accessingUnknownKeyShouldBeNull() - { + void accessingUnknownKeyShouldBeNull() { InternalRecord record = createRecord(); - assertThat( record.get( "k1" ), equalTo( value( 0 ) ) ); - assertThat( record.get( "k2" ), equalTo( value( 1 ) ) ); - assertThat( record.get( "k3" ), equalTo( NullValue.NULL ) ); + assertThat(record.get("k1"), equalTo(value(0))); + assertThat(record.get("k2"), equalTo(value(1))); + assertThat(record.get("k3"), equalTo(NullValue.NULL)); } @Test - void shouldHaveCorrectSize() - { + void shouldHaveCorrectSize() { InternalRecord record = createRecord(); - assertThat( record.size(), equalTo( 2 ) ); + assertThat(record.size(), equalTo(2)); } @Test - void shouldHaveCorrectFieldIndices() - { + void shouldHaveCorrectFieldIndices() { InternalRecord record = createRecord(); - assertThat( record.index( "k1" ), equalTo( 0 ) ); - assertThat( record.index( "k2" ), equalTo( 1 ) ); + assertThat(record.index("k1"), equalTo(0)); + assertThat(record.index("k2"), equalTo(1)); } @Test - void shouldThrowWhenAskingForIndexOfUnknownField() - { + void shouldThrowWhenAskingForIndexOfUnknownField() { InternalRecord record = createRecord(); - assertThrows( NoSuchElementException.class, () -> record.index( "BATMAN" ) ); + assertThrows(NoSuchElementException.class, () -> record.index("BATMAN")); } @Test - void accessingOutOfBoundsShouldBeNull() - { + void accessingOutOfBoundsShouldBeNull() { InternalRecord record = createRecord(); - assertThat( record.get( 0 ), equalTo( value( 0 ) ) ); - assertThat( record.get( 1 ), equalTo( value( 1 ) ) ); - assertThat( record.get( 2 ), equalTo( NullValue.NULL ) ); - assertThat( record.get( -37 ), equalTo( NullValue.NULL ) ); + assertThat(record.get(0), equalTo(value(0))); + assertThat(record.get(1), equalTo(value(1))); + assertThat(record.get(2), equalTo(NullValue.NULL)); + assertThat(record.get(-37), equalTo(NullValue.NULL)); } @Test - void testContainsKey() - { + void testContainsKey() { InternalRecord record = createRecord(); - assertTrue( record.containsKey( "k1" ) ); - assertTrue( record.containsKey( "k2" ) ); - assertFalse( record.containsKey( "k3" ) ); + assertTrue(record.containsKey("k1")); + assertTrue(record.containsKey("k2")); + assertFalse(record.containsKey("k3")); } @Test - void testIndex() - { + void testIndex() { InternalRecord record = createRecord(); - assertThat( record.index( "k1" ), equalTo( 0 ) ); - assertThat( record.index( "k2" ), equalTo( 1 ) ); + assertThat(record.index("k1"), equalTo(0)); + assertThat(record.index("k2"), equalTo(1)); } @Test - void testAsMap() - { + void testAsMap() { // GIVEN InternalRecord record = createRecord(); // WHEN - Map map = record.asMap(); + Map map = record.asMap(); // THEN - assertThat( map.keySet(), containsInAnyOrder( "k1", "k2" ) ); - assertThat( map.get( "k1" ), equalTo( 0L ) ); - assertThat( map.get( "k2" ), equalTo( 1L ) ); + assertThat(map.keySet(), containsInAnyOrder("k1", "k2")); + assertThat(map.get("k1"), equalTo(0L)); + assertThat(map.get("k2"), equalTo(1L)); } @Test - void testMapExtraction() - { + void testMapExtraction() { // GIVEN InternalRecord record = createRecord(); - Function addOne = value -> value.asInt() + 1; + Function addOne = value -> value.asInt() + 1; // WHEN - Map map = Extract.map( record, addOne ); + Map map = Extract.map(record, addOne); // THEN - assertThat( map.keySet(), contains( "k1", "k2" ) ); - assertThat( map.get( "k1" ), equalTo( 1 ) ); - assertThat( map.get( "k2" ), equalTo( 2 ) ); + assertThat(map.keySet(), contains("k1", "k2")); + assertThat(map.get("k1"), equalTo(1)); + assertThat(map.get("k2"), equalTo(2)); } @Test - void mapExtractionShouldPreserveIterationOrder() - { + void mapExtractionShouldPreserveIterationOrder() { // GIVEN - List keys = Arrays.asList( "k2", "k1" ); - InternalRecord record = new InternalRecord( keys, new Value[]{value( 0 ), value( 1 )} ); - Function addOne = value -> value.asInt() + 1; + List keys = Arrays.asList("k2", "k1"); + InternalRecord record = new InternalRecord(keys, new Value[] {value(0), value(1)}); + Function addOne = value -> value.asInt() + 1; // WHEN - Map map = Extract.map( record, addOne ); + Map map = Extract.map(record, addOne); // THEN - assertThat( map.keySet(), contains( "k2", "k1" ) ); + assertThat(map.keySet(), contains("k2", "k1")); Iterator values = map.values().iterator(); - assertThat( values.next(), equalTo( 1 ) ); - assertThat( values.next(), equalTo( 2 ) ); + assertThat(values.next(), equalTo(1)); + assertThat(values.next(), equalTo(2)); } @Test - void testToString() - { + void testToString() { InternalRecord record = createRecord(); - assertThat( record.toString(), equalTo( "Record<{k1: 0, k2: 1}>" ) ); + assertThat(record.toString(), equalTo("Record<{k1: 0, k2: 1}>")); } @Test - void shouldHaveMethodToGetKeys() - { - //GIVEN - List keys = Arrays.asList( "k2", "k1" ); - InternalRecord record = new InternalRecord( keys, new Value[]{value( 0 ), value( 1 )} ); + void shouldHaveMethodToGetKeys() { + // GIVEN + List keys = Arrays.asList("k2", "k1"); + InternalRecord record = new InternalRecord(keys, new Value[] {value(0), value(1)}); - //WHEN + // WHEN List appendedKeys = record.keys(); - //THEN - assertThat( appendedKeys, equalTo( keys ) ); + // THEN + assertThat(appendedKeys, equalTo(keys)); } @Test - void emptyKeysShouldGiveEmptyList() - { - //GIVEN + void emptyKeysShouldGiveEmptyList() { + // GIVEN List keys = Collections.emptyList(); - InternalRecord record = new InternalRecord( keys, new Value[]{} ); + InternalRecord record = new InternalRecord(keys, new Value[] {}); - //WHEN + // WHEN List appendedKeys = record.keys(); - //THEN - assertThat( appendedKeys, equalTo( keys ) ); + // THEN + assertThat(appendedKeys, equalTo(keys)); } - @Test - void shouldHaveMethodToGetValues() - { - //GIVEN - List keys = Arrays.asList( "k2", "k1" ); - Value[] values = new Value[]{value( 0 ), value( 1 )}; - InternalRecord record = new InternalRecord( keys, values ); - - //WHEN + void shouldHaveMethodToGetValues() { + // GIVEN + List keys = Arrays.asList("k2", "k1"); + Value[] values = new Value[] {value(0), value(1)}; + InternalRecord record = new InternalRecord(keys, values); + + // WHEN List appendedValues = record.values(); - //THEN - assertThat( appendedValues, equalTo( Arrays.asList( values ) ) ); + // THEN + assertThat(appendedValues, equalTo(Arrays.asList(values))); } @Test - void emptyValuesShouldGiveEmptyList() - { - //GIVEN + void emptyValuesShouldGiveEmptyList() { + // GIVEN List keys = Collections.emptyList(); - Value[] values = new Value[]{}; - InternalRecord record = new InternalRecord( keys, values ); + Value[] values = new Value[] {}; + InternalRecord record = new InternalRecord(keys, values); - //WHEN + // WHEN List appendedValues = record.values(); - //THEN - assertThat( appendedValues, equalTo( Arrays.asList( values ) ) ); + // THEN + assertThat(appendedValues, equalTo(Arrays.asList(values))); } - private InternalRecord createRecord() - { - List keys = Arrays.asList( "k1", "k2" ); - return new InternalRecord( keys, new Value[]{value( 0 ), value( 1 )} ); + private InternalRecord createRecord() { + List keys = Arrays.asList("k1", "k2"); + return new InternalRecord(keys, new Value[] {value(0), value(1)}); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalRelationshipTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalRelationshipTest.java index 2de449e061..5d156d2bb9 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalRelationshipTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalRelationshipTest.java @@ -18,57 +18,50 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.neo4j.driver.Value; -import java.util.function.Function; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.neo4j.driver.Values.NULL; import static org.neo4j.driver.Values.value; -class InternalRelationshipTest -{ +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; + +class InternalRelationshipTest { @Test - void extractValuesFromNode() - { + void extractValuesFromNode() { // GIVEN InternalRelationship relationship = createRelationship(); - Function extractor = Value::asInt; + Function extractor = Value::asInt; - //WHEN - Iterable values = relationship.values( extractor ); + // WHEN + Iterable values = relationship.values(extractor); - //THEN + // THEN Iterator iterator = values.iterator(); - assertThat( iterator.next(), equalTo( 1 ) ); - assertThat( iterator.next(), equalTo( 2 ) ); - assertFalse( iterator.hasNext() ); + assertThat(iterator.next(), equalTo(1)); + assertThat(iterator.next(), equalTo(2)); + assertFalse(iterator.hasNext()); } @Test - void accessUnknownKeyShouldBeNull() - { + void accessUnknownKeyShouldBeNull() { InternalRelationship relationship = createRelationship(); - assertThat( relationship.get( "k1" ), equalTo( value( 1 ) ) ); - assertThat( relationship.get( "k2" ), equalTo( value( 2 ) ) ); - assertThat( relationship.get( "k3" ), equalTo( NULL ) ); + assertThat(relationship.get("k1"), equalTo(value(1))); + assertThat(relationship.get("k2"), equalTo(value(2))); + assertThat(relationship.get("k3"), equalTo(NULL)); } - private InternalRelationship createRelationship() - { - Map props = new HashMap<>(); - props.put( "k1", value( 1 ) ); - props.put( "k2", value( 2 ) ); + private InternalRelationship createRelationship() { + Map props = new HashMap<>(); + props.put("k1", value(1)); + props.put("k2", value(2)); - return new InternalRelationship(1L, 0L, 1L, "T", props ); + return new InternalRelationship(1L, 0L, 1L, "T", props); } - } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalResultTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalResultTest.java index 658a24f2fd..1ab30926d1 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalResultTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalResultTest.java @@ -18,13 +18,29 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Records.column; +import static org.neo4j.driver.Values.ofString; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.Result; @@ -44,345 +60,301 @@ import org.neo4j.driver.internal.value.NullValue; import org.neo4j.driver.util.Pair; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Records.column; -import static org.neo4j.driver.Values.ofString; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; - -class InternalResultTest -{ +class InternalResultTest { @Test - void iterationShouldWorksAsExpected() - { + void iterationShouldWorksAsExpected() { // GIVEN - Result result = createResult( 3 ); + Result result = createResult(3); // WHEN - assertTrue( result.hasNext() ); - assertThat( values( result.next() ), equalTo( asList( value( "v1-1" ), value( "v2-1" ) ) ) ); + assertTrue(result.hasNext()); + assertThat(values(result.next()), equalTo(asList(value("v1-1"), value("v2-1")))); - assertTrue( result.hasNext() ); - assertThat( values( result.next() ), equalTo( asList( value( "v1-2" ), value( "v2-2" ) ) ) ); + assertTrue(result.hasNext()); + assertThat(values(result.next()), equalTo(asList(value("v1-2"), value("v2-2")))); - assertTrue( result.hasNext() ); //1 -> 2 + assertTrue(result.hasNext()); // 1 -> 2 // THEN - assertThat( values( result.next() ), equalTo( asList( value( "v1-3" ), value( "v2-3" ) ) ) ); - assertFalse( result.hasNext() ); + assertThat(values(result.next()), equalTo(asList(value("v1-3"), value("v2-3")))); + assertFalse(result.hasNext()); - assertThrows( NoSuchRecordException.class, result::next ); + assertThrows(NoSuchRecordException.class, result::next); } @Test - void firstOfFieldNameShouldWorkAsExpected() - { + void firstOfFieldNameShouldWorkAsExpected() { // GIVEN - Result result = createResult( 3 ); + Result result = createResult(3); // THEN - assertThat( result.next().get( "k1" ), equalTo( value( "v1-1" ) ) ); - assertTrue( result.hasNext() ); + assertThat(result.next().get("k1"), equalTo(value("v1-1"))); + assertTrue(result.hasNext()); } @Test - void firstOfFieldIndexShouldWorkAsExpected() - { + void firstOfFieldIndexShouldWorkAsExpected() { // GIVEN - Result result = createResult( 3 ); + Result result = createResult(3); // THEN - assertThat( result.next().get( 0 ), equalTo( value( "v1-1" ) ) ); - assertTrue( result.hasNext() ); + assertThat(result.next().get(0), equalTo(value("v1-1"))); + assertTrue(result.hasNext()); } @Test - void singlePastFirstShouldFail() - { + void singlePastFirstShouldFail() { // GIVEN - Result result = createResult( 2 ); + Result result = createResult(2); result.next(); result.next(); // THEN - assertThrows( NoSuchRecordException.class, result::single ); + assertThrows(NoSuchRecordException.class, result::single); } @Test - void singleNoneShouldFail() - { + void singleNoneShouldFail() { // GIVEN - Result result = createResult( 0 ); + Result result = createResult(0); // THEN - assertThrows( NoSuchRecordException.class, result::single ); + assertThrows(NoSuchRecordException.class, result::single); } @Test - void singleWhenMoreThanOneShouldFail() - { + void singleWhenMoreThanOneShouldFail() { // GIVEN - Result result = createResult( 2 ); + Result result = createResult(2); // THEN - assertThrows( NoSuchRecordException.class, result::single ); + assertThrows(NoSuchRecordException.class, result::single); } @Test - void singleOfFieldNameShouldWorkAsExpected() - { + void singleOfFieldNameShouldWorkAsExpected() { // GIVEN - Result result = createResult( 1 ); + Result result = createResult(1); // THEN - assertThat( result.single().get( "k1" ), equalTo( value( "v1-1" ) ) ); - assertFalse( result.hasNext() ); + assertThat(result.single().get("k1"), equalTo(value("v1-1"))); + assertFalse(result.hasNext()); } @Test - void singleOfFieldIndexShouldWorkAsExpected() - { + void singleOfFieldIndexShouldWorkAsExpected() { // GIVEN - Result result = createResult( 1 ); + Result result = createResult(1); // THEN - assertThat( result.single().get( 0 ), equalTo( value( "v1-1" ) ) ); - assertFalse( result.hasNext() ); + assertThat(result.single().get(0), equalTo(value("v1-1"))); + assertFalse(result.hasNext()); } @Test - void singleShouldWorkAsExpected() - { - assertNotNull( createResult( 1 ).single() ); + void singleShouldWorkAsExpected() { + assertNotNull(createResult(1).single()); } @Test - void singleShouldThrowOnBigResult() - { - assertThrows( NoSuchRecordException.class, () -> createResult( 42 ).single() ); + void singleShouldThrowOnBigResult() { + assertThrows(NoSuchRecordException.class, () -> createResult(42).single()); } @Test - void singleShouldThrowOnEmptyResult() - { - assertThrows( NoSuchRecordException.class, () -> createResult( 0 ).single() ); + void singleShouldThrowOnEmptyResult() { + assertThrows(NoSuchRecordException.class, () -> createResult(0).single()); } @Test - void singleShouldThrowOnConsumedResult() - { - assertThrows( ResultConsumedException.class, () -> - { - Result result = createResult( 2 ); + void singleShouldThrowOnConsumedResult() { + assertThrows(ResultConsumedException.class, () -> { + Result result = createResult(2); result.consume(); result.single(); - } ); + }); } @Test - void shouldConsumeTwice() - { + void shouldConsumeTwice() { // GIVEN - Result result = createResult( 2 ); + Result result = createResult(2); result.consume(); // WHEN result.consume(); // THEN - assertThrows( ResultConsumedException.class, result::hasNext ); + assertThrows(ResultConsumedException.class, result::hasNext); } @Test - void shouldList() - { + void shouldList() { // GIVEN - Result result = createResult( 2 ); - List records = result.list( column( "k1", ofString() ) ); + Result result = createResult(2); + List records = result.list(column("k1", ofString())); // THEN - assertThat( records, equalTo( asList( "v1-1", "v1-2" ) ) ); + assertThat(records, equalTo(asList("v1-1", "v1-2"))); } @Test - void shouldListTwice() - { + void shouldListTwice() { // GIVEN - Result result = createResult( 2 ); + Result result = createResult(2); List firstList = result.list(); - assertThat( firstList.size(), equalTo( 2 ) ); + assertThat(firstList.size(), equalTo(2)); // THEN List secondList = result.list(); - assertThat( secondList.size(), equalTo( 0 ) ); + assertThat(secondList.size(), equalTo(0)); } @Test - void singleShouldNotThrowOnPartiallyConsumedResult() - { + void singleShouldNotThrowOnPartiallyConsumedResult() { // Given - Result result = createResult( 2 ); + Result result = createResult(2); result.next(); // When + Then - assertNotNull( result.single() ); + assertNotNull(result.single()); } @Test - void singleShouldConsumeIfFailing() - { - Result result = createResult( 2 ); + void singleShouldConsumeIfFailing() { + Result result = createResult(2); - assertThrows( NoSuchRecordException.class, result::single ); - assertFalse( result.hasNext() ); + assertThrows(NoSuchRecordException.class, result::single); + assertFalse(result.hasNext()); } @Test - void retainShouldWorkAsExpected() - { + void retainShouldWorkAsExpected() { // GIVEN - Result result = createResult( 3 ); + Result result = createResult(3); // WHEN List records = result.list(); // THEN - assertFalse( result.hasNext() ); - assertThat( records, hasSize( 3 ) ); + assertFalse(result.hasNext()); + assertThat(records, hasSize(3)); } @Test - void retainAndMapByKeyShouldWorkAsExpected() - { + void retainAndMapByKeyShouldWorkAsExpected() { // GIVEN - Result result = createResult( 3 ); + Result result = createResult(3); // WHEN - List records = result.list( column( "k1" ) ); + List records = result.list(column("k1")); // THEN - assertFalse( result.hasNext() ); - assertThat( records, hasSize( 3 ) ); + assertFalse(result.hasNext()); + assertThat(records, hasSize(3)); } @Test - void retainAndMapByIndexShouldWorkAsExpected() - { + void retainAndMapByIndexShouldWorkAsExpected() { // GIVEN - Result result = createResult( 3 ); + Result result = createResult(3); // WHEN - List records = result.list( column( 0 ) ); + List records = result.list(column(0)); // THEN - assertFalse( result.hasNext() ); - assertThat( records, hasSize( 3 ) ); + assertFalse(result.hasNext()); + assertThat(records, hasSize(3)); } @Test - void accessingOutOfBoundsShouldBeNull() - { + void accessingOutOfBoundsShouldBeNull() { // GIVEN - Result result = createResult( 1 ); + Result result = createResult(1); // WHEN Record record = result.single(); // THEN - assertThat( record.get( 0 ), equalTo( value( "v1-1" ) ) ); - assertThat( record.get( 1 ), equalTo( value( "v2-1" ) ) ); - assertThat( record.get( 2 ), equalTo( NullValue.NULL ) ); - assertThat( record.get( -37 ), equalTo( NullValue.NULL ) ); + assertThat(record.get(0), equalTo(value("v1-1"))); + assertThat(record.get(1), equalTo(value("v2-1"))); + assertThat(record.get(2), equalTo(NullValue.NULL)); + assertThat(record.get(-37), equalTo(NullValue.NULL)); } @Test - void accessingKeysWithoutCallingNextShouldNotFail() - { + void accessingKeysWithoutCallingNextShouldNotFail() { // GIVEN - Result result = createResult( 11 ); + Result result = createResult(11); // WHEN // not calling next or single // THEN - assertThat( result.keys(), equalTo( asList( "k1", "k2" ) ) ); + assertThat(result.keys(), equalTo(asList("k1", "k2"))); } @Test - void shouldPeekIntoTheFuture() - { + void shouldPeekIntoTheFuture() { // WHEN - Result result = createResult( 2 ); + Result result = createResult(2); // THEN - assertThat( result.peek().get( "k1" ), equalTo( value( "v1-1" ) ) ); + assertThat(result.peek().get("k1"), equalTo(value("v1-1"))); // WHEN result.next(); // THEN - assertThat( result.peek().get( "k1" ), equalTo( value( "v1-2" ) ) ); + assertThat(result.peek().get("k1"), equalTo(value("v1-2"))); // WHEN result.next(); // THEN - assertThrows( NoSuchRecordException.class, result::peek ); + assertThrows(NoSuchRecordException.class, result::peek); } @Test - void shouldNotPeekIntoTheFutureWhenResultIsEmpty() - { + void shouldNotPeekIntoTheFutureWhenResultIsEmpty() { // GIVEN - Result result = createResult( 0 ); + Result result = createResult(0); // THEN - assertThrows( NoSuchRecordException.class, result::peek ); + assertThrows(NoSuchRecordException.class, result::peek); } - private Result createResult(int numberOfRecords ) - { - RunResponseHandler runHandler = new RunResponseHandler( new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock( Connection.class ), null ); - runHandler.onSuccess( singletonMap( "fields", value( Arrays.asList( "k1", "k2" ) ) ) ); - - Query query = new Query( "" ); - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( LOCAL_DEFAULT ); - when( connection.serverVersion() ).thenReturn( anyServerVersion() ); - when( connection.protocol() ).thenReturn( BoltProtocolV43.INSTANCE ); - when( connection.serverAgent() ).thenReturn( "Neo4j/4.2.5" ); - PullAllResponseHandler pullAllHandler = - new LegacyPullAllResponseHandler( query, runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, - mock( PullResponseCompletionListener.class ) ); - - for ( int i = 1; i <= numberOfRecords; i++ ) - { - pullAllHandler.onRecord( new Value[]{value( "v1-" + i ), value( "v2-" + i )} ); + private Result createResult(int numberOfRecords) { + RunResponseHandler runHandler = new RunResponseHandler( + new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock(Connection.class), null); + runHandler.onSuccess(singletonMap("fields", value(Arrays.asList("k1", "k2")))); + + Query query = new Query(""); + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(LOCAL_DEFAULT); + when(connection.serverVersion()).thenReturn(anyServerVersion()); + when(connection.protocol()).thenReturn(BoltProtocolV43.INSTANCE); + when(connection.serverAgent()).thenReturn("Neo4j/4.2.5"); + PullAllResponseHandler pullAllHandler = new LegacyPullAllResponseHandler( + query, + runHandler, + connection, + BoltProtocolV3.METADATA_EXTRACTOR, + mock(PullResponseCompletionListener.class)); + + for (int i = 1; i <= numberOfRecords; i++) { + pullAllHandler.onRecord(new Value[] {value("v1-" + i), value("v2-" + i)}); } - pullAllHandler.onSuccess( emptyMap() ); + pullAllHandler.onSuccess(emptyMap()); - AsyncResultCursor cursor = new AsyncResultCursorImpl( null, runHandler, pullAllHandler ); - return new InternalResult( connection, new DisposableAsyncResultCursor( cursor ) ); + AsyncResultCursor cursor = new AsyncResultCursorImpl(null, runHandler, pullAllHandler); + return new InternalResult(connection, new DisposableAsyncResultCursor(cursor)); } - private List values( Record record ) - { - List result = new ArrayList<>( record.keys().size() ); - for ( Pair property : record.fields() ) - { - result.add( property.value() ); + private List values(Record record) { + List result = new ArrayList<>(record.keys().size()); + for (Pair property : record.fields()) { + result.add(property.value()); } return result; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalTransactionTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalTransactionTest.java index 186d415212..00ab04bc8e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalTransactionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalTransactionTest.java @@ -18,26 +18,6 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Stream; - -import org.neo4j.driver.Query; -import org.neo4j.driver.Result; -import org.neo4j.driver.Transaction; -import org.neo4j.driver.Value; -import org.neo4j.driver.internal.async.ConnectionContext; -import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionProvider; -import org.neo4j.driver.internal.value.IntegerValue; -import org.neo4j.driver.summary.ResultSummary; - import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -58,115 +38,119 @@ import static org.neo4j.driver.util.TestUtil.verifyRollbackTx; import static org.neo4j.driver.util.TestUtil.verifyRunAndPull; -class InternalTransactionTest -{ +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.neo4j.driver.Query; +import org.neo4j.driver.Result; +import org.neo4j.driver.Transaction; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.async.ConnectionContext; +import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionProvider; +import org.neo4j.driver.internal.value.IntegerValue; +import org.neo4j.driver.summary.ResultSummary; + +class InternalTransactionTest { private Connection connection; private Transaction tx; @BeforeEach - void setUp() - { - connection = connectionMock( BoltProtocolV4.INSTANCE ); - ConnectionProvider connectionProvider = mock( ConnectionProvider.class ); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) - .thenReturn( completedFuture( connection ) ); - InternalSession session = new InternalSession( newSession( connectionProvider ) ); + void setUp() { + connection = connectionMock(BoltProtocolV4.INSTANCE); + ConnectionProvider connectionProvider = mock(ConnectionProvider.class); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))) + .thenReturn(completedFuture(connection)); + InternalSession session = new InternalSession(newSession(connectionProvider)); tx = session.beginTransaction(); } - private static Stream> allSessionRunMethods() - { + private static Stream> allSessionRunMethods() { return Stream.of( - tx -> tx.run( "RETURN 1" ), - tx -> tx.run( "RETURN $x", parameters( "x", 1 ) ), - tx -> tx.run( "RETURN $x", singletonMap( "x", 1 ) ), - tx -> tx.run( "RETURN $x", - new InternalRecord( singletonList( "x" ), new Value[]{new IntegerValue( 1 )} ) ), - tx -> tx.run( new Query( "RETURN $x", parameters( "x", 1 ) ) ) - ); + tx -> tx.run("RETURN 1"), + tx -> tx.run("RETURN $x", parameters("x", 1)), + tx -> tx.run("RETURN $x", singletonMap("x", 1)), + tx -> tx.run("RETURN $x", new InternalRecord(singletonList("x"), new Value[] {new IntegerValue(1)})), + tx -> tx.run(new Query("RETURN $x", parameters("x", 1)))); } @ParameterizedTest - @MethodSource( "allSessionRunMethods" ) - void shouldFlushOnRun( Function runReturnOne ) - { - setupSuccessfulRunAndPull( connection ); + @MethodSource("allSessionRunMethods") + void shouldFlushOnRun(Function runReturnOne) { + setupSuccessfulRunAndPull(connection); - Result result = runReturnOne.apply( tx ); + Result result = runReturnOne.apply(tx); ResultSummary summary = result.consume(); - verifyRunAndPull( connection, summary.query().text() ); + verifyRunAndPull(connection, summary.query().text()); } @Test - void shouldCommit() - { + void shouldCommit() { tx.commit(); tx.close(); - verifyCommitTx( connection ); - assertFalse( tx.isOpen() ); + verifyCommitTx(connection); + assertFalse(tx.isOpen()); } @Test - void shouldRollbackByDefault() - { + void shouldRollbackByDefault() { tx.close(); - verifyRollbackTx( connection ); - assertFalse( tx.isOpen() ); + verifyRollbackTx(connection); + assertFalse(tx.isOpen()); } @Test - void shouldRollback() - { + void shouldRollback() { tx.rollback(); tx.close(); - verifyRollbackTx( connection ); - assertFalse( tx.isOpen() ); + verifyRollbackTx(connection); + assertFalse(tx.isOpen()); } @Test - void shouldRollbackWhenFailedRun() - { - setupFailingRun( connection, new RuntimeException( "Bang!" ) ); - assertThrows( RuntimeException.class, () -> tx.run( "RETURN 1" ) ); + void shouldRollbackWhenFailedRun() { + setupFailingRun(connection, new RuntimeException("Bang!")); + assertThrows(RuntimeException.class, () -> tx.run("RETURN 1")); tx.close(); - verify( connection ).release(); - assertFalse( tx.isOpen() ); + verify(connection).release(); + assertFalse(tx.isOpen()); } @Test - void shouldReleaseConnectionWhenFailedToCommit() - { - setupFailingCommit( connection ); - assertThrows( Exception.class, () -> tx.commit() ); + void shouldReleaseConnectionWhenFailedToCommit() { + setupFailingCommit(connection); + assertThrows(Exception.class, () -> tx.commit()); - verify( connection ).release(); - assertFalse( tx.isOpen() ); + verify(connection).release(); + assertFalse(tx.isOpen()); } @Test - void shouldReleaseConnectionWhenFailedToRollback() - { - shouldReleaseConnectionWhenFailedToAction( Transaction::rollback ); + void shouldReleaseConnectionWhenFailedToRollback() { + shouldReleaseConnectionWhenFailedToAction(Transaction::rollback); } @Test - void shouldReleaseConnectionWhenFailedToClose() - { - shouldReleaseConnectionWhenFailedToAction( Transaction::close ); + void shouldReleaseConnectionWhenFailedToClose() { + shouldReleaseConnectionWhenFailedToAction(Transaction::close); } - private void shouldReleaseConnectionWhenFailedToAction( Consumer txAction ) - { - setupFailingRollback( connection ); - assertThrows( Exception.class, () -> txAction.accept( tx ) ); + private void shouldReleaseConnectionWhenFailedToAction(Consumer txAction) { + setupFailingRollback(connection); + assertThrows(Exception.class, () -> txAction.accept(tx)); - verify( connection ).release(); - assertFalse( tx.isOpen() ); + verify(connection).release(); + assertFalse(tx.isOpen()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/SchemeTest.java b/driver/src/test/java/org/neo4j/driver/internal/SchemeTest.java index d921b08ab4..8af04f44a8 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/SchemeTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/SchemeTest.java @@ -18,95 +18,81 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullSource; -import org.junit.jupiter.params.provider.ValueSource; - import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; -class SchemeTest -{ +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; + +class SchemeTest { @ParameterizedTest - @ValueSource( strings = {"neo4j", "neo4j+s", "neo4j+ssc", "bolt", "bolt+s", "bolt+ssc"} ) - void shouldAcceptValidSchemes( String input ) - { - Scheme.validateScheme( input ); + @ValueSource(strings = {"neo4j", "neo4j+s", "neo4j+ssc", "bolt", "bolt+s", "bolt+ssc"}) + void shouldAcceptValidSchemes(String input) { + Scheme.validateScheme(input); } @ParameterizedTest - @ValueSource( strings = {"bob", "grey", "", " ", "blah"} ) - void shouldRejectInvalidSchemes( String input ) - { - IllegalArgumentException ex = - assertThrows( IllegalArgumentException.class, () -> Scheme.validateScheme( input ) ); - assertTrue( ex.getMessage().contains( "Invalid address format " + input ) ); + @ValueSource(strings = {"bob", "grey", "", " ", "blah"}) + void shouldRejectInvalidSchemes(String input) { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Scheme.validateScheme(input)); + assertTrue(ex.getMessage().contains("Invalid address format " + input)); } @ParameterizedTest @NullSource - void shouldRejectNullScheme( String input ) - { - IllegalArgumentException ex = - assertThrows( IllegalArgumentException.class, () -> Scheme.validateScheme( input ) ); - assertTrue( ex.getMessage().contains( "Scheme must not be null" ) ); + void shouldRejectNullScheme(String input) { + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> Scheme.validateScheme(input)); + assertTrue(ex.getMessage().contains("Scheme must not be null")); } @ParameterizedTest - @ValueSource( strings = {"neo4j+s", "bolt+s"} ) - void shouldAcceptValidHighTrustSchemes( String scheme ) - { - assertTrue( Scheme.isHighTrustScheme( scheme ) ); + @ValueSource(strings = {"neo4j+s", "bolt+s"}) + void shouldAcceptValidHighTrustSchemes(String scheme) { + assertTrue(Scheme.isHighTrustScheme(scheme)); } @ParameterizedTest - @ValueSource( strings = {"neo4j", "neo4j+ssc", "bolt", "bolt+ssc", "blah"} ) - void shouldRejectInvalidHighTrustSchemes( String scheme ) - { - assertFalse( Scheme.isHighTrustScheme( scheme ) ); + @ValueSource(strings = {"neo4j", "neo4j+ssc", "bolt", "bolt+ssc", "blah"}) + void shouldRejectInvalidHighTrustSchemes(String scheme) { + assertFalse(Scheme.isHighTrustScheme(scheme)); } @ParameterizedTest - @ValueSource( strings = {"neo4j+ssc", "bolt+ssc"} ) - void shouldAcceptValidLowTrustSchemes( String scheme ) - { - assertTrue( Scheme.isLowTrustScheme( scheme ) ); + @ValueSource(strings = {"neo4j+ssc", "bolt+ssc"}) + void shouldAcceptValidLowTrustSchemes(String scheme) { + assertTrue(Scheme.isLowTrustScheme(scheme)); } @ParameterizedTest - @ValueSource( strings = {"neo4j", "neo4j+s", "bolt", "bolt+s", "blah"} ) - void shouldRejectInvalidLowTrustSchemes( String scheme ) - { - assertFalse( Scheme.isLowTrustScheme( scheme ) ); + @ValueSource(strings = {"neo4j", "neo4j+s", "bolt", "bolt+s", "blah"}) + void shouldRejectInvalidLowTrustSchemes(String scheme) { + assertFalse(Scheme.isLowTrustScheme(scheme)); } @ParameterizedTest - @ValueSource( strings = {"neo4j+s", "neo4j+ssc", "bolt+s", "bolt+ssc"} ) - void shouldAcceptValidSecuritySchemes( String scheme ) - { - assertTrue( Scheme.isSecurityScheme( scheme ) ); + @ValueSource(strings = {"neo4j+s", "neo4j+ssc", "bolt+s", "bolt+ssc"}) + void shouldAcceptValidSecuritySchemes(String scheme) { + assertTrue(Scheme.isSecurityScheme(scheme)); } @ParameterizedTest - @ValueSource( strings = {"neo4j", "bolt", "blah"} ) - void shouldRejectInvalidSecuritySchemes( String scheme ) - { - assertFalse( Scheme.isSecurityScheme( scheme ) ); + @ValueSource(strings = {"neo4j", "bolt", "blah"}) + void shouldRejectInvalidSecuritySchemes(String scheme) { + assertFalse(Scheme.isSecurityScheme(scheme)); } @ParameterizedTest - @ValueSource( strings = {"neo4j", "neo4j+s", "neo4j+ssc"} ) - void shouldAcceptValidRoutingSchemes( String scheme ) - { - assertTrue( Scheme.isRoutingScheme( scheme ) ); + @ValueSource(strings = {"neo4j", "neo4j+s", "neo4j+ssc"}) + void shouldAcceptValidRoutingSchemes(String scheme) { + assertTrue(Scheme.isRoutingScheme(scheme)); } @ParameterizedTest - @ValueSource( strings = {"bolt", "bolt+s", "bolt+ssc", "blah"} ) - void shouldRejectInvalidRoutingSchemes( String scheme ) - { - assertFalse( Scheme.isRoutingScheme( scheme ) ); + @ValueSource(strings = {"bolt", "bolt+s", "bolt+ssc", "blah"}) + void shouldRejectInvalidRoutingSchemes(String scheme) { + assertFalse(Scheme.isRoutingScheme(scheme)); } -} \ No newline at end of file +} diff --git a/driver/src/test/java/org/neo4j/driver/internal/SecuritySettingsTest.java b/driver/src/test/java/org/neo4j/driver/internal/SecuritySettingsTest.java index dce4b45d95..3ae24dc61f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/SecuritySettingsTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/SecuritySettingsTest.java @@ -18,310 +18,301 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.platform.commons.support.ReflectionSupport; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.internal.RevocationStrategy.NO_CHECKS; +import static org.neo4j.driver.internal.RevocationStrategy.STRICT; +import static org.neo4j.driver.internal.RevocationStrategy.VERIFY_IF_PRESENT; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.stream.Stream; - +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.platform.commons.support.ReflectionSupport; import org.neo4j.driver.Config; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.util.TestUtil; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.internal.RevocationStrategy.NO_CHECKS; -import static org.neo4j.driver.internal.RevocationStrategy.STRICT; -import static org.neo4j.driver.internal.RevocationStrategy.VERIFY_IF_PRESENT; - -class SecuritySettingsTest -{ - private static Stream selfSignedSchemes() - { - return Stream.of( "bolt+ssc", "neo4j+ssc" ); +class SecuritySettingsTest { + private static Stream selfSignedSchemes() { + return Stream.of("bolt+ssc", "neo4j+ssc"); } - private static Stream systemCertSchemes() - { - return Stream.of( "neo4j+s", "bolt+s" ); + private static Stream systemCertSchemes() { + return Stream.of("neo4j+s", "bolt+s"); } - private static Stream unencryptedSchemes() - { - return Stream.of( "neo4j", "bolt" ); + private static Stream unencryptedSchemes() { + return Stream.of("neo4j", "bolt"); } - private static Stream allSecureSchemes() - { - return Stream.concat( selfSignedSchemes(), systemCertSchemes() ); + private static Stream allSecureSchemes() { + return Stream.concat(selfSignedSchemes(), systemCertSchemes()); } @ParameterizedTest - @MethodSource( "allSecureSchemes" ) - void testEncryptionSchemeEnablesEncryption( String scheme ) - { + @MethodSource("allSecureSchemes") + void testEncryptionSchemeEnablesEncryption(String scheme) { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder().build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertTrue( securityPlan.requiresEncryption() ); + assertTrue(securityPlan.requiresEncryption()); } @ParameterizedTest - @MethodSource( "systemCertSchemes" ) - void testSystemCertCompatibleConfiguration( String scheme ) throws Exception - { + @MethodSource("systemCertSchemes") + void testSystemCertCompatibleConfiguration(String scheme) throws Exception { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder().build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertTrue( securityPlan.requiresEncryption() ); - assertTrue( securityPlan.requiresHostnameVerification() ); - assertEquals( NO_CHECKS, securityPlan.revocationStrategy() ); + assertTrue(securityPlan.requiresEncryption()); + assertTrue(securityPlan.requiresHostnameVerification()); + assertEquals(NO_CHECKS, securityPlan.revocationStrategy()); } @ParameterizedTest - @MethodSource( "selfSignedSchemes" ) - void testSelfSignedCertConfigDisablesHostnameVerification( String scheme ) throws Exception - { + @MethodSource("selfSignedSchemes") + void testSelfSignedCertConfigDisablesHostnameVerification(String scheme) throws Exception { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder().build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertTrue( securityPlan.requiresEncryption() ); - assertFalse( securityPlan.requiresHostnameVerification() ); + assertTrue(securityPlan.requiresEncryption()); + assertFalse(securityPlan.requiresHostnameVerification()); } @ParameterizedTest - @MethodSource( "allSecureSchemes" ) - void testThrowsOnUserCustomizedEncryption( String scheme ) - { - SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() - .withEncryption() - .build(); + @MethodSource("allSecureSchemes") + void testThrowsOnUserCustomizedEncryption(String scheme) { + SecuritySettings securitySettings = + new SecuritySettings.SecuritySettingsBuilder().withEncryption().build(); - ClientException ex = - assertThrows( ClientException.class, - () -> securitySettings.createSecurityPlan( scheme ) ); + ClientException ex = assertThrows(ClientException.class, () -> securitySettings.createSecurityPlan(scheme)); - assertTrue( ex.getMessage().contains( String.format( "Scheme %s is not configurable with manual encryption and trust settings", scheme ) )); + assertTrue(ex.getMessage() + .contains(String.format( + "Scheme %s is not configurable with manual encryption and trust settings", scheme))); } @ParameterizedTest - @MethodSource( "allSecureSchemes" ) - void testThrowsOnUserCustomizedTrustConfiguration( String scheme ) - { + @MethodSource("allSecureSchemes") + void testThrowsOnUserCustomizedTrustConfiguration(String scheme) { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() - .withTrustStrategy( Config.TrustStrategy.trustAllCertificates() ) + .withTrustStrategy(Config.TrustStrategy.trustAllCertificates()) .build(); - ClientException ex = - assertThrows( ClientException.class, - () -> securitySettings.createSecurityPlan( scheme ) ); + ClientException ex = assertThrows(ClientException.class, () -> securitySettings.createSecurityPlan(scheme)); - assertTrue( ex.getMessage().contains( String.format( "Scheme %s is not configurable with manual encryption and trust settings", scheme ) )); + assertTrue(ex.getMessage() + .contains(String.format( + "Scheme %s is not configurable with manual encryption and trust settings", scheme))); } @ParameterizedTest - @MethodSource( "allSecureSchemes" ) - void testThrowsOnUserCustomizedTrustConfigurationAndEncryption( String scheme ) - { + @MethodSource("allSecureSchemes") + void testThrowsOnUserCustomizedTrustConfigurationAndEncryption(String scheme) { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() - .withTrustStrategy( Config.TrustStrategy.trustSystemCertificates() ) + .withTrustStrategy(Config.TrustStrategy.trustSystemCertificates()) .withEncryption() .build(); - ClientException ex = - assertThrows( ClientException.class, - () -> securitySettings.createSecurityPlan( scheme ) ); + ClientException ex = assertThrows(ClientException.class, () -> securitySettings.createSecurityPlan(scheme)); - assertTrue( ex.getMessage().contains( String.format( "Scheme %s is not configurable with manual encryption and trust settings", scheme ) )); + assertTrue(ex.getMessage() + .contains(String.format( + "Scheme %s is not configurable with manual encryption and trust settings", scheme))); } @ParameterizedTest - @MethodSource( "unencryptedSchemes" ) - void testNoEncryption( String scheme ) - { + @MethodSource("unencryptedSchemes") + void testNoEncryption(String scheme) { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder().build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertFalse( securityPlan.requiresEncryption() ); + assertFalse(securityPlan.requiresEncryption()); } @ParameterizedTest - @MethodSource( "unencryptedSchemes" ) - void testConfiguredEncryption( String scheme ) - { - SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() - .withEncryption().build(); + @MethodSource("unencryptedSchemes") + void testConfiguredEncryption(String scheme) { + SecuritySettings securitySettings = + new SecuritySettings.SecuritySettingsBuilder().withEncryption().build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertTrue( securityPlan.requiresEncryption() ); + assertTrue(securityPlan.requiresEncryption()); } @ParameterizedTest - @MethodSource( "unencryptedSchemes" ) - void testConfiguredAllCertificates( String scheme) - { + @MethodSource("unencryptedSchemes") + void testConfiguredAllCertificates(String scheme) { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() .withEncryption() - .withTrustStrategy( Config.TrustStrategy.trustAllCertificates() ) + .withTrustStrategy(Config.TrustStrategy.trustAllCertificates()) .build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertTrue( securityPlan.requiresEncryption() ); + assertTrue(securityPlan.requiresEncryption()); } @ParameterizedTest - @MethodSource( "unencryptedSchemes" ) - void testConfigureStrictRevocationChecking( String scheme ) - { + @MethodSource("unencryptedSchemes") + void testConfigureStrictRevocationChecking(String scheme) { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() - .withTrustStrategy( Config.TrustStrategy.trustSystemCertificates().withStrictRevocationChecks() ) + .withTrustStrategy( + Config.TrustStrategy.trustSystemCertificates().withStrictRevocationChecks()) .withEncryption() .build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertEquals( STRICT, securityPlan.revocationStrategy() ); + assertEquals(STRICT, securityPlan.revocationStrategy()); } @ParameterizedTest - @MethodSource( "unencryptedSchemes" ) - void testConfigureVerifyIfPresentRevocationChecking( String scheme ) - { + @MethodSource("unencryptedSchemes") + void testConfigureVerifyIfPresentRevocationChecking(String scheme) { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() - .withTrustStrategy( Config.TrustStrategy.trustSystemCertificates().withVerifyIfPresentRevocationChecks() ) + .withTrustStrategy( + Config.TrustStrategy.trustSystemCertificates().withVerifyIfPresentRevocationChecks()) .withEncryption() .build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertEquals( VERIFY_IF_PRESENT, securityPlan.revocationStrategy() ); + assertEquals(VERIFY_IF_PRESENT, securityPlan.revocationStrategy()); } @ParameterizedTest - @MethodSource( "unencryptedSchemes" ) - void testRevocationCheckingDisabledByDefault( String scheme ) - { + @MethodSource("unencryptedSchemes") + void testRevocationCheckingDisabledByDefault(String scheme) { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() - .withTrustStrategy( Config.TrustStrategy.trustSystemCertificates() ) + .withTrustStrategy(Config.TrustStrategy.trustSystemCertificates()) .withEncryption() .build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( scheme ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(scheme); - assertEquals( NO_CHECKS, securityPlan.revocationStrategy() ); + assertEquals(NO_CHECKS, securityPlan.revocationStrategy()); } @Nested - class SerializationTests - { - Method isCustomized = ReflectionSupport.findMethod( SecuritySettings.class, "isCustomized" ).orElseThrow( - () -> new RuntimeException( "This test requires isCustomized to be present." ) ); - - boolean isCustomized( SecuritySettings securitySettings ) - { - isCustomized.setAccessible( true ); - try - { - return (boolean) isCustomized.invoke( securitySettings ); - } - catch ( IllegalAccessException | InvocationTargetException e ) - { - throw new RuntimeException( e ); + class SerializationTests { + Method isCustomized = ReflectionSupport.findMethod(SecuritySettings.class, "isCustomized") + .orElseThrow(() -> new RuntimeException("This test requires isCustomized to be present.")); + + boolean isCustomized(SecuritySettings securitySettings) { + isCustomized.setAccessible(true); + try { + return (boolean) isCustomized.invoke(securitySettings); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); } } @Test - void defaultSettingsShouldNotBeCustomizedWhenReadBack() throws IOException, ClassNotFoundException - { + void defaultSettingsShouldNotBeCustomizedWhenReadBack() throws IOException, ClassNotFoundException { SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder().build(); - assertFalse( isCustomized( securitySettings ) ); + assertFalse(isCustomized(securitySettings)); - SecuritySettings verify = TestUtil.serializeAndReadBack( securitySettings, SecuritySettings.class ); + SecuritySettings verify = TestUtil.serializeAndReadBack(securitySettings, SecuritySettings.class); - assertFalse( isCustomized( verify ) ); + assertFalse(isCustomized(verify)); } @Test - void defaultsShouldBeCheckCorrect() throws IOException, ClassNotFoundException - { - SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder().withoutEncryption().withTrustStrategy( - Config.TrustStrategy.trustSystemCertificates() ).build(); + void defaultsShouldBeCheckCorrect() throws IOException, ClassNotFoundException { + SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() + .withoutEncryption() + .withTrustStrategy(Config.TrustStrategy.trustSystemCertificates()) + .build(); - // The settings are still equivalent to the defaults, even if the builder has been used. It is not customized. - assertFalse( isCustomized( securitySettings ) ); + // The settings are still equivalent to the defaults, even if the builder has been used. It is not + // customized. + assertFalse(isCustomized(securitySettings)); - SecuritySettings verify = TestUtil.serializeAndReadBack( securitySettings, SecuritySettings.class ); + SecuritySettings verify = TestUtil.serializeAndReadBack(securitySettings, SecuritySettings.class); - assertFalse( isCustomized( verify ) ); + assertFalse(isCustomized(verify)); } @Test - void shouldReadBackChangedEncryption() throws IOException, ClassNotFoundException - { - SecuritySettings securitySettings = - new SecuritySettings.SecuritySettingsBuilder().withEncryption().withTrustStrategy( Config.TrustStrategy.trustSystemCertificates() ).build(); + void shouldReadBackChangedEncryption() throws IOException, ClassNotFoundException { + SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() + .withEncryption() + .withTrustStrategy(Config.TrustStrategy.trustSystemCertificates()) + .build(); - assertTrue( isCustomized( securitySettings ) ); - assertTrue( securitySettings.encrypted() ); + assertTrue(isCustomized(securitySettings)); + assertTrue(securitySettings.encrypted()); - SecuritySettings verify = TestUtil.serializeAndReadBack( securitySettings, SecuritySettings.class ); + SecuritySettings verify = TestUtil.serializeAndReadBack(securitySettings, SecuritySettings.class); - assertTrue( isCustomized( verify ) ); - assertTrue( securitySettings.encrypted() ); + assertTrue(isCustomized(verify)); + assertTrue(securitySettings.encrypted()); } @Test - void shouldReadBackChangedStrategey() throws IOException, ClassNotFoundException - { - SecuritySettings securitySettings = - new SecuritySettings.SecuritySettingsBuilder().withoutEncryption().withTrustStrategy( Config.TrustStrategy.trustAllCertificates() ).build(); - - // The settings are still equivalent to the defaults, even if the builder has been used. It is not customized. - assertTrue( isCustomized( securitySettings ) ); - assertFalse( securitySettings.encrypted() ); - assertEquals( Config.TrustStrategy.trustAllCertificates().strategy(), securitySettings.trustStrategy().strategy() ); - - SecuritySettings verify = TestUtil.serializeAndReadBack( securitySettings, SecuritySettings.class ); - - assertTrue( isCustomized( verify ) ); - assertFalse( securitySettings.encrypted() ); - assertEquals( Config.TrustStrategy.trustAllCertificates().strategy(), securitySettings.trustStrategy().strategy() ); + void shouldReadBackChangedStrategey() throws IOException, ClassNotFoundException { + SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() + .withoutEncryption() + .withTrustStrategy(Config.TrustStrategy.trustAllCertificates()) + .build(); + + // The settings are still equivalent to the defaults, even if the builder has been used. It is not + // customized. + assertTrue(isCustomized(securitySettings)); + assertFalse(securitySettings.encrypted()); + assertEquals( + Config.TrustStrategy.trustAllCertificates().strategy(), + securitySettings.trustStrategy().strategy()); + + SecuritySettings verify = TestUtil.serializeAndReadBack(securitySettings, SecuritySettings.class); + + assertTrue(isCustomized(verify)); + assertFalse(securitySettings.encrypted()); + assertEquals( + Config.TrustStrategy.trustAllCertificates().strategy(), + securitySettings.trustStrategy().strategy()); } @Test - void shouldReadBackChangedCertFile() throws IOException, ClassNotFoundException - { - SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder().withoutEncryption().withTrustStrategy( - Config.TrustStrategy.trustCustomCertificateSignedBy( new File( "some.cert" ) ) ).build(); - - // The settings are still equivalent to the defaults, even if the builder has been used. It is not customized. - assertTrue( isCustomized( securitySettings ) ); - assertFalse( securitySettings.encrypted() ); - assertEquals( Config.TrustStrategy.trustCustomCertificateSignedBy( new File( "some.cert" ) ).strategy(), - securitySettings.trustStrategy().strategy() ); - - SecuritySettings verify = TestUtil.serializeAndReadBack( securitySettings, SecuritySettings.class ); - - assertTrue( isCustomized( verify ) ); - assertFalse( securitySettings.encrypted() ); - assertEquals( Config.TrustStrategy.trustCustomCertificateSignedBy( new File( "some.cert" ) ).strategy(), - securitySettings.trustStrategy().strategy() ); + void shouldReadBackChangedCertFile() throws IOException, ClassNotFoundException { + SecuritySettings securitySettings = new SecuritySettings.SecuritySettingsBuilder() + .withoutEncryption() + .withTrustStrategy(Config.TrustStrategy.trustCustomCertificateSignedBy(new File("some.cert"))) + .build(); + + // The settings are still equivalent to the defaults, even if the builder has been used. It is not + // customized. + assertTrue(isCustomized(securitySettings)); + assertFalse(securitySettings.encrypted()); + assertEquals( + Config.TrustStrategy.trustCustomCertificateSignedBy(new File("some.cert")) + .strategy(), + securitySettings.trustStrategy().strategy()); + + SecuritySettings verify = TestUtil.serializeAndReadBack(securitySettings, SecuritySettings.class); + + assertTrue(isCustomized(verify)); + assertFalse(securitySettings.encrypted()); + assertEquals( + Config.TrustStrategy.trustCustomCertificateSignedBy(new File("some.cert")) + .strategy(), + securitySettings.trustStrategy().strategy()); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/SelfContainedNodeTest.java b/driver/src/test/java/org/neo4j/driver/internal/SelfContainedNodeTest.java index eadb3a3c66..d5d5652d97 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/SelfContainedNodeTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/SelfContainedNodeTest.java @@ -18,69 +18,63 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import org.neo4j.driver.internal.util.Iterables; -import org.neo4j.driver.Values; -import org.neo4j.driver.types.Node; - import static java.util.Collections.singletonList; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; import static org.neo4j.driver.Values.ofValue; import static org.neo4j.driver.Values.parameters; -class SelfContainedNodeTest -{ - private Node adamTheNode() - { - return new InternalNode( 1, singletonList( "Person" ), - parameters( "name", Values.value( "Adam" ) ).asMap( ofValue()) ); +import java.util.List; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Values; +import org.neo4j.driver.internal.util.Iterables; +import org.neo4j.driver.types.Node; + +class SelfContainedNodeTest { + private Node adamTheNode() { + return new InternalNode( + 1, + singletonList("Person"), + parameters("name", Values.value("Adam")).asMap(ofValue())); } @Test - void testIdentity() - { + void testIdentity() { // Given Node node = adamTheNode(); // Then - assertThat( node.id(), equalTo( 1l ) ); + assertThat(node.id(), equalTo(1l)); } @Test - void testLabels() - { + void testLabels() { // Given Node node = adamTheNode(); // Then - List labels = Iterables.asList( node.labels() ); - assertThat( labels.size(), equalTo( 1 ) ); - assertThat( labels.contains( "Person" ), equalTo( true ) ); + List labels = Iterables.asList(node.labels()); + assertThat(labels.size(), equalTo(1)); + assertThat(labels.contains("Person"), equalTo(true)); } @Test - void testKeys() - { + void testKeys() { // Given Node node = adamTheNode(); // Then - List keys = Iterables.asList( node.keys() ); - assertThat( keys.size(), equalTo( 1 ) ); - assertThat( keys.contains( "name" ), equalTo( true ) ); + List keys = Iterables.asList(node.keys()); + assertThat(keys.size(), equalTo(1)); + assertThat(keys.contains("name"), equalTo(true)); } @Test - void testValue() - { + void testValue() { // Given Node node = adamTheNode(); // Then - assertThat( node.get( "name" ).asString(), equalTo( "Adam" ) ); + assertThat(node.get("name").asString(), equalTo("Adam")); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/SessionFactoryImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/SessionFactoryImplTest.java index 057a0d9f71..8fe6c36812 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/SessionFactoryImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/SessionFactoryImplTest.java @@ -18,8 +18,13 @@ */ package org.neo4j.driver.internal; -import org.junit.jupiter.api.Test; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import org.junit.jupiter.api.Test; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Config; import org.neo4j.driver.internal.async.LeakLoggingNetworkSession; @@ -27,42 +32,39 @@ import org.neo4j.driver.internal.spi.ConnectionProvider; import org.neo4j.driver.internal.util.FixedRetryLogic; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; - -class SessionFactoryImplTest -{ +class SessionFactoryImplTest { @Test - void createsNetworkSessions() - { - Config config = Config.builder().withLogging( DEV_NULL_LOGGING ).build(); - SessionFactory factory = newSessionFactory( config ); + void createsNetworkSessions() { + Config config = Config.builder().withLogging(DEV_NULL_LOGGING).build(); + SessionFactory factory = newSessionFactory(config); - NetworkSession readSession = factory.newInstance( builder().withDefaultAccessMode( AccessMode.READ ).build() ); - assertThat( readSession, instanceOf( NetworkSession.class ) ); + NetworkSession readSession = factory.newInstance( + builder().withDefaultAccessMode(AccessMode.READ).build()); + assertThat(readSession, instanceOf(NetworkSession.class)); - NetworkSession writeSession = factory.newInstance( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ); - assertThat( writeSession, instanceOf( NetworkSession.class ) ); + NetworkSession writeSession = factory.newInstance( + builder().withDefaultAccessMode(AccessMode.WRITE).build()); + assertThat(writeSession, instanceOf(NetworkSession.class)); } @Test - void createsLeakLoggingNetworkSessions() - { - Config config = Config.builder().withLogging( DEV_NULL_LOGGING ).withLeakedSessionsLogging().build(); - SessionFactory factory = newSessionFactory( config ); + void createsLeakLoggingNetworkSessions() { + Config config = Config.builder() + .withLogging(DEV_NULL_LOGGING) + .withLeakedSessionsLogging() + .build(); + SessionFactory factory = newSessionFactory(config); - NetworkSession readSession = factory.newInstance( builder().withDefaultAccessMode( AccessMode.READ ).build() ); - assertThat( readSession, instanceOf( LeakLoggingNetworkSession.class ) ); + NetworkSession readSession = factory.newInstance( + builder().withDefaultAccessMode(AccessMode.READ).build()); + assertThat(readSession, instanceOf(LeakLoggingNetworkSession.class)); - NetworkSession writeSession = factory.newInstance( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ); - assertThat( writeSession, instanceOf( LeakLoggingNetworkSession.class ) ); + NetworkSession writeSession = factory.newInstance( + builder().withDefaultAccessMode(AccessMode.WRITE).build()); + assertThat(writeSession, instanceOf(LeakLoggingNetworkSession.class)); } - private static SessionFactory newSessionFactory( Config config ) - { - return new SessionFactoryImpl( mock( ConnectionProvider.class ), new FixedRetryLogic( 0 ), config ); + private static SessionFactory newSessionFactory(Config config) { + return new SessionFactoryImpl(mock(ConnectionProvider.class), new FixedRetryLogic(0), config); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/ValuesTest.java b/driver/src/test/java/org/neo4j/driver/internal/ValuesTest.java index 6932e8f88e..ad6fd7d703 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/ValuesTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/ValuesTest.java @@ -18,8 +18,31 @@ */ package org.neo4j.driver.internal; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.Values.isoDuration; +import static org.neo4j.driver.Values.ofDouble; +import static org.neo4j.driver.Values.ofFloat; +import static org.neo4j.driver.Values.ofInteger; +import static org.neo4j.driver.Values.ofList; +import static org.neo4j.driver.Values.ofLong; +import static org.neo4j.driver.Values.ofMap; +import static org.neo4j.driver.Values.ofNumber; +import static org.neo4j.driver.Values.ofObject; +import static org.neo4j.driver.Values.ofString; +import static org.neo4j.driver.Values.ofToString; +import static org.neo4j.driver.Values.point; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.Values.values; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; import java.time.Duration; import java.time.LocalDate; @@ -38,7 +61,11 @@ import java.util.Map; import java.util.Set; import java.util.stream.Stream; - +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.Values; +import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.value.DateTimeValue; import org.neo4j.driver.internal.value.DateValue; import org.neo4j.driver.internal.value.DurationValue; @@ -50,551 +77,460 @@ import org.neo4j.driver.internal.value.PathValue; import org.neo4j.driver.internal.value.RelationshipValue; import org.neo4j.driver.internal.value.TimeValue; -import org.neo4j.driver.Value; -import org.neo4j.driver.Values; -import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.types.IsoDuration; import org.neo4j.driver.types.Node; import org.neo4j.driver.types.Path; import org.neo4j.driver.types.Point; import org.neo4j.driver.types.Relationship; -import static java.util.Arrays.asList; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.collection.IsIterableContainingInOrder.contains; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -import static org.neo4j.driver.Values.isoDuration; -import static org.neo4j.driver.Values.ofDouble; -import static org.neo4j.driver.Values.ofFloat; -import static org.neo4j.driver.Values.ofInteger; -import static org.neo4j.driver.Values.ofList; -import static org.neo4j.driver.Values.ofLong; -import static org.neo4j.driver.Values.ofMap; -import static org.neo4j.driver.Values.ofNumber; -import static org.neo4j.driver.Values.ofObject; -import static org.neo4j.driver.Values.ofString; -import static org.neo4j.driver.Values.ofToString; -import static org.neo4j.driver.Values.point; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.Values.values; - -class ValuesTest -{ +class ValuesTest { @Test - void shouldConvertPrimitiveArrays() - { - assertThat( value( new short[]{1, 2, 3} ), - equalTo( new ListValue( values( 1, 2, 3 ) ) ) ); + void shouldConvertPrimitiveArrays() { + assertThat(value(new short[] {1, 2, 3}), equalTo(new ListValue(values(1, 2, 3)))); - assertThat( value( new int[]{1, 2, 3} ), - equalTo( new ListValue( values( 1, 2, 3 ) ) ) ); + assertThat(value(new int[] {1, 2, 3}), equalTo(new ListValue(values(1, 2, 3)))); - assertThat( value( new long[]{1, 2, 3} ), - equalTo( new ListValue( values( 1, 2, 3 ) ) ) ); + assertThat(value(new long[] {1, 2, 3}), equalTo(new ListValue(values(1, 2, 3)))); - assertThat( value( new float[]{1.1f, 2.2f, 3.3f} ), - equalTo( new ListValue( values( 1.1f, 2.2f, 3.3f ) ) ) ); + assertThat(value(new float[] {1.1f, 2.2f, 3.3f}), equalTo(new ListValue(values(1.1f, 2.2f, 3.3f)))); - assertThat( value( new double[]{1.1, 2.2, 3.3} ), - equalTo( new ListValue( values( 1.1, 2.2, 3.3 ) ) ) ); + assertThat(value(new double[] {1.1, 2.2, 3.3}), equalTo(new ListValue(values(1.1, 2.2, 3.3)))); - assertThat( value( new boolean[]{true, false, true} ), - equalTo( new ListValue( values( true, false, true ) ) ) ); + assertThat(value(new boolean[] {true, false, true}), equalTo(new ListValue(values(true, false, true)))); - assertThat( value( new char[]{'a', 'b', 'c'} ), - equalTo( new ListValue( values( 'a', 'b', 'c' ) ) ) ); + assertThat(value(new char[] {'a', 'b', 'c'}), equalTo(new ListValue(values('a', 'b', 'c')))); - assertThat( value( new String[]{"a", "b", "c"} ), - equalTo( new ListValue( values( "a", "b", "c" ) ) ) ); + assertThat(value(new String[] {"a", "b", "c"}), equalTo(new ListValue(values("a", "b", "c")))); } @Test - void shouldConvertPrimitiveArraysFromObject() - { - assertThat( value( (Object) new short[]{1, 2, 3} ), - equalTo( new ListValue( values( 1, 2, 3 ) ) ) ); + void shouldConvertPrimitiveArraysFromObject() { + assertThat(value((Object) new short[] {1, 2, 3}), equalTo(new ListValue(values(1, 2, 3)))); - assertThat( value( (Object) new int[]{1, 2, 3} ), - equalTo( new ListValue( values( 1, 2, 3 ) ) ) ); + assertThat(value((Object) new int[] {1, 2, 3}), equalTo(new ListValue(values(1, 2, 3)))); - assertThat( value( (Object) new long[]{1, 2, 3} ), - equalTo( new ListValue( values( 1, 2, 3 ) ) ) ); + assertThat(value((Object) new long[] {1, 2, 3}), equalTo(new ListValue(values(1, 2, 3)))); - assertThat( value( (Object) new float[]{1.1f, 2.2f, 3.3f} ), - equalTo( new ListValue( values( 1.1f, 2.2f, 3.3f ) ) ) ); + assertThat(value((Object) new float[] {1.1f, 2.2f, 3.3f}), equalTo(new ListValue(values(1.1f, 2.2f, 3.3f)))); - assertThat( value( (Object) new double[]{1.1, 2.2, 3.3} ), - equalTo( new ListValue( values( 1.1, 2.2, 3.3 ) ) ) ); + assertThat(value((Object) new double[] {1.1, 2.2, 3.3}), equalTo(new ListValue(values(1.1, 2.2, 3.3)))); - assertThat( value( (Object) new boolean[]{true, false, true} ), - equalTo( new ListValue( values( true, false, true ) ) ) ); + assertThat( + value((Object) new boolean[] {true, false, true}), equalTo(new ListValue(values(true, false, true)))); - assertThat( value( (Object) new char[]{'a', 'b', 'c'} ), - equalTo( new ListValue( values( 'a', 'b', 'c' ) ) ) ); + assertThat(value((Object) new char[] {'a', 'b', 'c'}), equalTo(new ListValue(values('a', 'b', 'c')))); - assertThat( value( (Object) new String[]{"a", "b", "c"} ), - equalTo( new ListValue( values( "a", "b", "c" ) ) ) ); + assertThat(value((Object) new String[] {"a", "b", "c"}), equalTo(new ListValue(values("a", "b", "c")))); } @Test - void shouldComplainAboutStrangeTypes() - { - ClientException e = assertThrows( ClientException.class, () -> value( new Object() ) ); - assertEquals( "Unable to convert java.lang.Object to Neo4j Value.", e.getMessage() ); + void shouldComplainAboutStrangeTypes() { + ClientException e = assertThrows(ClientException.class, () -> value(new Object())); + assertEquals("Unable to convert java.lang.Object to Neo4j Value.", e.getMessage()); } @Test - void equalityRules() - { - assertEquals( value( 1 ), value( 1 ) ); - assertEquals( value( Long.MAX_VALUE ), value( Long.MAX_VALUE ) ); - assertEquals( value( Long.MIN_VALUE ), value( Long.MIN_VALUE ) ); - assertNotEquals( value( 1 ), value( 2 ) ); + void equalityRules() { + assertEquals(value(1), value(1)); + assertEquals(value(Long.MAX_VALUE), value(Long.MAX_VALUE)); + assertEquals(value(Long.MIN_VALUE), value(Long.MIN_VALUE)); + assertNotEquals(value(1), value(2)); - assertEquals( value( 1.1337 ), value( 1.1337 ) ); - assertEquals( value( Double.MAX_VALUE ), value( Double.MAX_VALUE ) ); - assertEquals( value( Double.MIN_VALUE ), value( Double.MIN_VALUE ) ); + assertEquals(value(1.1337), value(1.1337)); + assertEquals(value(Double.MAX_VALUE), value(Double.MAX_VALUE)); + assertEquals(value(Double.MIN_VALUE), value(Double.MIN_VALUE)); - assertEquals( value( true ), value( true ) ); - assertEquals( value( false ), value( false ) ); - assertNotEquals( value( true ), value( false ) ); + assertEquals(value(true), value(true)); + assertEquals(value(false), value(false)); + assertNotEquals(value(true), value(false)); - assertEquals( value( "Hello" ), value( "Hello" ) ); - assertEquals( value( "This åäö string ?? contains strange Ü" ), - value( "This åäö string ?? contains strange Ü" ) ); - assertEquals( value( "" ), value( "" ) ); - assertNotEquals( value( "Hello" ), value( "hello" ) ); - assertNotEquals( value( "This åäö string ?? contains strange " ), - value( "This åäö string ?? contains strange Ü" ) ); + assertEquals(value("Hello"), value("Hello")); + assertEquals(value("This åäö string ?? contains strange Ü"), value("This åäö string ?? contains strange Ü")); + assertEquals(value(""), value("")); + assertNotEquals(value("Hello"), value("hello")); + assertNotEquals(value("This åäö string ?? contains strange "), value("This åäö string ?? contains strange Ü")); - assertEquals( value( 'A' ), value( 'A' ) ); - assertEquals( value( 'A' ), value( "A" ) ); + assertEquals(value('A'), value('A')); + assertEquals(value('A'), value("A")); } @Test - void shouldMapDriverComplexTypesToListOfJavaPrimitiveTypes() - { + void shouldMapDriverComplexTypesToListOfJavaPrimitiveTypes() { // Given - Map map = new HashMap<>(); - map.put( "Cat", new ListValue( values( "meow", "miaow" ) ) ); - map.put( "Dog", new ListValue( values( "wow" ) ) ); - map.put( "Wrong", new ListValue( values( -1 ) ) ); - MapValue mapValue = new MapValue( map ); + Map map = new HashMap<>(); + map.put("Cat", new ListValue(values("meow", "miaow"))); + map.put("Dog", new ListValue(values("wow"))); + map.put("Wrong", new ListValue(values(-1))); + MapValue mapValue = new MapValue(map); // When - Iterable> list = mapValue.values( ofList( ofToString() ) ); + Iterable> list = mapValue.values(ofList(ofToString())); // Then - assertEquals( 3, mapValue.size() ); + assertEquals(3, mapValue.size()); Iterator> listIterator = list.iterator(); - Set setA = new HashSet<>( 3 ); - Set setB = new HashSet<>( 3 ); - for ( Value value : mapValue.values() ) - { - String a = value.get( 0 ).toString(); - String b = listIterator.next().get( 0 ); - setA.add( a ); - setB.add( b ); + Set setA = new HashSet<>(3); + Set setB = new HashSet<>(3); + for (Value value : mapValue.values()) { + String a = value.get(0).toString(); + String b = listIterator.next().get(0); + setA.add(a); + setB.add(b); } - assertThat( setA, equalTo( setB ) ); + assertThat(setA, equalTo(setB)); } @Test - void shouldMapDriverMapsToJavaMaps() - { + void shouldMapDriverMapsToJavaMaps() { // Given - Map map = new HashMap<>(); - map.put( "Cat", value( 1 ) ); - map.put( "Dog", value( 2 ) ); - MapValue values = new MapValue( map ); + Map map = new HashMap<>(); + map.put("Cat", value(1)); + map.put("Dog", value(2)); + MapValue values = new MapValue(map); // When - Map result = values.asMap( Values.ofToString() ); + Map result = values.asMap(Values.ofToString()); // Then - assertThat( result.size(), equalTo( 2 ) ); - assertThat( result.get( "Dog" ), equalTo( "2" ) ); - assertThat( result.get( "Cat" ), equalTo( "1" ) ); + assertThat(result.size(), equalTo(2)); + assertThat(result.get("Dog"), equalTo("2")); + assertThat(result.get("Cat"), equalTo("1")); } @Test - void shouldNotBeAbleToGetKeysFromNonKeyedValue() - { - assertThrows( ClientException.class, () -> value( "asd" ).get( 1 ) ); + void shouldNotBeAbleToGetKeysFromNonKeyedValue() { + assertThrows(ClientException.class, () -> value("asd").get(1)); } @Test - void shouldNotBeAbleToDoCrazyCoercions() - { - assertThrows( ClientException.class, () -> value( 1 ).asPath() ); + void shouldNotBeAbleToDoCrazyCoercions() { + assertThrows(ClientException.class, () -> value(1).asPath()); } @Test - void shouldNotBeAbleToGetSizeOnNonSizedValues() - { - assertThrows( ClientException.class, () -> value( 1 ).size() ); + void shouldNotBeAbleToGetSizeOnNonSizedValues() { + assertThrows(ClientException.class, () -> value(1).size()); } @Test - void shouldMapInteger() - { + void shouldMapInteger() { // Given - Value val = value( 1, 2, 3 ); + Value val = value(1, 2, 3); // When/Then - assertThat( val.asList( ofInteger() ), contains( 1, 2, 3 ) ); - assertThat( val.asList( ofLong() ), contains( 1L, 2L, 3L ) ); - assertThat( val.asList( ofNumber() ), contains( 1L, 2L, 3L ) ); - assertThat( val.asList( ofObject() ), contains( 1L, 2L, 3L ) ); + assertThat(val.asList(ofInteger()), contains(1, 2, 3)); + assertThat(val.asList(ofLong()), contains(1L, 2L, 3L)); + assertThat(val.asList(ofNumber()), contains(1L, 2L, 3L)); + assertThat(val.asList(ofObject()), contains(1L, 2L, 3L)); } @Test - void shouldMapFloat() - { + void shouldMapFloat() { // Given - Value val = value( 1.0, 1.2, 3.2 ); + Value val = value(1.0, 1.2, 3.2); // When/Then - assertThat( val.asList( ofDouble() ), contains( 1.0, 1.2, 3.2 ) ); - assertThat( val.asList( ofNumber() ), contains( 1.0, 1.2, 3.2 ) ); - assertThat( val.asList( ofObject() ), contains( 1.0, 1.2, 3.2 ) ); + assertThat(val.asList(ofDouble()), contains(1.0, 1.2, 3.2)); + assertThat(val.asList(ofNumber()), contains(1.0, 1.2, 3.2)); + assertThat(val.asList(ofObject()), contains(1.0, 1.2, 3.2)); } @Test - void shouldMapFloatToJavaFloat() - { + void shouldMapFloatToJavaFloat() { // Given all double -> float conversions other than integers // loose precision, as far as java is concerned, so we // can only convert integer numbers to float. - Value val = value( 1.0, 2.0, 3.0 ); + Value val = value(1.0, 2.0, 3.0); // When/Then - assertThat( val.asList( ofFloat() ), contains( 1.0F, 2.0F, 3.0F ) ); + assertThat(val.asList(ofFloat()), contains(1.0F, 2.0F, 3.0F)); } @Test - void shouldMapString() - { + void shouldMapString() { // Given - Value val = value( "hello", "world" ); + Value val = value("hello", "world"); // When/Then - assertThat( val.asList( ofString() ), contains( "hello", "world" ) ); - assertThat( val.asList( ofObject() ), contains( "hello", "world" ) ); + assertThat(val.asList(ofString()), contains("hello", "world")); + assertThat(val.asList(ofObject()), contains("hello", "world")); } - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") @Test - void shouldMapMapOfString() - { + void shouldMapMapOfString() { // Given - Map map = new HashMap<>(); - map.put( "hello", "world" ); - Value val = value( asList( map, map ) ); + Map map = new HashMap<>(); + map.put("hello", "world"); + Value val = value(asList(map, map)); // When/Then - assertThat( val.asList( ofMap() ), contains( map, map ) ); - assertThat( val.asList( ofObject() ), contains( map, map ) ); + assertThat(val.asList(ofMap()), contains(map, map)); + assertThat(val.asList(ofObject()), contains(map, map)); } @Test - void shouldHandleCollection() - { + void shouldHandleCollection() { // Given Collection collection = new ArrayDeque<>(); - collection.add( "hello" ); - collection.add( "world" ); - Value val = value( collection ); + collection.add("hello"); + collection.add("world"); + Value val = value(collection); // When/Then - assertThat( val.asList(), Matchers.containsInAnyOrder( "hello", "world" ) ); + assertThat(val.asList(), Matchers.containsInAnyOrder("hello", "world")); } @Test - void shouldHandleIterator() - { + void shouldHandleIterator() { // Given - Iterator iterator = asList( "hello", "world" ).iterator(); - Value val = value( iterator ); + Iterator iterator = asList("hello", "world").iterator(); + Value val = value(iterator); // When/Then - assertThat( val.asList(), Matchers.containsInAnyOrder( "hello", "world" ) ); + assertThat(val.asList(), Matchers.containsInAnyOrder("hello", "world")); } @Test - void shouldCreateDateValueFromLocalDate() - { + void shouldCreateDateValueFromLocalDate() { LocalDate localDate = LocalDate.now(); - Value value = value( localDate ); + Value value = value(localDate); - assertThat( value, instanceOf( DateValue.class ) ); - assertEquals( localDate, value.asLocalDate() ); + assertThat(value, instanceOf(DateValue.class)); + assertEquals(localDate, value.asLocalDate()); } @Test - void shouldCreateDateValue() - { + void shouldCreateDateValue() { Object localDate = LocalDate.now(); - Value value = value( localDate ); + Value value = value(localDate); - assertThat( value, instanceOf( DateValue.class ) ); - assertEquals( localDate, value.asObject() ); + assertThat(value, instanceOf(DateValue.class)); + assertEquals(localDate, value.asObject()); } @Test - void shouldCreateTimeValueFromOffsetTime() - { + void shouldCreateTimeValueFromOffsetTime() { OffsetTime offsetTime = OffsetTime.now(); - Value value = value( offsetTime ); + Value value = value(offsetTime); - assertThat( value, instanceOf( TimeValue.class ) ); - assertEquals( offsetTime, value.asOffsetTime() ); + assertThat(value, instanceOf(TimeValue.class)); + assertEquals(offsetTime, value.asOffsetTime()); } @Test - void shouldCreateTimeValue() - { + void shouldCreateTimeValue() { OffsetTime offsetTime = OffsetTime.now(); - Value value = value( offsetTime ); + Value value = value(offsetTime); - assertThat( value, instanceOf( TimeValue.class ) ); - assertEquals( offsetTime, value.asObject() ); + assertThat(value, instanceOf(TimeValue.class)); + assertEquals(offsetTime, value.asObject()); } @Test - void shouldCreateLocalTimeValueFromLocalTime() - { + void shouldCreateLocalTimeValueFromLocalTime() { LocalTime localTime = LocalTime.now(); - Value value = value( localTime ); + Value value = value(localTime); - assertThat( value, instanceOf( LocalTimeValue.class ) ); - assertEquals( localTime, value.asLocalTime() ); + assertThat(value, instanceOf(LocalTimeValue.class)); + assertEquals(localTime, value.asLocalTime()); } @Test - void shouldCreateLocalTimeValue() - { + void shouldCreateLocalTimeValue() { LocalTime localTime = LocalTime.now(); - Value value = value( localTime ); + Value value = value(localTime); - assertThat( value, instanceOf( LocalTimeValue.class ) ); - assertEquals( localTime, value.asObject() ); + assertThat(value, instanceOf(LocalTimeValue.class)); + assertEquals(localTime, value.asObject()); } @Test - void shouldCreateLocalDateTimeValueFromLocalDateTime() - { + void shouldCreateLocalDateTimeValueFromLocalDateTime() { LocalDateTime localDateTime = LocalDateTime.now(); - Value value = value( localDateTime ); + Value value = value(localDateTime); - assertThat( value, instanceOf( LocalDateTimeValue.class ) ); - assertEquals( localDateTime, value.asLocalDateTime() ); + assertThat(value, instanceOf(LocalDateTimeValue.class)); + assertEquals(localDateTime, value.asLocalDateTime()); } @Test - void shouldCreateLocalDateTimeValue() - { + void shouldCreateLocalDateTimeValue() { LocalDateTime localDateTime = LocalDateTime.now(); - Value value = value( localDateTime ); + Value value = value(localDateTime); - assertThat( value, instanceOf( LocalDateTimeValue.class ) ); - assertEquals( localDateTime, value.asObject() ); + assertThat(value, instanceOf(LocalDateTimeValue.class)); + assertEquals(localDateTime, value.asObject()); } @Test - void shouldCreateDateTimeValueFromOffsetDateTime() - { + void shouldCreateDateTimeValueFromOffsetDateTime() { OffsetDateTime offsetDateTime = OffsetDateTime.now(); - Value value = value( offsetDateTime ); + Value value = value(offsetDateTime); - assertThat( value, instanceOf( DateTimeValue.class ) ); - assertEquals( offsetDateTime, value.asOffsetDateTime() ); - assertEquals( offsetDateTime.toZonedDateTime(), value.asZonedDateTime() ); - assertEquals( offsetDateTime.toZonedDateTime(), value.asObject() ); + assertThat(value, instanceOf(DateTimeValue.class)); + assertEquals(offsetDateTime, value.asOffsetDateTime()); + assertEquals(offsetDateTime.toZonedDateTime(), value.asZonedDateTime()); + assertEquals(offsetDateTime.toZonedDateTime(), value.asObject()); } @Test - void shouldCreateDateTimeValueFromZonedDateTime() - { + void shouldCreateDateTimeValueFromZonedDateTime() { ZonedDateTime zonedDateTime = ZonedDateTime.now(); - Value value = value( zonedDateTime ); + Value value = value(zonedDateTime); - assertThat( value, instanceOf( DateTimeValue.class ) ); - assertEquals( zonedDateTime, value.asZonedDateTime() ); + assertThat(value, instanceOf(DateTimeValue.class)); + assertEquals(zonedDateTime, value.asZonedDateTime()); } @Test - void shouldCreateDateTimeValue() - { + void shouldCreateDateTimeValue() { ZonedDateTime zonedDateTime = ZonedDateTime.now(); - Value value = value( zonedDateTime ); + Value value = value(zonedDateTime); - assertThat( value, instanceOf( DateTimeValue.class ) ); - assertEquals( zonedDateTime, value.asObject() ); + assertThat(value, instanceOf(DateTimeValue.class)); + assertEquals(zonedDateTime, value.asObject()); } @Test - void shouldCreateIsoDurationValue() - { - Value value = isoDuration( 42_1, 42_2, 42_3, 42_4 ); + void shouldCreateIsoDurationValue() { + Value value = isoDuration(42_1, 42_2, 42_3, 42_4); - assertThat( value, instanceOf( DurationValue.class ) ); + assertThat(value, instanceOf(DurationValue.class)); IsoDuration duration = value.asIsoDuration(); - assertEquals( 42_1, duration.months() ); - assertEquals( 42_2, duration.days() ); - assertEquals( 42_3, duration.seconds() ); - assertEquals( 42_4, duration.nanoseconds() ); + assertEquals(42_1, duration.months()); + assertEquals(42_2, duration.days()); + assertEquals(42_3, duration.seconds()); + assertEquals(42_4, duration.nanoseconds()); } @Test - void shouldCreateValueFromIsoDuration() - { - Value durationValue1 = isoDuration( 1, 2, 3, 4 ); + void shouldCreateValueFromIsoDuration() { + Value durationValue1 = isoDuration(1, 2, 3, 4); IsoDuration duration = durationValue1.asIsoDuration(); - Value durationValue2 = value( duration ); + Value durationValue2 = value(duration); - assertEquals( duration, durationValue1.asIsoDuration() ); - assertEquals( duration, durationValue2.asIsoDuration() ); - assertEquals( durationValue1, durationValue2 ); + assertEquals(duration, durationValue1.asIsoDuration()); + assertEquals(duration, durationValue2.asIsoDuration()); + assertEquals(durationValue1, durationValue2); } @Test - void shouldCreateValueFromPeriod() - { - Period period = Period.of( 5, 11, 190 ); + void shouldCreateValueFromPeriod() { + Period period = Period.of(5, 11, 190); - Value value = value( period ); + Value value = value(period); IsoDuration isoDuration = value.asIsoDuration(); - assertEquals( period.toTotalMonths(), isoDuration.months() ); - assertEquals( period.getDays(), isoDuration.days() ); - assertEquals( 0, isoDuration.seconds() ); - assertEquals( 0, isoDuration.nanoseconds() ); + assertEquals(period.toTotalMonths(), isoDuration.months()); + assertEquals(period.getDays(), isoDuration.days()); + assertEquals(0, isoDuration.seconds()); + assertEquals(0, isoDuration.nanoseconds()); } @Test - void shouldCreateValueFromDuration() - { - Duration duration = Duration.ofSeconds( 183951, 4384718937L ); + void shouldCreateValueFromDuration() { + Duration duration = Duration.ofSeconds(183951, 4384718937L); - Value value = value( duration ); + Value value = value(duration); IsoDuration isoDuration = value.asIsoDuration(); - assertEquals( 0, isoDuration.months() ); - assertEquals( 0, isoDuration.days() ); - assertEquals( duration.getSeconds(), isoDuration.seconds() ); - assertEquals( duration.getNano(), isoDuration.nanoseconds() ); + assertEquals(0, isoDuration.months()); + assertEquals(0, isoDuration.days()); + assertEquals(duration.getSeconds(), isoDuration.seconds()); + assertEquals(duration.getNano(), isoDuration.nanoseconds()); } @Test - void shouldCreateValueFromPoint2D() - { - Value point2DValue1 = point( 1, 2, 3 ); + void shouldCreateValueFromPoint2D() { + Value point2DValue1 = point(1, 2, 3); Point point2D = point2DValue1.asPoint(); - Value point2DValue2 = value( point2D ); + Value point2DValue2 = value(point2D); - assertEquals( point2D, point2DValue1.asPoint() ); - assertEquals( point2D, point2DValue2.asPoint() ); - assertEquals( point2DValue1, point2DValue2 ); + assertEquals(point2D, point2DValue1.asPoint()); + assertEquals(point2D, point2DValue2.asPoint()); + assertEquals(point2DValue1, point2DValue2); } @Test - void shouldCreateValueFromPoint3D() - { - Value point3DValue1 = point( 1, 2, 3, 4 ); + void shouldCreateValueFromPoint3D() { + Value point3DValue1 = point(1, 2, 3, 4); Point point3D = point3DValue1.asPoint(); - Value point3DValue2 = value( point3D ); + Value point3DValue2 = value(point3D); - assertEquals( point3D, point3DValue1.asPoint() ); - assertEquals( point3D, point3DValue2.asPoint() ); - assertEquals( point3DValue1, point3DValue2 ); + assertEquals(point3D, point3DValue1.asPoint()); + assertEquals(point3D, point3DValue2.asPoint()); + assertEquals(point3DValue1, point3DValue2); } @Test - void shouldCreateValueFromNodeValue() - { + void shouldCreateValueFromNodeValue() { NodeValue node = emptyNodeValue(); - Value value = value( node ); - assertEquals( node, value ); + Value value = value(node); + assertEquals(node, value); } @Test - void shouldCreateValueFromNode() - { + void shouldCreateValueFromNode() { Node node = emptyNodeValue().asNode(); - Value value = value( node ); - assertEquals( node, value.asNode() ); + Value value = value(node); + assertEquals(node, value.asNode()); } @Test - void shouldCreateValueFromRelationshipValue() - { + void shouldCreateValueFromRelationshipValue() { RelationshipValue rel = emptyRelationshipValue(); - Value value = value( rel ); - assertEquals( rel, value ); + Value value = value(rel); + assertEquals(rel, value); } @Test - void shouldCreateValueFromRelationship() - { + void shouldCreateValueFromRelationship() { Relationship rel = emptyRelationshipValue().asRelationship(); - Value value = value( rel ); - assertEquals( rel, value.asRelationship() ); + Value value = value(rel); + assertEquals(rel, value.asRelationship()); } @Test - void shouldCreateValueFromPathValue() - { + void shouldCreateValueFromPathValue() { PathValue path = filledPathValue(); - Value value = value( path ); - assertEquals( path, value ); + Value value = value(path); + assertEquals(path, value); } @Test - void shouldCreateValueFromPath() - { + void shouldCreateValueFromPath() { Path path = filledPathValue().asPath(); - Value value = value( path ); - assertEquals( path, value.asPath() ); + Value value = value(path); + assertEquals(path, value.asPath()); } @Test - void shouldCreateValueFromStream() - { - Stream stream = Stream.of( "foo", "bar", "baz", "qux" ); - Value value = value( stream ); - assertEquals( asList( "foo", "bar", "baz", "qux" ), value.asObject() ); + void shouldCreateValueFromStream() { + Stream stream = Stream.of("foo", "bar", "baz", "qux"); + Value value = value(stream); + assertEquals(asList("foo", "bar", "baz", "qux"), value.asObject()); } @Test - void shouldFailToConvertStreamOfUnsupportedTypeToValue() - { - Stream stream = Stream.of( new Object(), new Object() ); - ClientException e = assertThrows( ClientException.class, () -> value( stream ) ); - assertEquals( "Unable to convert java.lang.Object to Neo4j Value.", e.getMessage() ); + void shouldFailToConvertStreamOfUnsupportedTypeToValue() { + Stream stream = Stream.of(new Object(), new Object()); + ClientException e = assertThrows(ClientException.class, () -> value(stream)); + assertEquals("Unable to convert java.lang.Object to Neo4j Value.", e.getMessage()); } @Test - void shouldCreateValueFromStreamOfStreams() - { - Stream> stream = Stream.of( Stream.of( "foo", "bar" ), Stream.of( "baz", "qux" ) ); - Value value = value( stream ); - assertEquals( asList( asList( "foo", "bar" ), asList( "baz", "qux" ) ), value.asObject() ); + void shouldCreateValueFromStreamOfStreams() { + Stream> stream = Stream.of(Stream.of("foo", "bar"), Stream.of("baz", "qux")); + Value value = value(stream); + assertEquals(asList(asList("foo", "bar"), asList("baz", "qux")), value.asObject()); } @Test - void shouldCreateValueFromStreamOfNulls() - { - Stream stream = Stream.of( null, null, null ); - Value value = value( stream ); - assertEquals( asList( null, null, null ), value.asObject() ); + void shouldCreateValueFromStreamOfNulls() { + Stream stream = Stream.of(null, null, null); + Value value = value(stream); + assertEquals(asList(null, null, null), value.asObject()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/AsyncResultCursorImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/AsyncResultCursorImplTest.java index b58de0d4ef..05914e2779 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/AsyncResultCursorImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/AsyncResultCursorImplTest.java @@ -18,7 +18,27 @@ */ package org.neo4j.driver.internal.async; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +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.neo4j.driver.Values.value; +import static org.neo4j.driver.Values.values; +import static org.neo4j.driver.internal.summary.InternalDatabaseInfo.DEFAULT_DATABASE_INFO; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; +import static org.neo4j.driver.util.TestUtil.await; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -26,7 +46,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.exceptions.NoSuchRecordException; @@ -45,375 +65,332 @@ import org.neo4j.driver.summary.QueryType; import org.neo4j.driver.summary.ResultSummary; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -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.neo4j.driver.Values.value; -import static org.neo4j.driver.Values.values; -import static org.neo4j.driver.internal.summary.InternalDatabaseInfo.DEFAULT_DATABASE_INFO; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; -import static org.neo4j.driver.util.TestUtil.await; - -class AsyncResultCursorImplTest -{ +class AsyncResultCursorImplTest { @Test - void shouldReturnQueryKeys() - { + void shouldReturnQueryKeys() { RunResponseHandler runHandler = newRunResponseHandler(); - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - List keys = asList( "key1", "key2", "key3" ); - runHandler.onSuccess( singletonMap( "fields", value( keys ) ) ); + List keys = asList("key1", "key2", "key3"); + runHandler.onSuccess(singletonMap("fields", value(keys))); - AsyncResultCursorImpl cursor = newCursor( runHandler, pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(runHandler, pullAllHandler); - assertEquals( keys, cursor.keys() ); + assertEquals(keys, cursor.keys()); } @Test - void shouldReturnSummary() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldReturnSummary() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); ResultSummary summary = new InternalResultSummary( - new Query( "RETURN 42" ), - new InternalServerInfo( "Neo4j/4.2.5", BoltServerAddress.LOCAL_DEFAULT, anyServerVersion(), BoltProtocolV43.VERSION ), - DEFAULT_DATABASE_INFO, QueryType.SCHEMA_WRITE, - new InternalSummaryCounters( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 ), - null, null, emptyList(), 42, 42 - ); - when( pullAllHandler.consumeAsync() ).thenReturn( completedFuture( summary ) ); - - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); - - assertEquals( summary, await( cursor.consumeAsync() ) ); + new Query("RETURN 42"), + new InternalServerInfo( + "Neo4j/4.2.5", BoltServerAddress.LOCAL_DEFAULT, anyServerVersion(), BoltProtocolV43.VERSION), + DEFAULT_DATABASE_INFO, + QueryType.SCHEMA_WRITE, + new InternalSummaryCounters(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0), + null, + null, + emptyList(), + 42, + 42); + when(pullAllHandler.consumeAsync()).thenReturn(completedFuture(summary)); + + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); + + assertEquals(summary, await(cursor.consumeAsync())); } @Test - void shouldReturnNextExistingRecord() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldReturnNextExistingRecord() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - Record record = new InternalRecord( asList( "key1", "key2" ), values( 1, 2 ) ); - when( pullAllHandler.nextAsync() ).thenReturn( completedFuture( record ) ); + Record record = new InternalRecord(asList("key1", "key2"), values(1, 2)); + when(pullAllHandler.nextAsync()).thenReturn(completedFuture(record)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertEquals( record, await( cursor.nextAsync() ) ); + assertEquals(record, await(cursor.nextAsync())); } @Test - void shouldReturnNextNonExistingRecord() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - when( pullAllHandler.nextAsync() ).thenReturn( completedWithNull() ); + void shouldReturnNextNonExistingRecord() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + when(pullAllHandler.nextAsync()).thenReturn(completedWithNull()); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertNull( await( cursor.nextAsync() ) ); + assertNull(await(cursor.nextAsync())); } @Test - void shouldPeekExistingRecord() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldPeekExistingRecord() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - Record record = new InternalRecord( asList( "key1", "key2", "key3" ), values( 3, 2, 1 ) ); - when( pullAllHandler.peekAsync() ).thenReturn( completedFuture( record ) ); + Record record = new InternalRecord(asList("key1", "key2", "key3"), values(3, 2, 1)); + when(pullAllHandler.peekAsync()).thenReturn(completedFuture(record)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertEquals( record, await( cursor.peekAsync() ) ); + assertEquals(record, await(cursor.peekAsync())); } @Test - void shouldPeekNonExistingRecord() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - when( pullAllHandler.peekAsync() ).thenReturn( completedWithNull() ); + void shouldPeekNonExistingRecord() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + when(pullAllHandler.peekAsync()).thenReturn(completedWithNull()); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertNull( await( cursor.peekAsync() ) ); + assertNull(await(cursor.peekAsync())); } @Test - void shouldReturnSingleRecord() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldReturnSingleRecord() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - Record record = new InternalRecord( asList( "key1", "key2" ), values( 42, 42 ) ); - when( pullAllHandler.nextAsync() ).thenReturn( completedFuture( record ) ) - .thenReturn( completedWithNull() ); + Record record = new InternalRecord(asList("key1", "key2"), values(42, 42)); + when(pullAllHandler.nextAsync()).thenReturn(completedFuture(record)).thenReturn(completedWithNull()); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertEquals( record, await( cursor.singleAsync() ) ); + assertEquals(record, await(cursor.singleAsync())); } @Test - void shouldFailWhenAskedForSingleRecordButResultIsEmpty() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - when( pullAllHandler.nextAsync() ).thenReturn( completedWithNull() ); + void shouldFailWhenAskedForSingleRecordButResultIsEmpty() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + when(pullAllHandler.nextAsync()).thenReturn(completedWithNull()); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - NoSuchRecordException e = assertThrows( NoSuchRecordException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), containsString( "result is empty" ) ); + NoSuchRecordException e = assertThrows(NoSuchRecordException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), containsString("result is empty")); } @Test - void shouldFailWhenAskedForSingleRecordButResultContainsMore() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldFailWhenAskedForSingleRecordButResultContainsMore() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - Record record1 = new InternalRecord( asList( "key1", "key2" ), values( 1, 1 ) ); - Record record2 = new InternalRecord( asList( "key1", "key2" ), values( 2, 2 ) ); - when( pullAllHandler.nextAsync() ).thenReturn( completedFuture( record1 ) ) - .thenReturn( completedFuture( record2 ) ); + Record record1 = new InternalRecord(asList("key1", "key2"), values(1, 1)); + Record record2 = new InternalRecord(asList("key1", "key2"), values(2, 2)); + when(pullAllHandler.nextAsync()).thenReturn(completedFuture(record1)).thenReturn(completedFuture(record2)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - NoSuchRecordException e = assertThrows( NoSuchRecordException.class, () -> await( cursor.singleAsync() ) ); - assertThat( e.getMessage(), containsString( "Ensure your query returns only one record" ) ); + NoSuchRecordException e = assertThrows(NoSuchRecordException.class, () -> await(cursor.singleAsync())); + assertThat(e.getMessage(), containsString("Ensure your query returns only one record")); } @Test - void shouldForEachAsyncWhenResultContainsMultipleRecords() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldForEachAsyncWhenResultContainsMultipleRecords() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - Record record1 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 1, 1, 1 ) ); - Record record2 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 2, 2, 2 ) ); - Record record3 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 3, 3, 3 ) ); - when( pullAllHandler.nextAsync() ).thenReturn( completedFuture( record1 ) ) - .thenReturn( completedFuture( record2 ) ).thenReturn( completedFuture( record3 ) ) - .thenReturn( completedWithNull() ); + Record record1 = new InternalRecord(asList("key1", "key2", "key3"), values(1, 1, 1)); + Record record2 = new InternalRecord(asList("key1", "key2", "key3"), values(2, 2, 2)); + Record record3 = new InternalRecord(asList("key1", "key2", "key3"), values(3, 3, 3)); + when(pullAllHandler.nextAsync()) + .thenReturn(completedFuture(record1)) + .thenReturn(completedFuture(record2)) + .thenReturn(completedFuture(record3)) + .thenReturn(completedWithNull()); - ResultSummary summary = mock( ResultSummary.class ); - when( pullAllHandler.consumeAsync() ).thenReturn( completedFuture( summary ) ); + ResultSummary summary = mock(ResultSummary.class); + when(pullAllHandler.consumeAsync()).thenReturn(completedFuture(summary)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); List records = new CopyOnWriteArrayList<>(); - CompletionStage summaryStage = cursor.forEachAsync( records::add ); + CompletionStage summaryStage = cursor.forEachAsync(records::add); - assertEquals( summary, await( summaryStage ) ); - assertEquals( asList( record1, record2, record3 ), records ); + assertEquals(summary, await(summaryStage)); + assertEquals(asList(record1, record2, record3), records); } @Test - void shouldForEachAsyncWhenResultContainsOneRecords() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldForEachAsyncWhenResultContainsOneRecords() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - Record record = new InternalRecord( asList( "key1", "key2", "key3" ), values( 1, 1, 1 ) ); - when( pullAllHandler.nextAsync() ).thenReturn( completedFuture( record ) ) - .thenReturn( completedWithNull() ); + Record record = new InternalRecord(asList("key1", "key2", "key3"), values(1, 1, 1)); + when(pullAllHandler.nextAsync()).thenReturn(completedFuture(record)).thenReturn(completedWithNull()); - ResultSummary summary = mock( ResultSummary.class ); - when( pullAllHandler.consumeAsync() ).thenReturn( completedFuture( summary ) ); + ResultSummary summary = mock(ResultSummary.class); + when(pullAllHandler.consumeAsync()).thenReturn(completedFuture(summary)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); List records = new CopyOnWriteArrayList<>(); - CompletionStage summaryStage = cursor.forEachAsync( records::add ); + CompletionStage summaryStage = cursor.forEachAsync(records::add); - assertEquals( summary, await( summaryStage ) ); - assertEquals( singletonList( record ), records ); + assertEquals(summary, await(summaryStage)); + assertEquals(singletonList(record), records); } @Test - void shouldForEachAsyncWhenResultContainsNoRecords() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - when( pullAllHandler.nextAsync() ).thenReturn( completedWithNull() ); + void shouldForEachAsyncWhenResultContainsNoRecords() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + when(pullAllHandler.nextAsync()).thenReturn(completedWithNull()); - ResultSummary summary = mock( ResultSummary.class ); - when( pullAllHandler.consumeAsync() ).thenReturn( completedFuture( summary ) ); + ResultSummary summary = mock(ResultSummary.class); + when(pullAllHandler.consumeAsync()).thenReturn(completedFuture(summary)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); List records = new CopyOnWriteArrayList<>(); - CompletionStage summaryStage = cursor.forEachAsync( records::add ); + CompletionStage summaryStage = cursor.forEachAsync(records::add); - assertEquals( summary, await( summaryStage ) ); - assertEquals( 0, records.size() ); + assertEquals(summary, await(summaryStage)); + assertEquals(0, records.size()); } @Test - void shouldFailForEachWhenGivenActionThrows() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldFailForEachWhenGivenActionThrows() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - Record record1 = new InternalRecord( asList( "key1", "key2" ), values( 1, 1 ) ); - Record record2 = new InternalRecord( asList( "key1", "key2" ), values( 2, 2 ) ); - Record record3 = new InternalRecord( asList( "key1", "key2" ), values( 3, 3 ) ); - when( pullAllHandler.nextAsync() ).thenReturn( completedFuture( record1 ) ) - .thenReturn( completedFuture( record2 ) ).thenReturn( completedFuture( record3 ) ) - .thenReturn( completedWithNull() ); + Record record1 = new InternalRecord(asList("key1", "key2"), values(1, 1)); + Record record2 = new InternalRecord(asList("key1", "key2"), values(2, 2)); + Record record3 = new InternalRecord(asList("key1", "key2"), values(3, 3)); + when(pullAllHandler.nextAsync()) + .thenReturn(completedFuture(record1)) + .thenReturn(completedFuture(record2)) + .thenReturn(completedFuture(record3)) + .thenReturn(completedWithNull()); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); AtomicInteger recordsProcessed = new AtomicInteger(); - RuntimeException error = new RuntimeException( "Hello" ); + RuntimeException error = new RuntimeException("Hello"); - CompletionStage stage = cursor.forEachAsync( record -> - { - if ( record.get( "key2" ).asInt() == 2 ) - { + CompletionStage stage = cursor.forEachAsync(record -> { + if (record.get("key2").asInt() == 2) { throw error; - } - else - { + } else { recordsProcessed.incrementAndGet(); } - } ); + }); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( stage ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(stage)); + assertEquals(error, e); - assertEquals( 1, recordsProcessed.get() ); - verify( pullAllHandler, times( 2 ) ).nextAsync(); + assertEquals(1, recordsProcessed.get()); + verify(pullAllHandler, times(2)).nextAsync(); } @Test - void shouldReturnFailureWhenExists() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldReturnFailureWhenExists() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - ServiceUnavailableException error = new ServiceUnavailableException( "Hi" ); - when( pullAllHandler.pullAllFailureAsync() ).thenReturn( completedFuture( error ) ); + ServiceUnavailableException error = new ServiceUnavailableException("Hi"); + when(pullAllHandler.pullAllFailureAsync()).thenReturn(completedFuture(error)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertEquals( error, await( cursor.pullAllFailureAsync() ) ); + assertEquals(error, await(cursor.pullAllFailureAsync())); } @Test - void shouldReturnNullFailureWhenDoesNotExist() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - when( pullAllHandler.pullAllFailureAsync() ).thenReturn( completedWithNull() ); + void shouldReturnNullFailureWhenDoesNotExist() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + when(pullAllHandler.pullAllFailureAsync()).thenReturn(completedWithNull()); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertNull( await( cursor.pullAllFailureAsync() ) ); + assertNull(await(cursor.pullAllFailureAsync())); } @Test - void shouldListAsyncWithoutMapFunction() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldListAsyncWithoutMapFunction() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - Record record1 = new InternalRecord( asList( "key1", "key2" ), values( 1, 1 ) ); - Record record2 = new InternalRecord( asList( "key1", "key2" ), values( 2, 2 ) ); - List records = asList( record1, record2 ); + Record record1 = new InternalRecord(asList("key1", "key2"), values(1, 1)); + Record record2 = new InternalRecord(asList("key1", "key2"), values(2, 2)); + List records = asList(record1, record2); - when( pullAllHandler.listAsync( Function.identity() ) ).thenReturn( completedFuture( records ) ); + when(pullAllHandler.listAsync(Function.identity())).thenReturn(completedFuture(records)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertEquals( records, await( cursor.listAsync() ) ); - verify( pullAllHandler ).listAsync( Function.identity() ); + assertEquals(records, await(cursor.listAsync())); + verify(pullAllHandler).listAsync(Function.identity()); } @Test - void shouldListAsyncWithMapFunction() - { - Function mapFunction = record -> record.get( 0 ).asString(); - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + void shouldListAsyncWithMapFunction() { + Function mapFunction = record -> record.get(0).asString(); + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - List values = asList( "a", "b", "c", "d", "e" ); - when( pullAllHandler.listAsync( mapFunction ) ).thenReturn( completedFuture( values ) ); + List values = asList("a", "b", "c", "d", "e"); + when(pullAllHandler.listAsync(mapFunction)).thenReturn(completedFuture(values)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertEquals( values, await( cursor.listAsync( mapFunction ) ) ); - verify( pullAllHandler ).listAsync( mapFunction ); + assertEquals(values, await(cursor.listAsync(mapFunction))); + verify(pullAllHandler).listAsync(mapFunction); } @Test - void shouldPropagateFailureFromListAsyncWithoutMapFunction() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - RuntimeException error = new RuntimeException( "Hi" ); - when( pullAllHandler.listAsync( Function.identity() ) ).thenReturn( failedFuture( error ) ); + void shouldPropagateFailureFromListAsyncWithoutMapFunction() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + RuntimeException error = new RuntimeException("Hi"); + when(pullAllHandler.listAsync(Function.identity())).thenReturn(failedFuture(error)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( cursor.listAsync() ) ); - assertEquals( error, e ); - verify( pullAllHandler ).listAsync( Function.identity() ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(cursor.listAsync())); + assertEquals(error, e); + verify(pullAllHandler).listAsync(Function.identity()); } @Test - void shouldPropagateFailureFromListAsyncWithMapFunction() - { - Function mapFunction = record -> record.get( 0 ).asString(); - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - RuntimeException error = new RuntimeException( "Hi" ); - when( pullAllHandler.listAsync( mapFunction ) ).thenReturn( failedFuture( error ) ); + void shouldPropagateFailureFromListAsyncWithMapFunction() { + Function mapFunction = record -> record.get(0).asString(); + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + RuntimeException error = new RuntimeException("Hi"); + when(pullAllHandler.listAsync(mapFunction)).thenReturn(failedFuture(error)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( cursor.listAsync( mapFunction ) ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(cursor.listAsync(mapFunction))); + assertEquals(error, e); - verify( pullAllHandler ).listAsync( mapFunction ); + verify(pullAllHandler).listAsync(mapFunction); } @Test - void shouldConsumeAsync() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - ResultSummary summary = mock( ResultSummary.class ); - when( pullAllHandler.consumeAsync() ).thenReturn( completedFuture( summary ) ); + void shouldConsumeAsync() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + ResultSummary summary = mock(ResultSummary.class); + when(pullAllHandler.consumeAsync()).thenReturn(completedFuture(summary)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - assertEquals( summary, await( cursor.consumeAsync() ) ); + assertEquals(summary, await(cursor.consumeAsync())); } @Test - void shouldPropagateFailureInConsumeAsync() - { - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); - RuntimeException error = new RuntimeException( "Hi" ); - when( pullAllHandler.consumeAsync() ).thenReturn( failedFuture( error ) ); + void shouldPropagateFailureInConsumeAsync() { + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); + RuntimeException error = new RuntimeException("Hi"); + when(pullAllHandler.consumeAsync()).thenReturn(failedFuture(error)); - AsyncResultCursorImpl cursor = newCursor( pullAllHandler ); + AsyncResultCursorImpl cursor = newCursor(pullAllHandler); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( cursor.consumeAsync() ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(cursor.consumeAsync())); + assertEquals(error, e); } - private static AsyncResultCursorImpl newCursor(PullAllResponseHandler pullAllHandler ) - { - return new AsyncResultCursorImpl( null, newRunResponseHandler(), pullAllHandler ); + private static AsyncResultCursorImpl newCursor(PullAllResponseHandler pullAllHandler) { + return new AsyncResultCursorImpl(null, newRunResponseHandler(), pullAllHandler); } - private static AsyncResultCursorImpl newCursor(RunResponseHandler runHandler, PullAllResponseHandler pullAllHandler ) - { - return new AsyncResultCursorImpl( null, runHandler, pullAllHandler ); + private static AsyncResultCursorImpl newCursor( + RunResponseHandler runHandler, PullAllResponseHandler pullAllHandler) { + return new AsyncResultCursorImpl(null, runHandler, pullAllHandler); } - private static RunResponseHandler newRunResponseHandler() - { - return new RunResponseHandler( new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock( Connection.class ), null ); + private static RunResponseHandler newRunResponseHandler() { + return new RunResponseHandler( + new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock(Connection.class), null); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncSessionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncSessionTest.java index 627ea6750a..a19256c6fd 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncSessionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncSessionTest.java @@ -18,36 +18,6 @@ */ package org.neo4j.driver.internal.async; -import org.hamcrest.junit.MatcherAssert; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.concurrent.CompletionStage; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Query; -import org.neo4j.driver.TransactionConfig; -import org.neo4j.driver.Value; -import org.neo4j.driver.async.AsyncSession; -import org.neo4j.driver.async.AsyncTransaction; -import org.neo4j.driver.async.AsyncTransactionWork; -import org.neo4j.driver.async.ResultCursor; -import org.neo4j.driver.exceptions.ServiceUnavailableException; -import org.neo4j.driver.exceptions.SessionExpiredException; -import org.neo4j.driver.internal.InternalBookmark; -import org.neo4j.driver.internal.InternalRecord; -import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; -import org.neo4j.driver.internal.retry.RetryLogic; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionProvider; -import org.neo4j.driver.internal.util.FixedRetryLogic; -import org.neo4j.driver.internal.value.IntegerValue; - import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -79,316 +49,301 @@ import static org.neo4j.driver.util.TestUtil.verifyRollbackTx; import static org.neo4j.driver.util.TestUtil.verifyRunAndPull; -class InternalAsyncSessionTest -{ +import java.util.concurrent.CompletionStage; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; +import org.hamcrest.junit.MatcherAssert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Query; +import org.neo4j.driver.TransactionConfig; +import org.neo4j.driver.Value; +import org.neo4j.driver.async.AsyncSession; +import org.neo4j.driver.async.AsyncTransaction; +import org.neo4j.driver.async.AsyncTransactionWork; +import org.neo4j.driver.async.ResultCursor; +import org.neo4j.driver.exceptions.ServiceUnavailableException; +import org.neo4j.driver.exceptions.SessionExpiredException; +import org.neo4j.driver.internal.InternalBookmark; +import org.neo4j.driver.internal.InternalRecord; +import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; +import org.neo4j.driver.internal.retry.RetryLogic; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionProvider; +import org.neo4j.driver.internal.util.FixedRetryLogic; +import org.neo4j.driver.internal.value.IntegerValue; + +class InternalAsyncSessionTest { private Connection connection; private ConnectionProvider connectionProvider; private AsyncSession asyncSession; private NetworkSession session; @BeforeEach - void setUp() - { - connection = connectionMock( BoltProtocolV4.INSTANCE ); - connectionProvider = mock( ConnectionProvider.class ); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) - .thenReturn( completedFuture( connection ) ); - session = newSession( connectionProvider ); - asyncSession = new InternalAsyncSession( session ); + void setUp() { + connection = connectionMock(BoltProtocolV4.INSTANCE); + connectionProvider = mock(ConnectionProvider.class); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))) + .thenReturn(completedFuture(connection)); + session = newSession(connectionProvider); + asyncSession = new InternalAsyncSession(session); } - private static Stream>> allSessionRunMethods() - { + private static Stream>> allSessionRunMethods() { return Stream.of( - session -> session.runAsync( "RETURN 1" ), - session -> session.runAsync( "RETURN $x", parameters( "x", 1 ) ), - session -> session.runAsync( "RETURN $x", singletonMap( "x", 1 ) ), - session -> session.runAsync( "RETURN $x", - new InternalRecord( singletonList( "x" ), new Value[]{new IntegerValue( 1 )} ) ), - session -> session.runAsync( new Query( "RETURN $x", parameters( "x", 1 ) ) ), - session -> session.runAsync( new Query( "RETURN $x", parameters( "x", 1 ) ), empty() ), - session -> session.runAsync( "RETURN $x", singletonMap( "x", 1 ), empty() ), - session -> session.runAsync( "RETURN 1", empty() ) - ); + session -> session.runAsync("RETURN 1"), + session -> session.runAsync("RETURN $x", parameters("x", 1)), + session -> session.runAsync("RETURN $x", singletonMap("x", 1)), + session -> session.runAsync( + "RETURN $x", new InternalRecord(singletonList("x"), new Value[] {new IntegerValue(1)})), + session -> session.runAsync(new Query("RETURN $x", parameters("x", 1))), + session -> session.runAsync(new Query("RETURN $x", parameters("x", 1)), empty()), + session -> session.runAsync("RETURN $x", singletonMap("x", 1), empty()), + session -> session.runAsync("RETURN 1", empty())); } - private static Stream>> allBeginTxMethods() - { + private static Stream>> allBeginTxMethods() { return Stream.of( session -> session.beginTransactionAsync(), - session -> session.beginTransactionAsync( TransactionConfig.empty() ) - ); + session -> session.beginTransactionAsync(TransactionConfig.empty())); } - private static Stream>> allRunTxMethods() - { + private static Stream>> allRunTxMethods() { return Stream.of( - session -> session.readTransactionAsync( tx -> completedFuture( "a" ) ), - session -> session.writeTransactionAsync( tx -> completedFuture( "a" ) ), - session -> session.readTransactionAsync( tx -> completedFuture( "a" ), empty() ), - session -> session.writeTransactionAsync( tx -> completedFuture( "a" ), empty() ) - ); + session -> session.readTransactionAsync(tx -> completedFuture("a")), + session -> session.writeTransactionAsync(tx -> completedFuture("a")), + session -> session.readTransactionAsync(tx -> completedFuture("a"), empty()), + session -> session.writeTransactionAsync(tx -> completedFuture("a"), empty())); } @ParameterizedTest - @MethodSource( "allSessionRunMethods" ) - void shouldFlushOnRun( Function> runReturnOne ) throws Throwable - { - setupSuccessfulRunAndPull( connection ); + @MethodSource("allSessionRunMethods") + void shouldFlushOnRun(Function> runReturnOne) throws Throwable { + setupSuccessfulRunAndPull(connection); - ResultCursor cursor = await( runReturnOne.apply( asyncSession ) ); + ResultCursor cursor = await(runReturnOne.apply(asyncSession)); - verifyRunAndPull( connection, await( cursor.consumeAsync() ).query().text() ); + verifyRunAndPull(connection, await(cursor.consumeAsync()).query().text()); } @ParameterizedTest - @MethodSource( "allBeginTxMethods" ) - void shouldDelegateBeginTx( Function> beginTx ) throws Throwable - { - AsyncTransaction tx = await( beginTx.apply( asyncSession ) ); + @MethodSource("allBeginTxMethods") + void shouldDelegateBeginTx(Function> beginTx) throws Throwable { + AsyncTransaction tx = await(beginTx.apply(asyncSession)); - verifyBeginTx( connection ); - assertNotNull( tx ); + verifyBeginTx(connection); + assertNotNull(tx); } @ParameterizedTest - @MethodSource( "allRunTxMethods" ) - void txRunShouldBeginAndCommitTx( Function> runTx ) throws Throwable - { - String string = await( runTx.apply( asyncSession ) ); - - verifyBeginTx( connection ); - verifyCommitTx( connection ); - verify( connection ).release(); - assertThat( string, equalTo( "a" ) ); + @MethodSource("allRunTxMethods") + void txRunShouldBeginAndCommitTx(Function> runTx) throws Throwable { + String string = await(runTx.apply(asyncSession)); + + verifyBeginTx(connection); + verifyCommitTx(connection); + verify(connection).release(); + assertThat(string, equalTo("a")); } - @Test - void rollsBackReadTxWhenFunctionThrows() - { - testTxRollbackWhenThrows( READ ); + void rollsBackReadTxWhenFunctionThrows() { + testTxRollbackWhenThrows(READ); } @Test - void rollsBackWriteTxWhenFunctionThrows() - { - testTxRollbackWhenThrows( WRITE ); + void rollsBackWriteTxWhenFunctionThrows() { + testTxRollbackWhenThrows(WRITE); } @Test - void readTxRetriedUntilSuccessWhenFunctionThrows() - { - testTxIsRetriedUntilSuccessWhenFunctionThrows( READ ); + void readTxRetriedUntilSuccessWhenFunctionThrows() { + testTxIsRetriedUntilSuccessWhenFunctionThrows(READ); } @Test - void writeTxRetriedUntilSuccessWhenFunctionThrows() - { - testTxIsRetriedUntilSuccessWhenFunctionThrows( WRITE ); + void writeTxRetriedUntilSuccessWhenFunctionThrows() { + testTxIsRetriedUntilSuccessWhenFunctionThrows(WRITE); } @Test - void readTxRetriedUntilSuccessWhenTxCloseThrows() - { - testTxIsRetriedUntilSuccessWhenCommitThrows( READ ); + void readTxRetriedUntilSuccessWhenTxCloseThrows() { + testTxIsRetriedUntilSuccessWhenCommitThrows(READ); } @Test - void writeTxRetriedUntilSuccessWhenTxCloseThrows() - { - testTxIsRetriedUntilSuccessWhenCommitThrows( WRITE ); + void writeTxRetriedUntilSuccessWhenTxCloseThrows() { + testTxIsRetriedUntilSuccessWhenCommitThrows(WRITE); } @Test - void readTxRetriedUntilFailureWhenFunctionThrows() - { - testTxIsRetriedUntilFailureWhenFunctionThrows( READ ); + void readTxRetriedUntilFailureWhenFunctionThrows() { + testTxIsRetriedUntilFailureWhenFunctionThrows(READ); } @Test - void writeTxRetriedUntilFailureWhenFunctionThrows() - { - testTxIsRetriedUntilFailureWhenFunctionThrows( WRITE ); + void writeTxRetriedUntilFailureWhenFunctionThrows() { + testTxIsRetriedUntilFailureWhenFunctionThrows(WRITE); } @Test - void readTxRetriedUntilFailureWhenTxCloseThrows() - { - testTxIsRetriedUntilFailureWhenCommitFails( READ ); + void readTxRetriedUntilFailureWhenTxCloseThrows() { + testTxIsRetriedUntilFailureWhenCommitFails(READ); } @Test - void writeTxRetriedUntilFailureWhenTxCloseThrows() - { - testTxIsRetriedUntilFailureWhenCommitFails( WRITE ); + void writeTxRetriedUntilFailureWhenTxCloseThrows() { + testTxIsRetriedUntilFailureWhenCommitFails(WRITE); } - @Test - void shouldCloseSession() throws Throwable - { - await ( asyncSession.closeAsync() ); - assertFalse( this.session.isOpen() ); + void shouldCloseSession() throws Throwable { + await(asyncSession.closeAsync()); + assertFalse(this.session.isOpen()); } @Test - void shouldReturnBookmark() throws Throwable - { - session = newSession( connectionProvider, InternalBookmark.parse( "Bookmark1" ) ); - asyncSession = new InternalAsyncSession( session ); + void shouldReturnBookmark() throws Throwable { + session = newSession(connectionProvider, InternalBookmark.parse("Bookmark1")); + asyncSession = new InternalAsyncSession(session); - assertThat( asyncSession.lastBookmark(), equalTo( session.lastBookmark() )); + assertThat(asyncSession.lastBookmark(), equalTo(session.lastBookmark())); } - private void testTxRollbackWhenThrows( AccessMode transactionMode ) - { - final RuntimeException error = new IllegalStateException( "Oh!" ); - AsyncTransactionWork> work = tx -> - { + private void testTxRollbackWhenThrows(AccessMode transactionMode) { + final RuntimeException error = new IllegalStateException("Oh!"); + AsyncTransactionWork> work = tx -> { throw error; }; - Exception e = assertThrows( Exception.class, () -> executeTransaction( asyncSession, transactionMode, work ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> executeTransaction(asyncSession, transactionMode, work)); + assertEquals(error, e); - verify( connectionProvider ).acquireConnection( any( ConnectionContext.class ) ); - verifyBeginTx( connection ); - verifyRollbackTx( connection ); + verify(connectionProvider).acquireConnection(any(ConnectionContext.class)); + verifyBeginTx(connection); + verifyRollbackTx(connection); } - private void testTxIsRetriedUntilSuccessWhenFunctionThrows( AccessMode mode ) - { + private void testTxIsRetriedUntilSuccessWhenFunctionThrows(AccessMode mode) { int failures = 12; int retries = failures + 1; - RetryLogic retryLogic = new FixedRetryLogic( retries ); - session = newSession( connectionProvider, retryLogic ); - asyncSession = new InternalAsyncSession( session ); + RetryLogic retryLogic = new FixedRetryLogic(retries); + session = newSession(connectionProvider, retryLogic); + asyncSession = new InternalAsyncSession(session); - TxWork work = spy( new TxWork( 42, failures, new SessionExpiredException( "" ) ) ); - int answer = executeTransaction( asyncSession, mode, work ); + TxWork work = spy(new TxWork(42, failures, new SessionExpiredException(""))); + int answer = executeTransaction(asyncSession, mode, work); - assertEquals( 42, answer ); - verifyInvocationCount( work, failures + 1 ); - verifyCommitTx( connection ); - verifyRollbackTx( connection, times( failures ) ); + assertEquals(42, answer); + verifyInvocationCount(work, failures + 1); + verifyCommitTx(connection); + verifyRollbackTx(connection, times(failures)); } - private void testTxIsRetriedUntilSuccessWhenCommitThrows( AccessMode mode ) - { + private void testTxIsRetriedUntilSuccessWhenCommitThrows(AccessMode mode) { int failures = 13; int retries = failures + 1; - RetryLogic retryLogic = new FixedRetryLogic( retries ); - setupFailingCommit( connection, failures ); - session = newSession( connectionProvider, retryLogic ); - asyncSession = new InternalAsyncSession( session ); + RetryLogic retryLogic = new FixedRetryLogic(retries); + setupFailingCommit(connection, failures); + session = newSession(connectionProvider, retryLogic); + asyncSession = new InternalAsyncSession(session); - TxWork work = spy( new TxWork( 43 ) ); - int answer = executeTransaction( asyncSession, mode, work ); + TxWork work = spy(new TxWork(43)); + int answer = executeTransaction(asyncSession, mode, work); - assertEquals( 43, answer ); - verifyInvocationCount( work, failures + 1 ); - verifyCommitTx( connection, times( retries ) ); + assertEquals(43, answer); + verifyInvocationCount(work, failures + 1); + verifyCommitTx(connection, times(retries)); } - private void testTxIsRetriedUntilFailureWhenFunctionThrows( AccessMode mode ) - { + private void testTxIsRetriedUntilFailureWhenFunctionThrows(AccessMode mode) { int failures = 14; int retries = failures - 1; - RetryLogic retryLogic = new FixedRetryLogic( retries ); - session = newSession( connectionProvider, retryLogic ); - asyncSession = new InternalAsyncSession( session ); + RetryLogic retryLogic = new FixedRetryLogic(retries); + session = newSession(connectionProvider, retryLogic); + asyncSession = new InternalAsyncSession(session); - TxWork work = spy( new TxWork( 42, failures, new SessionExpiredException( "Oh!" ) ) ); + TxWork work = spy(new TxWork(42, failures, new SessionExpiredException("Oh!"))); - Exception e = assertThrows( Exception.class, () -> executeTransaction( asyncSession, mode, work ) ); + Exception e = assertThrows(Exception.class, () -> executeTransaction(asyncSession, mode, work)); - MatcherAssert.assertThat( e, instanceOf( SessionExpiredException.class ) ); - assertEquals( "Oh!", e.getMessage() ); - verifyInvocationCount( work, failures ); - verifyCommitTx( connection, never() ); - verifyRollbackTx( connection, times( failures ) ); + MatcherAssert.assertThat(e, instanceOf(SessionExpiredException.class)); + assertEquals("Oh!", e.getMessage()); + verifyInvocationCount(work, failures); + verifyCommitTx(connection, never()); + verifyRollbackTx(connection, times(failures)); } - private void testTxIsRetriedUntilFailureWhenCommitFails( AccessMode mode ) - { + private void testTxIsRetriedUntilFailureWhenCommitFails(AccessMode mode) { int failures = 17; int retries = failures - 1; - RetryLogic retryLogic = new FixedRetryLogic( retries ); - setupFailingCommit( connection, failures ); - session = newSession( connectionProvider, retryLogic ); - asyncSession = new InternalAsyncSession( session ); + RetryLogic retryLogic = new FixedRetryLogic(retries); + setupFailingCommit(connection, failures); + session = newSession(connectionProvider, retryLogic); + asyncSession = new InternalAsyncSession(session); - TxWork work = spy( new TxWork( 42 ) ); + TxWork work = spy(new TxWork(42)); - Exception e = assertThrows( Exception.class, () -> executeTransaction( asyncSession, mode, work ) ); + Exception e = assertThrows(Exception.class, () -> executeTransaction(asyncSession, mode, work)); - MatcherAssert.assertThat( e, instanceOf( ServiceUnavailableException.class ) ); - verifyInvocationCount( work, failures ); - verifyCommitTx( connection, times( failures ) ); + MatcherAssert.assertThat(e, instanceOf(ServiceUnavailableException.class)); + verifyInvocationCount(work, failures); + verifyCommitTx(connection, times(failures)); } - private static T executeTransaction( AsyncSession session, AccessMode mode, AsyncTransactionWork> work ) - { - if ( mode == READ ) - { - return await( session.readTransactionAsync( work ) ); - } - else if ( mode == WRITE ) - { - return await( session.writeTransactionAsync( work ) ); - } - else - { - throw new IllegalArgumentException( "Unknown mode " + mode ); + private static T executeTransaction( + AsyncSession session, AccessMode mode, AsyncTransactionWork> work) { + if (mode == READ) { + return await(session.readTransactionAsync(work)); + } else if (mode == WRITE) { + return await(session.writeTransactionAsync(work)); + } else { + throw new IllegalArgumentException("Unknown mode " + mode); } } - private static void verifyInvocationCount( AsyncTransactionWork workSpy, int expectedInvocationCount ) - { - verify( workSpy, times( expectedInvocationCount ) ).execute( any( AsyncTransaction.class ) ); + private static void verifyInvocationCount(AsyncTransactionWork workSpy, int expectedInvocationCount) { + verify(workSpy, times(expectedInvocationCount)).execute(any(AsyncTransaction.class)); } - private static class TxWork implements AsyncTransactionWork> - { + private static class TxWork implements AsyncTransactionWork> { final int result; final int timesToThrow; final Supplier errorSupplier; int invoked; - @SuppressWarnings( "unchecked" ) - TxWork( int result ) - { - this( result, 0, (Supplier) null ); + @SuppressWarnings("unchecked") + TxWork(int result) { + this(result, 0, (Supplier) null); } - TxWork( int result, int timesToThrow, final RuntimeException error ) - { + TxWork(int result, int timesToThrow, final RuntimeException error) { this.result = result; this.timesToThrow = timesToThrow; this.errorSupplier = () -> error; } - TxWork( int result, int timesToThrow, Supplier errorSupplier ) - { + TxWork(int result, int timesToThrow, Supplier errorSupplier) { this.result = result; this.timesToThrow = timesToThrow; this.errorSupplier = errorSupplier; } @Override - public CompletionStage execute( AsyncTransaction tx ) - { - if ( timesToThrow > 0 && invoked++ < timesToThrow ) - { + public CompletionStage execute(AsyncTransaction tx) { + if (timesToThrow > 0 && invoked++ < timesToThrow) { throw errorSupplier.get(); } - return completedFuture( result ); + return completedFuture(result); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncTransactionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncTransactionTest.java index 9ac1054445..8a1e2fc785 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncTransactionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncTransactionTest.java @@ -18,28 +18,6 @@ */ package org.neo4j.driver.internal.async; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.concurrent.CompletionStage; -import java.util.function.Function; -import java.util.stream.Stream; - -import org.neo4j.driver.Query; -import org.neo4j.driver.Value; -import org.neo4j.driver.async.AsyncTransaction; -import org.neo4j.driver.async.ResultCursor; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.internal.InternalRecord; -import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionProvider; -import org.neo4j.driver.internal.util.Futures; -import org.neo4j.driver.internal.value.IntegerValue; -import org.neo4j.driver.summary.ResultSummary; - import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -62,96 +40,108 @@ import static org.neo4j.driver.util.TestUtil.verifyRollbackTx; import static org.neo4j.driver.util.TestUtil.verifyRunAndPull; -class InternalAsyncTransactionTest -{ +import java.util.concurrent.CompletionStage; +import java.util.function.Function; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.neo4j.driver.Query; +import org.neo4j.driver.Value; +import org.neo4j.driver.async.AsyncTransaction; +import org.neo4j.driver.async.ResultCursor; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.internal.InternalRecord; +import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionProvider; +import org.neo4j.driver.internal.util.Futures; +import org.neo4j.driver.internal.value.IntegerValue; +import org.neo4j.driver.summary.ResultSummary; + +class InternalAsyncTransactionTest { private Connection connection; private NetworkSession networkSession; private InternalAsyncTransaction tx; @BeforeEach - void setUp() - { - connection = connectionMock( BoltProtocolV4.INSTANCE ); - ConnectionProvider connectionProvider = mock( ConnectionProvider.class ); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) - .thenReturn( completedFuture( connection ) ); + void setUp() { + connection = connectionMock(BoltProtocolV4.INSTANCE); + ConnectionProvider connectionProvider = mock(ConnectionProvider.class); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))) + .thenReturn(completedFuture(connection)); networkSession = newSession(connectionProvider); InternalAsyncSession session = new InternalAsyncSession(networkSession); - tx = (InternalAsyncTransaction) await( session.beginTransactionAsync() ); + tx = (InternalAsyncTransaction) await(session.beginTransactionAsync()); } - private static Stream>> allSessionRunMethods() - { + private static Stream>> allSessionRunMethods() { return Stream.of( - tx -> tx.runAsync( "RETURN 1" ), - tx -> tx.runAsync( "RETURN $x", parameters( "x", 1 ) ), - tx -> tx.runAsync( "RETURN $x", singletonMap( "x", 1 ) ), - tx -> tx.runAsync( "RETURN $x", - new InternalRecord( singletonList( "x" ), new Value[]{new IntegerValue( 1 )} ) ), - tx -> tx.runAsync( new Query( "RETURN $x", parameters( "x", 1 ) ) ) - ); + tx -> tx.runAsync("RETURN 1"), + tx -> tx.runAsync("RETURN $x", parameters("x", 1)), + tx -> tx.runAsync("RETURN $x", singletonMap("x", 1)), + tx -> tx.runAsync( + "RETURN $x", new InternalRecord(singletonList("x"), new Value[] {new IntegerValue(1)})), + tx -> tx.runAsync(new Query("RETURN $x", parameters("x", 1)))); } @ParameterizedTest - @MethodSource( "allSessionRunMethods" ) - void shouldFlushOnRun( Function> runReturnOne ) - { - setupSuccessfulRunAndPull( connection ); + @MethodSource("allSessionRunMethods") + void shouldFlushOnRun(Function> runReturnOne) { + setupSuccessfulRunAndPull(connection); - ResultCursor result = await( runReturnOne.apply( tx ) ); - ResultSummary summary = await( result.consumeAsync() ); + ResultCursor result = await(runReturnOne.apply(tx)); + ResultSummary summary = await(result.consumeAsync()); - verifyRunAndPull( connection, summary.query().text() ); + verifyRunAndPull(connection, summary.query().text()); } @Test - void shouldCommit() - { - await( tx.commitAsync() ); + void shouldCommit() { + await(tx.commitAsync()); - verifyCommitTx( connection ); - verify( connection ).release(); - assertFalse( tx.isOpen() ); + verifyCommitTx(connection); + verify(connection).release(); + assertFalse(tx.isOpen()); } @Test - void shouldRollback() - { - await( tx.rollbackAsync() ); + void shouldRollback() { + await(tx.rollbackAsync()); - verifyRollbackTx( connection ); - verify( connection ).release(); - assertFalse( tx.isOpen() ); + verifyRollbackTx(connection); + verify(connection).release(); + assertFalse(tx.isOpen()); } @Test - void shouldRollbackWhenFailedRun() - { - Futures.blockingGet( networkSession.resetAsync() ); - ClientException clientException = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - - assertThat( clientException.getMessage(), containsString( "It has been rolled back either because of an error or explicit termination" ) ); - verify( connection ).release(); - assertFalse( tx.isOpen() ); + void shouldRollbackWhenFailedRun() { + Futures.blockingGet(networkSession.resetAsync()); + ClientException clientException = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + + assertThat( + clientException.getMessage(), + containsString("It has been rolled back either because of an error or explicit termination")); + verify(connection).release(); + assertFalse(tx.isOpen()); } @Test - void shouldReleaseConnectionWhenFailedToCommit() - { - setupFailingCommit( connection ); - assertThrows( Exception.class, () -> await( tx.commitAsync() ) ); + void shouldReleaseConnectionWhenFailedToCommit() { + setupFailingCommit(connection); + assertThrows(Exception.class, () -> await(tx.commitAsync())); - verify( connection ).release(); - assertFalse( tx.isOpen() ); + verify(connection).release(); + assertFalse(tx.isOpen()); } @Test - void shouldReleaseConnectionWhenFailedToRollback() - { - setupFailingRollback( connection ); - assertThrows( Exception.class, () -> await( tx.rollbackAsync() ) ); + void shouldReleaseConnectionWhenFailedToRollback() { + setupFailingRollback(connection); + assertThrows(Exception.class, () -> await(tx.rollbackAsync())); - verify( connection ).release(); - assertFalse( tx.isOpen() ); + verify(connection).release(); + assertFalse(tx.isOpen()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java index d0af1ffe8d..46f16bfa27 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java @@ -18,22 +18,6 @@ */ package org.neo4j.driver.internal.async; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInfo; -import org.mockito.ArgumentCaptor; - -import java.lang.reflect.Method; - -import org.neo4j.driver.Logger; -import org.neo4j.driver.Logging; -import org.neo4j.driver.TransactionConfig; -import org.neo4j.driver.internal.DefaultBookmarkHolder; -import org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionProvider; -import org.neo4j.driver.internal.util.FixedRetryLogic; -import org.neo4j.driver.util.TestUtil; - import static java.util.concurrent.CompletableFuture.completedFuture; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.junit.MatcherAssert.assertThat; @@ -48,71 +32,86 @@ import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; import static org.neo4j.driver.util.TestUtil.DEFAULT_TEST_PROTOCOL; -class LeakLoggingNetworkSessionTest -{ +import java.lang.reflect.Method; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.mockito.ArgumentCaptor; +import org.neo4j.driver.Logger; +import org.neo4j.driver.Logging; +import org.neo4j.driver.TransactionConfig; +import org.neo4j.driver.internal.DefaultBookmarkHolder; +import org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionProvider; +import org.neo4j.driver.internal.util.FixedRetryLogic; +import org.neo4j.driver.util.TestUtil; + +class LeakLoggingNetworkSessionTest { @Test - void logsNothingDuringFinalizationIfClosed() throws Exception - { - Logging logging = mock( Logging.class ); - Logger log = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( log ); - LeakLoggingNetworkSession session = newSession( logging, false ); + void logsNothingDuringFinalizationIfClosed() throws Exception { + Logging logging = mock(Logging.class); + Logger log = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(log); + LeakLoggingNetworkSession session = newSession(logging, false); - finalize( session ); + finalize(session); - verify( log, never() ).error( anyString(), any( Throwable.class ) ); + verify(log, never()).error(anyString(), any(Throwable.class)); } @Test - void logsMessageWithStacktraceDuringFinalizationIfLeaked( TestInfo testInfo ) throws Exception - { - Logging logging = mock( Logging.class ); - Logger log = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( log ); - LeakLoggingNetworkSession session = newSession( logging, true ); + void logsMessageWithStacktraceDuringFinalizationIfLeaked(TestInfo testInfo) throws Exception { + Logging logging = mock(Logging.class); + Logger log = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(log); + LeakLoggingNetworkSession session = newSession(logging, true); // begin transaction to make session obtain a connection - session.beginTransactionAsync( TransactionConfig.empty() ); + session.beginTransactionAsync(TransactionConfig.empty()); - finalize( session ); + finalize(session); - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass( String.class ); - verify( log ).error( messageCaptor.capture(), any() ); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(log).error(messageCaptor.capture(), any()); - assertEquals( 1, messageCaptor.getAllValues().size() ); + assertEquals(1, messageCaptor.getAllValues().size()); String loggedMessage = messageCaptor.getValue(); - assertThat( loggedMessage, containsString( "Neo4j Session object leaked" ) ); - assertThat( loggedMessage, containsString( "Session was create at" ) ); - assertThat( loggedMessage, containsString( - getClass().getSimpleName() + "." + testInfo.getTestMethod().get().getName() ) - ); + assertThat(loggedMessage, containsString("Neo4j Session object leaked")); + assertThat(loggedMessage, containsString("Session was create at")); + assertThat( + loggedMessage, + containsString(getClass().getSimpleName() + "." + + testInfo.getTestMethod().get().getName())); } - private static void finalize( NetworkSession session ) throws Exception - { - Method finalizeMethod = session.getClass().getDeclaredMethod( "finalize" ); - finalizeMethod.setAccessible( true ); - finalizeMethod.invoke( session ); + private static void finalize(NetworkSession session) throws Exception { + Method finalizeMethod = session.getClass().getDeclaredMethod("finalize"); + finalizeMethod.setAccessible(true); + finalizeMethod.invoke(session); } - private static LeakLoggingNetworkSession newSession( Logging logging, boolean openConnection ) - { - return new LeakLoggingNetworkSession( connectionProviderMock( openConnection ), new FixedRetryLogic( 0 ), defaultDatabase(), READ, - new DefaultBookmarkHolder(), null, FetchSizeUtil.UNLIMITED_FETCH_SIZE, logging ); + private static LeakLoggingNetworkSession newSession(Logging logging, boolean openConnection) { + return new LeakLoggingNetworkSession( + connectionProviderMock(openConnection), + new FixedRetryLogic(0), + defaultDatabase(), + READ, + new DefaultBookmarkHolder(), + null, + FetchSizeUtil.UNLIMITED_FETCH_SIZE, + logging); } - private static ConnectionProvider connectionProviderMock( boolean openConnection ) - { - ConnectionProvider provider = mock( ConnectionProvider.class ); - Connection connection = connectionMock( openConnection ); - when( provider.acquireConnection( any( ConnectionContext.class ) ) ).thenReturn( completedFuture( connection ) ); + private static ConnectionProvider connectionProviderMock(boolean openConnection) { + ConnectionProvider provider = mock(ConnectionProvider.class); + Connection connection = connectionMock(openConnection); + when(provider.acquireConnection(any(ConnectionContext.class))).thenReturn(completedFuture(connection)); return provider; } - private static Connection connectionMock( boolean open ) - { - Connection connection = TestUtil.connectionMock( DEFAULT_TEST_PROTOCOL ); - when( connection.isOpen() ).thenReturn( open ); + private static Connection connectionMock(boolean open) { + Connection connection = TestUtil.connectionMock(DEFAULT_TEST_PROTOCOL); + when(connection.isOpen()).thenReturn(open); return connection; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/NetworkConnectionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/NetworkConnectionTest.java index c67018f113..c6e983169d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/NetworkConnectionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/NetworkConnectionTest.java @@ -18,14 +18,32 @@ */ package org.neo4j.driver.internal.async; +import static java.util.Collections.emptyMap; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.terminationReason; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; +import static org.neo4j.driver.internal.util.Iterables.single; +import static org.neo4j.driver.util.DaemonThreadFactory.daemon; +import static org.neo4j.driver.util.TestUtil.DEFAULT_TEST_PROTOCOL_VERSION; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; + import io.netty.channel.Channel; import io.netty.channel.DefaultEventLoop; import io.netty.channel.EventLoop; import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -34,7 +52,9 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.neo4j.driver.Query; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.connection.ChannelAttributes; @@ -47,367 +67,346 @@ import org.neo4j.driver.internal.util.FakeClock; import org.neo4j.driver.internal.util.ServerVersion; -import static java.util.Collections.emptyMap; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.terminationReason; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; -import static org.neo4j.driver.internal.util.Iterables.single; -import static org.neo4j.driver.util.DaemonThreadFactory.daemon; -import static org.neo4j.driver.util.TestUtil.DEFAULT_TEST_PROTOCOL_VERSION; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; - -class NetworkConnectionTest -{ +class NetworkConnectionTest { private static final NoOpResponseHandler NO_OP_HANDLER = NoOpResponseHandler.INSTANCE; private ExecutorService executor; private EventLoop eventLoop; @AfterEach - void tearDown() throws Exception - { + void tearDown() throws Exception { shutdownEventLoop(); } @Test - void shouldBeOpenAfterCreated() - { - NetworkConnection connection = newConnection( newChannel() ); - assertTrue( connection.isOpen() ); + void shouldBeOpenAfterCreated() { + NetworkConnection connection = newConnection(newChannel()); + assertTrue(connection.isOpen()); } @Test - void shouldNotBeOpenAfterRelease() - { - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotBeOpenAfterRelease() { + NetworkConnection connection = newConnection(newChannel()); connection.release(); - assertFalse( connection.isOpen() ); + assertFalse(connection.isOpen()); } @Test - void shouldSendResetOnRelease() - { + void shouldSendResetOnRelease() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.release(); channel.runPendingTasks(); - assertEquals( 1, channel.outboundMessages().size() ); - assertEquals( RESET, channel.readOutbound() ); + assertEquals(1, channel.outboundMessages().size()); + assertEquals(RESET, channel.readOutbound()); } @Test - void shouldWriteInEventLoopThread() throws Exception - { - testWriteInEventLoop( "WriteSingleMessage", - connection -> connection.write( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), NO_OP_HANDLER ) ); + void shouldWriteInEventLoopThread() throws Exception { + testWriteInEventLoop( + "WriteSingleMessage", + connection -> connection.write( + RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), NO_OP_HANDLER)); - testWriteInEventLoop( "WriteMultipleMessages", - connection -> connection.write( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), NO_OP_HANDLER, PULL_ALL, - NO_OP_HANDLER ) ); + testWriteInEventLoop( + "WriteMultipleMessages", + connection -> connection.write( + RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), + NO_OP_HANDLER, + PULL_ALL, + NO_OP_HANDLER)); } @Test - void shouldWriteAndFlushInEventLoopThread() throws Exception - { - testWriteInEventLoop( "WriteAndFlushSingleMessage", - connection -> connection.writeAndFlush( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), - NO_OP_HANDLER ) ); + void shouldWriteAndFlushInEventLoopThread() throws Exception { + testWriteInEventLoop( + "WriteAndFlushSingleMessage", + connection -> connection.writeAndFlush( + RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), NO_OP_HANDLER)); - testWriteInEventLoop( "WriteAndFlushMultipleMessages", - connection -> connection.writeAndFlush( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), NO_OP_HANDLER, - PULL_ALL, NO_OP_HANDLER ) ); + testWriteInEventLoop( + "WriteAndFlushMultipleMessages", + connection -> connection.writeAndFlush( + RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), + NO_OP_HANDLER, + PULL_ALL, + NO_OP_HANDLER)); } @Test - void shouldWriteForceReleaseInEventLoopThread() throws Exception - { - testWriteInEventLoop( "ReleaseTestEventLoop", NetworkConnection::release ); + void shouldWriteForceReleaseInEventLoopThread() throws Exception { + testWriteInEventLoop("ReleaseTestEventLoop", NetworkConnection::release); } @Test - void shouldFlushInEventLoopThread() throws Exception - { - EmbeddedChannel channel = spy( new EmbeddedChannel() ); - initializeEventLoop( channel, "Flush" ); - ChannelAttributes.setProtocolVersion( channel, DEFAULT_TEST_PROTOCOL_VERSION ); + void shouldFlushInEventLoopThread() throws Exception { + EmbeddedChannel channel = spy(new EmbeddedChannel()); + initializeEventLoop(channel, "Flush"); + ChannelAttributes.setProtocolVersion(channel, DEFAULT_TEST_PROTOCOL_VERSION); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.flush(); shutdownEventLoop(); - verify( channel ).flush(); + verify(channel).flush(); } @Test - void shouldEnableAutoReadWhenReleased() - { + void shouldEnableAutoReadWhenReleased() { EmbeddedChannel channel = newChannel(); - channel.config().setAutoRead( false ); + channel.config().setAutoRead(false); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.release(); channel.runPendingTasks(); - assertTrue( channel.config().isAutoRead() ); + assertTrue(channel.config().isAutoRead()); } @Test - void shouldNotDisableAutoReadWhenReleased() - { + void shouldNotDisableAutoReadWhenReleased() { EmbeddedChannel channel = newChannel(); - channel.config().setAutoRead( true ); + channel.config().setAutoRead(true); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.release(); connection.disableAutoRead(); // does nothing on released connection - assertTrue( channel.config().isAutoRead() ); + assertTrue(channel.config().isAutoRead()); } @Test - void shouldWriteSingleMessage() - { + void shouldWriteSingleMessage() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); - connection.write( PULL_ALL, NO_OP_HANDLER ); + connection.write(PULL_ALL, NO_OP_HANDLER); - assertEquals( 0, channel.outboundMessages().size() ); + assertEquals(0, channel.outboundMessages().size()); channel.flushOutbound(); - assertEquals( 1, channel.outboundMessages().size() ); - assertEquals( PULL_ALL, single( channel.outboundMessages() ) ); + assertEquals(1, channel.outboundMessages().size()); + assertEquals(PULL_ALL, single(channel.outboundMessages())); } @Test - void shouldWriteMultipleMessage() - { + void shouldWriteMultipleMessage() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); - connection.write( PULL_ALL, NO_OP_HANDLER, RESET, NO_OP_HANDLER ); + connection.write(PULL_ALL, NO_OP_HANDLER, RESET, NO_OP_HANDLER); - assertEquals( 0, channel.outboundMessages().size() ); + assertEquals(0, channel.outboundMessages().size()); channel.flushOutbound(); - assertEquals( 2, channel.outboundMessages().size() ); - assertEquals( PULL_ALL, channel.outboundMessages().poll() ); - assertEquals( RESET, channel.outboundMessages().poll() ); + assertEquals(2, channel.outboundMessages().size()); + assertEquals(PULL_ALL, channel.outboundMessages().poll()); + assertEquals(RESET, channel.outboundMessages().poll()); } @Test - void shouldWriteAndFlushSingleMessage() - { + void shouldWriteAndFlushSingleMessage() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); - connection.writeAndFlush( PULL_ALL, NO_OP_HANDLER ); - channel.runPendingTasks(); // writeAndFlush is scheduled to execute in the event loop thread, trigger its execution + connection.writeAndFlush(PULL_ALL, NO_OP_HANDLER); + channel.runPendingTasks(); // writeAndFlush is scheduled to execute in the event loop thread, trigger its + // execution - assertEquals( 1, channel.outboundMessages().size() ); - assertEquals( PULL_ALL, single( channel.outboundMessages() ) ); + assertEquals(1, channel.outboundMessages().size()); + assertEquals(PULL_ALL, single(channel.outboundMessages())); } @Test - void shouldWriteAndFlushMultipleMessage() - { + void shouldWriteAndFlushMultipleMessage() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); - connection.writeAndFlush( PULL_ALL, NO_OP_HANDLER, RESET, NO_OP_HANDLER ); - channel.runPendingTasks(); // writeAndFlush is scheduled to execute in the event loop thread, trigger its execution + connection.writeAndFlush(PULL_ALL, NO_OP_HANDLER, RESET, NO_OP_HANDLER); + channel.runPendingTasks(); // writeAndFlush is scheduled to execute in the event loop thread, trigger its + // execution - assertEquals( 2, channel.outboundMessages().size() ); - assertEquals( PULL_ALL, channel.outboundMessages().poll() ); - assertEquals( RESET, channel.outboundMessages().poll() ); + assertEquals(2, channel.outboundMessages().size()); + assertEquals(PULL_ALL, channel.outboundMessages().poll()); + assertEquals(RESET, channel.outboundMessages().poll()); } @Test - void shouldNotWriteSingleMessageWhenReleased() - { - ResponseHandler handler = mock( ResponseHandler.class ); - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotWriteSingleMessageWhenReleased() { + ResponseHandler handler = mock(ResponseHandler.class); + NetworkConnection connection = newConnection(newChannel()); connection.release(); - connection.write( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), handler ); + connection.write(RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), handler); - ArgumentCaptor failureCaptor = ArgumentCaptor.forClass( IllegalStateException.class ); - verify( handler ).onFailure( failureCaptor.capture() ); - assertConnectionReleasedError( failureCaptor.getValue() ); + ArgumentCaptor failureCaptor = ArgumentCaptor.forClass(IllegalStateException.class); + verify(handler).onFailure(failureCaptor.capture()); + assertConnectionReleasedError(failureCaptor.getValue()); } @Test - void shouldNotWriteMultipleMessagesWhenReleased() - { - ResponseHandler runHandler = mock( ResponseHandler.class ); - ResponseHandler pullAllHandler = mock( ResponseHandler.class ); - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotWriteMultipleMessagesWhenReleased() { + ResponseHandler runHandler = mock(ResponseHandler.class); + ResponseHandler pullAllHandler = mock(ResponseHandler.class); + NetworkConnection connection = newConnection(newChannel()); connection.release(); - connection.write( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), runHandler, PULL_ALL, pullAllHandler ); + connection.write( + RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), + runHandler, + PULL_ALL, + pullAllHandler); - ArgumentCaptor failureCaptor = ArgumentCaptor.forClass( IllegalStateException.class ); - verify( runHandler ).onFailure( failureCaptor.capture() ); - assertConnectionReleasedError( failureCaptor.getValue() ); + ArgumentCaptor failureCaptor = ArgumentCaptor.forClass(IllegalStateException.class); + verify(runHandler).onFailure(failureCaptor.capture()); + assertConnectionReleasedError(failureCaptor.getValue()); } @Test - void shouldNotWriteAndFlushSingleMessageWhenReleased() - { - ResponseHandler handler = mock( ResponseHandler.class ); - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotWriteAndFlushSingleMessageWhenReleased() { + ResponseHandler handler = mock(ResponseHandler.class); + NetworkConnection connection = newConnection(newChannel()); connection.release(); - connection.writeAndFlush( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), handler ); + connection.writeAndFlush(RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), handler); - ArgumentCaptor failureCaptor = ArgumentCaptor.forClass( IllegalStateException.class ); - verify( handler ).onFailure( failureCaptor.capture() ); - assertConnectionReleasedError( failureCaptor.getValue() ); + ArgumentCaptor failureCaptor = ArgumentCaptor.forClass(IllegalStateException.class); + verify(handler).onFailure(failureCaptor.capture()); + assertConnectionReleasedError(failureCaptor.getValue()); } @Test - void shouldNotWriteAndFlushMultipleMessagesWhenReleased() - { - ResponseHandler runHandler = mock( ResponseHandler.class ); - ResponseHandler pullAllHandler = mock( ResponseHandler.class ); - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotWriteAndFlushMultipleMessagesWhenReleased() { + ResponseHandler runHandler = mock(ResponseHandler.class); + ResponseHandler pullAllHandler = mock(ResponseHandler.class); + NetworkConnection connection = newConnection(newChannel()); connection.release(); - connection.writeAndFlush( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), runHandler, PULL_ALL, pullAllHandler ); + connection.writeAndFlush( + RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), + runHandler, + PULL_ALL, + pullAllHandler); - ArgumentCaptor failureCaptor = ArgumentCaptor.forClass( IllegalStateException.class ); - verify( runHandler ).onFailure( failureCaptor.capture() ); - assertConnectionReleasedError( failureCaptor.getValue() ); + ArgumentCaptor failureCaptor = ArgumentCaptor.forClass(IllegalStateException.class); + verify(runHandler).onFailure(failureCaptor.capture()); + assertConnectionReleasedError(failureCaptor.getValue()); } @Test - void shouldNotWriteSingleMessageWhenTerminated() - { - ResponseHandler handler = mock( ResponseHandler.class ); - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotWriteSingleMessageWhenTerminated() { + ResponseHandler handler = mock(ResponseHandler.class); + NetworkConnection connection = newConnection(newChannel()); - connection.terminateAndRelease( "42" ); - connection.write( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), handler ); + connection.terminateAndRelease("42"); + connection.write(RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), handler); - ArgumentCaptor failureCaptor = ArgumentCaptor.forClass( IllegalStateException.class ); - verify( handler ).onFailure( failureCaptor.capture() ); - assertConnectionTerminatedError( failureCaptor.getValue() ); + ArgumentCaptor failureCaptor = ArgumentCaptor.forClass(IllegalStateException.class); + verify(handler).onFailure(failureCaptor.capture()); + assertConnectionTerminatedError(failureCaptor.getValue()); } @Test - void shouldNotWriteMultipleMessagesWhenTerminated() - { - ResponseHandler runHandler = mock( ResponseHandler.class ); - ResponseHandler pullAllHandler = mock( ResponseHandler.class ); - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotWriteMultipleMessagesWhenTerminated() { + ResponseHandler runHandler = mock(ResponseHandler.class); + ResponseHandler pullAllHandler = mock(ResponseHandler.class); + NetworkConnection connection = newConnection(newChannel()); - connection.terminateAndRelease( "42" ); - connection.write( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), runHandler, PULL_ALL, pullAllHandler ); + connection.terminateAndRelease("42"); + connection.write( + RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), + runHandler, + PULL_ALL, + pullAllHandler); - ArgumentCaptor failureCaptor = ArgumentCaptor.forClass( IllegalStateException.class ); - verify( runHandler ).onFailure( failureCaptor.capture() ); - assertConnectionTerminatedError( failureCaptor.getValue() ); + ArgumentCaptor failureCaptor = ArgumentCaptor.forClass(IllegalStateException.class); + verify(runHandler).onFailure(failureCaptor.capture()); + assertConnectionTerminatedError(failureCaptor.getValue()); } @Test - void shouldNotWriteAndFlushSingleMessageWhenTerminated() - { - ResponseHandler handler = mock( ResponseHandler.class ); - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotWriteAndFlushSingleMessageWhenTerminated() { + ResponseHandler handler = mock(ResponseHandler.class); + NetworkConnection connection = newConnection(newChannel()); - connection.terminateAndRelease( "42" ); - connection.writeAndFlush( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), handler ); + connection.terminateAndRelease("42"); + connection.writeAndFlush(RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), handler); - ArgumentCaptor failureCaptor = ArgumentCaptor.forClass( IllegalStateException.class ); - verify( handler ).onFailure( failureCaptor.capture() ); - assertConnectionTerminatedError( failureCaptor.getValue() ); + ArgumentCaptor failureCaptor = ArgumentCaptor.forClass(IllegalStateException.class); + verify(handler).onFailure(failureCaptor.capture()); + assertConnectionTerminatedError(failureCaptor.getValue()); } @Test - void shouldNotWriteAndFlushMultipleMessagesWhenTerminated() - { - ResponseHandler runHandler = mock( ResponseHandler.class ); - ResponseHandler pullAllHandler = mock( ResponseHandler.class ); - NetworkConnection connection = newConnection( newChannel() ); + void shouldNotWriteAndFlushMultipleMessagesWhenTerminated() { + ResponseHandler runHandler = mock(ResponseHandler.class); + ResponseHandler pullAllHandler = mock(ResponseHandler.class); + NetworkConnection connection = newConnection(newChannel()); - connection.terminateAndRelease( "42" ); - connection.writeAndFlush( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 1" ) ), runHandler, PULL_ALL, pullAllHandler ); + connection.terminateAndRelease("42"); + connection.writeAndFlush( + RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 1")), + runHandler, + PULL_ALL, + pullAllHandler); - ArgumentCaptor failureCaptor = ArgumentCaptor.forClass( IllegalStateException.class ); - verify( runHandler ).onFailure( failureCaptor.capture() ); - assertConnectionTerminatedError( failureCaptor.getValue() ); + ArgumentCaptor failureCaptor = ArgumentCaptor.forClass(IllegalStateException.class); + verify(runHandler).onFailure(failureCaptor.capture()); + assertConnectionTerminatedError(failureCaptor.getValue()); } @Test - void shouldReturnServerAgentWhenCreated() - { + void shouldReturnServerAgentWhenCreated() { EmbeddedChannel channel = newChannel(); String agent = "Neo4j/4.2.5"; - ChannelAttributes.setServerAgent( channel, agent ); + ChannelAttributes.setServerAgent(channel, agent); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); - assertEquals( agent, connection.serverAgent() ); + assertEquals(agent, connection.serverAgent()); } @Test - void shouldReturnServerAgentWhenReleased() - { + void shouldReturnServerAgentWhenReleased() { EmbeddedChannel channel = newChannel(); String agent = "Neo4j/4.2.5"; - ChannelAttributes.setServerAgent( channel, agent ); + ChannelAttributes.setServerAgent(channel, agent); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.release(); - assertEquals( agent, connection.serverAgent() ); + assertEquals(agent, connection.serverAgent()); } @Test - void shouldReturnServerAddressWhenReleased() - { + void shouldReturnServerAddressWhenReleased() { EmbeddedChannel channel = newChannel(); - BoltServerAddress address = new BoltServerAddress( "host", 4242 ); - ChannelAttributes.setServerAddress( channel, address ); + BoltServerAddress address = new BoltServerAddress("host", 4242); + ChannelAttributes.setServerAddress(channel, address); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.release(); - assertEquals( address, connection.serverAddress() ); + assertEquals(address, connection.serverAddress()); } @Test - void shouldReturnServerVersionWhenReleased() - { + void shouldReturnServerVersionWhenReleased() { EmbeddedChannel channel = newChannel(); ServerVersion version = anyServerVersion(); - ChannelAttributes.setServerVersion( channel, version ); + ChannelAttributes.setServerVersion(channel, version); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.release(); - assertEquals( version, connection.serverVersion() ); + assertEquals(version, connection.serverVersion()); } @Test - void shouldReturnSameCompletionStageFromRelease() - { + void shouldReturnSameCompletionStageFromRelease() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); CompletionStage releaseStage1 = connection.release(); CompletionStage releaseStage2 = connection.release(); @@ -416,158 +415,147 @@ void shouldReturnSameCompletionStageFromRelease() channel.runPendingTasks(); // RESET should be send only once - assertEquals( 1, channel.outboundMessages().size() ); - assertEquals( RESET, channel.outboundMessages().poll() ); + assertEquals(1, channel.outboundMessages().size()); + assertEquals(RESET, channel.outboundMessages().poll()); // all returned stages should be the same - assertEquals( releaseStage1, releaseStage2 ); - assertEquals( releaseStage2, releaseStage3 ); + assertEquals(releaseStage1, releaseStage2); + assertEquals(releaseStage2, releaseStage3); } @Test - void shouldEnableAutoRead() - { + void shouldEnableAutoRead() { EmbeddedChannel channel = newChannel(); - channel.config().setAutoRead( false ); - NetworkConnection connection = newConnection( channel ); + channel.config().setAutoRead(false); + NetworkConnection connection = newConnection(channel); connection.enableAutoRead(); - assertTrue( channel.config().isAutoRead() ); + assertTrue(channel.config().isAutoRead()); } @Test - void shouldDisableAutoRead() - { + void shouldDisableAutoRead() { EmbeddedChannel channel = newChannel(); - channel.config().setAutoRead( true ); - NetworkConnection connection = newConnection( channel ); + channel.config().setAutoRead(true); + NetworkConnection connection = newConnection(channel); connection.disableAutoRead(); - assertFalse( channel.config().isAutoRead() ); + assertFalse(channel.config().isAutoRead()); } @Test - void shouldSetTerminationReasonOnChannelWhenTerminated() - { + void shouldSetTerminationReasonOnChannelWhenTerminated() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); String reason = "Something really bad has happened"; - connection.terminateAndRelease( reason ); + connection.terminateAndRelease(reason); - assertEquals( reason, terminationReason( channel ) ); + assertEquals(reason, terminationReason(channel)); } @Test - void shouldCloseChannelWhenTerminated() - { + void shouldCloseChannelWhenTerminated() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); - assertTrue( channel.isActive() ); + NetworkConnection connection = newConnection(channel); + assertTrue(channel.isActive()); - connection.terminateAndRelease( "test" ); + connection.terminateAndRelease("test"); - assertFalse( channel.isActive() ); + assertFalse(channel.isActive()); } @Test - void shouldReleaseChannelWhenTerminated() - { + void shouldReleaseChannelWhenTerminated() { EmbeddedChannel channel = newChannel(); - ExtendedChannelPool pool = mock( ExtendedChannelPool.class ); - NetworkConnection connection = newConnection( channel, pool ); - verify( pool, never() ).release( any() ); + ExtendedChannelPool pool = mock(ExtendedChannelPool.class); + NetworkConnection connection = newConnection(channel, pool); + verify(pool, never()).release(any()); - connection.terminateAndRelease( "test" ); + connection.terminateAndRelease("test"); - verify( pool ).release( channel ); + verify(pool).release(channel); } @Test - void shouldNotReleaseChannelMultipleTimesWhenTerminatedMultipleTimes() - { + void shouldNotReleaseChannelMultipleTimesWhenTerminatedMultipleTimes() { EmbeddedChannel channel = newChannel(); - ExtendedChannelPool pool = mock( ExtendedChannelPool.class ); - NetworkConnection connection = newConnection( channel, pool ); - verify( pool, never() ).release( any() ); + ExtendedChannelPool pool = mock(ExtendedChannelPool.class); + NetworkConnection connection = newConnection(channel, pool); + verify(pool, never()).release(any()); - connection.terminateAndRelease( "reason 1" ); - connection.terminateAndRelease( "reason 2" ); - connection.terminateAndRelease( "reason 3" ); + connection.terminateAndRelease("reason 1"); + connection.terminateAndRelease("reason 2"); + connection.terminateAndRelease("reason 3"); // channel is terminated with the first termination reason - assertEquals( "reason 1", terminationReason( channel ) ); + assertEquals("reason 1", terminationReason(channel)); // channel is released to the pool only once - verify( pool ).release( channel ); + verify(pool).release(channel); } @Test - void shouldNotReleaseAfterTermination() - { + void shouldNotReleaseAfterTermination() { EmbeddedChannel channel = newChannel(); - ExtendedChannelPool pool = mock( ExtendedChannelPool.class ); - NetworkConnection connection = newConnection( channel, pool ); - verify( pool, never() ).release( any() ); + ExtendedChannelPool pool = mock(ExtendedChannelPool.class); + NetworkConnection connection = newConnection(channel, pool); + verify(pool, never()).release(any()); - connection.terminateAndRelease( "test" ); + connection.terminateAndRelease("test"); CompletionStage releaseStage = connection.release(); // release stage should be completed immediately - assertTrue( releaseStage.toCompletableFuture().isDone() ); + assertTrue(releaseStage.toCompletableFuture().isDone()); // channel is released to the pool only once - verify( pool ).release( channel ); + verify(pool).release(channel); } @Test - void shouldSendResetMessageWhenReset() - { + void shouldSendResetMessageWhenReset() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.reset(); channel.runPendingTasks(); - assertEquals( 1, channel.outboundMessages().size() ); - assertEquals( RESET, channel.readOutbound() ); + assertEquals(1, channel.outboundMessages().size()); + assertEquals(RESET, channel.readOutbound()); } @Test - void shouldCompleteResetFutureWhenSuccessResponseArrives() - { + void shouldCompleteResetFutureWhenSuccessResponseArrives() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); CompletableFuture resetFuture = connection.reset().toCompletableFuture(); channel.runPendingTasks(); - assertFalse( resetFuture.isDone() ); + assertFalse(resetFuture.isDone()); - messageDispatcher( channel ).handleSuccessMessage( emptyMap() ); - assertTrue( resetFuture.isDone() ); - assertFalse( resetFuture.isCompletedExceptionally() ); + messageDispatcher(channel).handleSuccessMessage(emptyMap()); + assertTrue(resetFuture.isDone()); + assertFalse(resetFuture.isCompletedExceptionally()); } @Test - void shouldCompleteResetFutureWhenFailureResponseArrives() - { + void shouldCompleteResetFutureWhenFailureResponseArrives() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); CompletableFuture resetFuture = connection.reset().toCompletableFuture(); channel.runPendingTasks(); - assertFalse( resetFuture.isDone() ); + assertFalse(resetFuture.isDone()); - messageDispatcher( channel ).handleFailureMessage( "Neo.TransientError.Transaction.Terminated", "Message" ); - assertTrue( resetFuture.isDone() ); - assertFalse( resetFuture.isCompletedExceptionally() ); + messageDispatcher(channel).handleFailureMessage("Neo.TransientError.Transaction.Terminated", "Message"); + assertTrue(resetFuture.isDone()); + assertFalse(resetFuture.isCompletedExceptionally()); } @Test - void shouldDoNothingInResetWhenClosed() - { + void shouldDoNothingInResetWhenClosed() { EmbeddedChannel channel = newChannel(); - NetworkConnection connection = newConnection( channel ); + NetworkConnection connection = newConnection(channel); connection.release(); channel.runPendingTasks(); @@ -575,104 +563,90 @@ void shouldDoNothingInResetWhenClosed() CompletableFuture resetFuture = connection.reset().toCompletableFuture(); channel.runPendingTasks(); - assertEquals( 1, channel.outboundMessages().size() ); - assertEquals( RESET, channel.readOutbound() ); - assertTrue( resetFuture.isDone() ); - assertFalse( resetFuture.isCompletedExceptionally() ); + assertEquals(1, channel.outboundMessages().size()); + assertEquals(RESET, channel.readOutbound()); + assertTrue(resetFuture.isDone()); + assertFalse(resetFuture.isCompletedExceptionally()); } @Test - void shouldEnableAutoReadWhenDoingReset() - { + void shouldEnableAutoReadWhenDoingReset() { EmbeddedChannel channel = newChannel(); - channel.config().setAutoRead( false ); - NetworkConnection connection = newConnection( channel ); + channel.config().setAutoRead(false); + NetworkConnection connection = newConnection(channel); connection.reset(); channel.runPendingTasks(); - assertTrue( channel.config().isAutoRead() ); + assertTrue(channel.config().isAutoRead()); } - private void testWriteInEventLoop( String threadName, Consumer action ) throws Exception - { - EmbeddedChannel channel = spy( new EmbeddedChannel() ); - initializeEventLoop( channel, threadName ); - ThreadTrackingInboundMessageDispatcher dispatcher = new ThreadTrackingInboundMessageDispatcher( channel ); - ChannelAttributes.setProtocolVersion( channel, DEFAULT_TEST_PROTOCOL_VERSION ); - ChannelAttributes.setMessageDispatcher( channel, dispatcher ); + private void testWriteInEventLoop(String threadName, Consumer action) throws Exception { + EmbeddedChannel channel = spy(new EmbeddedChannel()); + initializeEventLoop(channel, threadName); + ThreadTrackingInboundMessageDispatcher dispatcher = new ThreadTrackingInboundMessageDispatcher(channel); + ChannelAttributes.setProtocolVersion(channel, DEFAULT_TEST_PROTOCOL_VERSION); + ChannelAttributes.setMessageDispatcher(channel, dispatcher); - NetworkConnection connection = newConnection( channel ); - action.accept( connection ); + NetworkConnection connection = newConnection(channel); + action.accept(connection); shutdownEventLoop(); - assertThat( single( dispatcher.queueThreadNames ), startsWith( threadName ) ); + assertThat(single(dispatcher.queueThreadNames), startsWith(threadName)); } - private void initializeEventLoop( Channel channel, String namePrefix ) - { - executor = Executors.newSingleThreadExecutor( daemon( namePrefix ) ); - eventLoop = new DefaultEventLoop( executor ); - when( channel.eventLoop() ).thenReturn( eventLoop ); + private void initializeEventLoop(Channel channel, String namePrefix) { + executor = Executors.newSingleThreadExecutor(daemon(namePrefix)); + eventLoop = new DefaultEventLoop(executor); + when(channel.eventLoop()).thenReturn(eventLoop); } - private void shutdownEventLoop() throws Exception - { - if ( eventLoop != null ) - { + private void shutdownEventLoop() throws Exception { + if (eventLoop != null) { eventLoop.shutdownGracefully(); } - if ( executor != null ) - { + if (executor != null) { executor.shutdown(); - assertTrue( executor.awaitTermination( 30, TimeUnit.SECONDS ) ); + assertTrue(executor.awaitTermination(30, TimeUnit.SECONDS)); } } - private static EmbeddedChannel newChannel() - { + private static EmbeddedChannel newChannel() { EmbeddedChannel channel = new EmbeddedChannel(); - InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ); - ChannelAttributes.setProtocolVersion( channel, DEFAULT_TEST_PROTOCOL_VERSION ); - ChannelAttributes.setMessageDispatcher( channel, messageDispatcher ); + InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher(channel, DEV_NULL_LOGGING); + ChannelAttributes.setProtocolVersion(channel, DEFAULT_TEST_PROTOCOL_VERSION); + ChannelAttributes.setMessageDispatcher(channel, messageDispatcher); return channel; } - private static NetworkConnection newConnection( Channel channel ) - { - return newConnection( channel, mock( ExtendedChannelPool.class ) ); + private static NetworkConnection newConnection(Channel channel) { + return newConnection(channel, mock(ExtendedChannelPool.class)); } - private static NetworkConnection newConnection( Channel channel, ExtendedChannelPool pool ) - { - return new NetworkConnection( channel, pool, new FakeClock(), DevNullMetricsListener.INSTANCE, DEV_NULL_LOGGING ); + private static NetworkConnection newConnection(Channel channel, ExtendedChannelPool pool) { + return new NetworkConnection(channel, pool, new FakeClock(), DevNullMetricsListener.INSTANCE, DEV_NULL_LOGGING); } - private static void assertConnectionReleasedError( IllegalStateException e ) - { - assertThat( e.getMessage(), startsWith( "Connection has been released" ) ); + private static void assertConnectionReleasedError(IllegalStateException e) { + assertThat(e.getMessage(), startsWith("Connection has been released")); } - private static void assertConnectionTerminatedError( IllegalStateException e ) - { - assertThat( e.getMessage(), startsWith( "Connection has been terminated" ) ); + private static void assertConnectionTerminatedError(IllegalStateException e) { + assertThat(e.getMessage(), startsWith("Connection has been terminated")); } - private static class ThreadTrackingInboundMessageDispatcher extends InboundMessageDispatcher - { + private static class ThreadTrackingInboundMessageDispatcher extends InboundMessageDispatcher { final Set queueThreadNames = ConcurrentHashMap.newKeySet(); - ThreadTrackingInboundMessageDispatcher( Channel channel ) - { - super( channel, DEV_NULL_LOGGING ); + + ThreadTrackingInboundMessageDispatcher(Channel channel) { + super(channel, DEV_NULL_LOGGING); } @Override - public void enqueue( ResponseHandler handler ) - { - queueThreadNames.add( Thread.currentThread().getName() ); - super.enqueue( handler ); + public void enqueue(ResponseHandler handler) { + queueThreadNames.add(Thread.currentThread().getName()); + super.enqueue(handler); } - } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/NetworkSessionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/NetworkSessionTest.java index 303a538594..fe9006dba2 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/NetworkSessionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/NetworkSessionTest.java @@ -18,25 +18,6 @@ */ package org.neo4j.driver.internal.async; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; - -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Bookmark; -import org.neo4j.driver.Query; -import org.neo4j.driver.TransactionConfig; -import org.neo4j.driver.async.ResultCursor; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.internal.InternalBookmark; -import org.neo4j.driver.internal.messaging.BoltProtocol; -import org.neo4j.driver.internal.messaging.request.PullMessage; -import org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage; -import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionProvider; - import static java.util.concurrent.CompletableFuture.completedFuture; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; @@ -70,413 +51,403 @@ import static org.neo4j.driver.util.TestUtil.verifyRunAndPull; import static org.neo4j.driver.util.TestUtil.verifyRunRx; -class NetworkSessionTest -{ +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Bookmark; +import org.neo4j.driver.Query; +import org.neo4j.driver.TransactionConfig; +import org.neo4j.driver.async.ResultCursor; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.internal.InternalBookmark; +import org.neo4j.driver.internal.messaging.BoltProtocol; +import org.neo4j.driver.internal.messaging.request.PullMessage; +import org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage; +import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionProvider; + +class NetworkSessionTest { private Connection connection; private ConnectionProvider connectionProvider; private NetworkSession session; @BeforeEach - void setUp() - { - connection = connectionMock( BoltProtocolV4.INSTANCE ); - connectionProvider = mock( ConnectionProvider.class ); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) - .thenReturn( completedFuture( connection ) ); - session = newSession( connectionProvider ); + void setUp() { + connection = connectionMock(BoltProtocolV4.INSTANCE); + connectionProvider = mock(ConnectionProvider.class); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))) + .thenReturn(completedFuture(connection)); + session = newSession(connectionProvider); } @Test - void shouldFlushOnRunAsync() - { - setupSuccessfulRunAndPull( connection ); - await( session.runAsync( new Query( "RETURN 1" ), TransactionConfig.empty() ) ); + void shouldFlushOnRunAsync() { + setupSuccessfulRunAndPull(connection); + await(session.runAsync(new Query("RETURN 1"), TransactionConfig.empty())); - verifyRunAndPull( connection, "RETURN 1" ); + verifyRunAndPull(connection, "RETURN 1"); } @Test - void shouldFlushOnRunRx() - { - setupSuccessfulRunRx( connection ); - await( session.runRx( new Query( "RETURN 1" ), TransactionConfig.empty() ) ); + void shouldFlushOnRunRx() { + setupSuccessfulRunRx(connection); + await(session.runRx(new Query("RETURN 1"), TransactionConfig.empty())); - verifyRunRx( connection, "RETURN 1" ); + verifyRunRx(connection, "RETURN 1"); } @Test - void shouldNotAllowNewTxWhileOneIsRunning() - { + void shouldNotAllowNewTxWhileOneIsRunning() { // Given - beginTransaction( session ); + beginTransaction(session); // Expect - assertThrows( ClientException.class, () -> beginTransaction( session ) ); + assertThrows(ClientException.class, () -> beginTransaction(session)); } @Test - void shouldBeAbleToOpenTxAfterPreviousIsClosed() - { + void shouldBeAbleToOpenTxAfterPreviousIsClosed() { // Given - await( beginTransaction( session ).closeAsync() ); + await(beginTransaction(session).closeAsync()); // When - UnmanagedTransaction tx = beginTransaction( session ); + UnmanagedTransaction tx = beginTransaction(session); // Then we should've gotten a transaction object back - assertNotNull( tx ); - verifyRollbackTx( connection ); + assertNotNull(tx); + verifyRollbackTx(connection); } @Test - void shouldNotBeAbleToUseSessionWhileOngoingTransaction() - { + void shouldNotBeAbleToUseSessionWhileOngoingTransaction() { // Given - beginTransaction( session ); + beginTransaction(session); // Expect - assertThrows( ClientException.class, () -> run( session, "RETURN 1" ) ); + assertThrows(ClientException.class, () -> run(session, "RETURN 1")); } @Test - void shouldBeAbleToUseSessionAgainWhenTransactionIsClosed() - { + void shouldBeAbleToUseSessionAgainWhenTransactionIsClosed() { // Given - await( beginTransaction( session ).closeAsync() ); + await(beginTransaction(session).closeAsync()); String query = "RETURN 1"; - setupSuccessfulRunAndPull( connection, query ); + setupSuccessfulRunAndPull(connection, query); // When - run( session, query ); + run(session, query); // Then - verifyRunAndPull( connection, query ); + verifyRunAndPull(connection, query); } @Test - void shouldNotCloseAlreadyClosedSession() - { - beginTransaction( session ); + void shouldNotCloseAlreadyClosedSession() { + beginTransaction(session); - close( session ); - close( session ); - close( session ); + close(session); + close(session); + close(session); - verifyRollbackTx( connection ); + verifyRollbackTx(connection); } @Test - void runThrowsWhenSessionIsClosed() - { - close( session ); + void runThrowsWhenSessionIsClosed() { + close(session); - Exception e = assertThrows( Exception.class, () -> run( session, "CREATE ()" ) ); - assertThat( e, instanceOf( ClientException.class ) ); - assertThat( e.getMessage(), containsString( "session is already closed" ) ); + Exception e = assertThrows(Exception.class, () -> run(session, "CREATE ()")); + assertThat(e, instanceOf(ClientException.class)); + assertThat(e.getMessage(), containsString("session is already closed")); } @Test - void acquiresNewConnectionForRun() - { + void acquiresNewConnectionForRun() { String query = "RETURN 1"; - setupSuccessfulRunAndPull( connection, query ); + setupSuccessfulRunAndPull(connection, query); - run( session, query ); + run(session, query); - verify( connectionProvider ).acquireConnection( any( ConnectionContext.class ) ); + verify(connectionProvider).acquireConnection(any(ConnectionContext.class)); } @Test - void releasesOpenConnectionUsedForRunWhenSessionIsClosed() - { + void releasesOpenConnectionUsedForRunWhenSessionIsClosed() { String query = "RETURN 1"; - setupSuccessfulRunAndPull( connection, query ); + setupSuccessfulRunAndPull(connection, query); - run( session, query ); + run(session, query); - close( session ); + close(session); - InOrder inOrder = inOrder( connection ); - inOrder.verify( connection ).write( any( RunWithMetadataMessage.class ), any() ); - inOrder.verify( connection ).writeAndFlush( any( PullMessage.class ), any() ); - inOrder.verify( connection, atLeastOnce() ).release(); + InOrder inOrder = inOrder(connection); + inOrder.verify(connection).write(any(RunWithMetadataMessage.class), any()); + inOrder.verify(connection).writeAndFlush(any(PullMessage.class), any()); + inOrder.verify(connection, atLeastOnce()).release(); } - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") @Test - void resetDoesNothingWhenNoTransactionAndNoConnection() - { - await( session.resetAsync() ); + void resetDoesNothingWhenNoTransactionAndNoConnection() { + await(session.resetAsync()); - verify( connectionProvider, never() ).acquireConnection( any( ConnectionContext.class ) ); + verify(connectionProvider, never()).acquireConnection(any(ConnectionContext.class)); } @Test - void closeWithoutConnection() - { - NetworkSession session = newSession( connectionProvider ); + void closeWithoutConnection() { + NetworkSession session = newSession(connectionProvider); - close( session ); + close(session); - verify( connectionProvider, never() ).acquireConnection( any( ConnectionContext.class ) ); + verify(connectionProvider, never()).acquireConnection(any(ConnectionContext.class)); } @Test - void acquiresNewConnectionForBeginTx() - { - UnmanagedTransaction tx = beginTransaction( session ); + void acquiresNewConnectionForBeginTx() { + UnmanagedTransaction tx = beginTransaction(session); - assertNotNull( tx ); - verify( connectionProvider ).acquireConnection( any( ConnectionContext.class ) ); + assertNotNull(tx); + verify(connectionProvider).acquireConnection(any(ConnectionContext.class)); } @Test - void updatesBookmarkWhenTxIsClosed() - { - Bookmark bookmarkAfterCommit = InternalBookmark.parse( "TheBookmark" ); + void updatesBookmarkWhenTxIsClosed() { + Bookmark bookmarkAfterCommit = InternalBookmark.parse("TheBookmark"); - BoltProtocol protocol = spy( BoltProtocolV4.INSTANCE ); - doReturn( completedFuture( bookmarkAfterCommit ) ).when( protocol ).commitTransaction( any( Connection.class ) ); + BoltProtocol protocol = spy(BoltProtocolV4.INSTANCE); + doReturn(completedFuture(bookmarkAfterCommit)).when(protocol).commitTransaction(any(Connection.class)); - when( connection.protocol() ).thenReturn( protocol ); + when(connection.protocol()).thenReturn(protocol); - UnmanagedTransaction tx = beginTransaction( session ); - assertThat( session.lastBookmark(), instanceOf( InternalBookmark.class ) ); + UnmanagedTransaction tx = beginTransaction(session); + assertThat(session.lastBookmark(), instanceOf(InternalBookmark.class)); Bookmark bookmark = (InternalBookmark) session.lastBookmark(); - assertTrue( bookmark.isEmpty() ); + assertTrue(bookmark.isEmpty()); - await( tx.commitAsync() ); - assertEquals( bookmarkAfterCommit, session.lastBookmark() ); + await(tx.commitAsync()); + assertEquals(bookmarkAfterCommit, session.lastBookmark()); } @Test - void releasesConnectionWhenTxIsClosed() - { + void releasesConnectionWhenTxIsClosed() { String query = "RETURN 42"; - setupSuccessfulRunAndPull( connection, query ); + setupSuccessfulRunAndPull(connection, query); - UnmanagedTransaction tx = beginTransaction( session ); - await( tx.runAsync( new Query( query ) ) ); + UnmanagedTransaction tx = beginTransaction(session); + await(tx.runAsync(new Query(query))); - verify( connectionProvider ).acquireConnection( any( ConnectionContext.class ) ); - verifyRunAndPull( connection, query ); + verify(connectionProvider).acquireConnection(any(ConnectionContext.class)); + verifyRunAndPull(connection, query); - await( tx.closeAsync() ); - verify( connection ).release(); + await(tx.closeAsync()); + verify(connection).release(); } @Test - void bookmarkIsPropagatedFromSession() - { - Bookmark bookmark = InternalBookmark.parse( "Bookmarks" ); - NetworkSession session = newSession( connectionProvider, bookmark ); + void bookmarkIsPropagatedFromSession() { + Bookmark bookmark = InternalBookmark.parse("Bookmarks"); + NetworkSession session = newSession(connectionProvider, bookmark); - UnmanagedTransaction tx = beginTransaction( session ); - assertNotNull( tx ); - verifyBeginTx( connection ); + UnmanagedTransaction tx = beginTransaction(session); + assertNotNull(tx); + verifyBeginTx(connection); } @Test - void bookmarkIsPropagatedBetweenTransactions() - { - Bookmark bookmark1 = InternalBookmark.parse( "Bookmark1" ); - Bookmark bookmark2 = InternalBookmark.parse( "Bookmark2" ); + void bookmarkIsPropagatedBetweenTransactions() { + Bookmark bookmark1 = InternalBookmark.parse("Bookmark1"); + Bookmark bookmark2 = InternalBookmark.parse("Bookmark2"); - NetworkSession session = newSession( connectionProvider ); + NetworkSession session = newSession(connectionProvider); - BoltProtocol protocol = spy( BoltProtocolV4.INSTANCE ); - doReturn( completedFuture( bookmark1 ), completedFuture( bookmark2 ) ).when( protocol ).commitTransaction( any( Connection.class ) ); + BoltProtocol protocol = spy(BoltProtocolV4.INSTANCE); + doReturn(completedFuture(bookmark1), completedFuture(bookmark2)) + .when(protocol) + .commitTransaction(any(Connection.class)); - when( connection.protocol() ).thenReturn( protocol ); + when(connection.protocol()).thenReturn(protocol); - UnmanagedTransaction tx1 = beginTransaction( session ); - await( tx1.commitAsync() ); - assertEquals( bookmark1, session.lastBookmark() ); + UnmanagedTransaction tx1 = beginTransaction(session); + await(tx1.commitAsync()); + assertEquals(bookmark1, session.lastBookmark()); - UnmanagedTransaction tx2 = beginTransaction( session ); - verifyBeginTx( connection, 2 ); - await( tx2.commitAsync() ); + UnmanagedTransaction tx2 = beginTransaction(session); + verifyBeginTx(connection, 2); + await(tx2.commitAsync()); - assertEquals( bookmark2, session.lastBookmark() ); + assertEquals(bookmark2, session.lastBookmark()); } @Test - void accessModeUsedToAcquireReadConnections() - { - accessModeUsedToAcquireConnections( READ ); + void accessModeUsedToAcquireReadConnections() { + accessModeUsedToAcquireConnections(READ); } @Test - void accessModeUsedToAcquireWriteConnections() - { - accessModeUsedToAcquireConnections( WRITE ); + void accessModeUsedToAcquireWriteConnections() { + accessModeUsedToAcquireConnections(WRITE); } - private void accessModeUsedToAcquireConnections( AccessMode mode ) - { - NetworkSession session2 = newSession( connectionProvider, mode ); - beginTransaction( session2 ); - ArgumentCaptor argument = ArgumentCaptor.forClass( ConnectionContext.class ); - verify( connectionProvider ).acquireConnection( argument.capture() ); - assertEquals( mode, argument.getValue().mode() ); + private void accessModeUsedToAcquireConnections(AccessMode mode) { + NetworkSession session2 = newSession(connectionProvider, mode); + beginTransaction(session2); + ArgumentCaptor argument = ArgumentCaptor.forClass(ConnectionContext.class); + verify(connectionProvider).acquireConnection(argument.capture()); + assertEquals(mode, argument.getValue().mode()); } @Test - void testPassingNoBookmarkShouldRetainBookmark() - { - NetworkSession session = newSession( connectionProvider, InternalBookmark.parse( "X" ) ); - beginTransaction( session ); - assertThat( session.lastBookmark(), equalTo( InternalBookmark.parse( "X" ) ) ); + void testPassingNoBookmarkShouldRetainBookmark() { + NetworkSession session = newSession(connectionProvider, InternalBookmark.parse("X")); + beginTransaction(session); + assertThat(session.lastBookmark(), equalTo(InternalBookmark.parse("X"))); } @Test - void connectionShouldBeResetAfterSessionReset() - { + void connectionShouldBeResetAfterSessionReset() { String query = "RETURN 1"; - setupSuccessfulRunAndPull( connection, query ); + setupSuccessfulRunAndPull(connection, query); - run( session, query ); + run(session, query); - InOrder connectionInOrder = inOrder( connection ); - connectionInOrder.verify( connection, never() ).reset(); - connectionInOrder.verify( connection ).release(); + InOrder connectionInOrder = inOrder(connection); + connectionInOrder.verify(connection, never()).reset(); + connectionInOrder.verify(connection).release(); - await( session.resetAsync() ); - connectionInOrder.verify( connection ).reset(); - connectionInOrder.verify( connection, never() ).release(); + await(session.resetAsync()); + connectionInOrder.verify(connection).reset(); + connectionInOrder.verify(connection, never()).release(); } @Test - void shouldHaveEmptyLastBookmarkInitially() - { - assertThat( session.lastBookmark(), instanceOf( InternalBookmark.class ) ); + void shouldHaveEmptyLastBookmarkInitially() { + assertThat(session.lastBookmark(), instanceOf(InternalBookmark.class)); Bookmark bookmark = (InternalBookmark) session.lastBookmark(); - assertTrue( bookmark.isEmpty() ); + assertTrue(bookmark.isEmpty()); } @Test - void shouldDoNothingWhenClosingWithoutAcquiredConnection() - { - RuntimeException error = new RuntimeException( "Hi" ); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ).thenReturn( failedFuture( error ) ); + void shouldDoNothingWhenClosingWithoutAcquiredConnection() { + RuntimeException error = new RuntimeException("Hi"); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))).thenReturn(failedFuture(error)); - Exception e = assertThrows( Exception.class, () -> run( session, "RETURN 1" ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> run(session, "RETURN 1")); + assertEquals(error, e); - close( session ); + close(session); } @Test - void shouldRunAfterRunFailure() - { - RuntimeException error = new RuntimeException( "Hi" ); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) - .thenReturn( failedFuture( error ) ).thenReturn( completedFuture( connection ) ); + void shouldRunAfterRunFailure() { + RuntimeException error = new RuntimeException("Hi"); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))) + .thenReturn(failedFuture(error)) + .thenReturn(completedFuture(connection)); - Exception e = assertThrows( Exception.class, () -> run( session, "RETURN 1" ) ); + Exception e = assertThrows(Exception.class, () -> run(session, "RETURN 1")); - assertEquals( error, e ); + assertEquals(error, e); String query = "RETURN 2"; - setupSuccessfulRunAndPull( connection, query ); + setupSuccessfulRunAndPull(connection, query); - run( session, query ); + run(session, query); - verify( connectionProvider, times( 2 ) ).acquireConnection( any( ConnectionContext.class ) ); - verifyRunAndPull( connection, query ); + verify(connectionProvider, times(2)).acquireConnection(any(ConnectionContext.class)); + verifyRunAndPull(connection, query); } @Test - void shouldRunAfterBeginTxFailureOnBookmark() - { - RuntimeException error = new RuntimeException( "Hi" ); - Connection connection1 = connectionMock( BoltProtocolV4.INSTANCE ); - setupFailingBegin( connection1, error ); - Connection connection2 = connectionMock( BoltProtocolV4.INSTANCE ); + void shouldRunAfterBeginTxFailureOnBookmark() { + RuntimeException error = new RuntimeException("Hi"); + Connection connection1 = connectionMock(BoltProtocolV4.INSTANCE); + setupFailingBegin(connection1, error); + Connection connection2 = connectionMock(BoltProtocolV4.INSTANCE); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) - .thenReturn( completedFuture( connection1 ) ).thenReturn( completedFuture( connection2 ) ); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))) + .thenReturn(completedFuture(connection1)) + .thenReturn(completedFuture(connection2)); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx42" ); - NetworkSession session = newSession( connectionProvider, bookmark ); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx42"); + NetworkSession session = newSession(connectionProvider, bookmark); - Exception e = assertThrows( Exception.class, () -> beginTransaction( session ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> beginTransaction(session)); + assertEquals(error, e); String query = "RETURN 2"; - setupSuccessfulRunAndPull( connection2, query ); + setupSuccessfulRunAndPull(connection2, query); - run( session, query ); + run(session, query); - verify( connectionProvider, times( 2 ) ).acquireConnection( any( ConnectionContext.class ) ); - verifyBeginTx( connection1 ); - verifyRunAndPull( connection2, "RETURN 2" ); + verify(connectionProvider, times(2)).acquireConnection(any(ConnectionContext.class)); + verifyBeginTx(connection1); + verifyRunAndPull(connection2, "RETURN 2"); } @Test - void shouldBeginTxAfterBeginTxFailureOnBookmark() - { - RuntimeException error = new RuntimeException( "Hi" ); - Connection connection1 = connectionMock( BoltProtocolV4.INSTANCE ); - setupFailingBegin( connection1, error ); - Connection connection2 = connectionMock( BoltProtocolV4.INSTANCE ); + void shouldBeginTxAfterBeginTxFailureOnBookmark() { + RuntimeException error = new RuntimeException("Hi"); + Connection connection1 = connectionMock(BoltProtocolV4.INSTANCE); + setupFailingBegin(connection1, error); + Connection connection2 = connectionMock(BoltProtocolV4.INSTANCE); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) - .thenReturn( completedFuture( connection1 ) ).thenReturn( completedFuture( connection2 ) ); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))) + .thenReturn(completedFuture(connection1)) + .thenReturn(completedFuture(connection2)); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx42" ); - NetworkSession session = newSession( connectionProvider, bookmark ); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx42"); + NetworkSession session = newSession(connectionProvider, bookmark); - Exception e = assertThrows( Exception.class, () -> beginTransaction( session ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> beginTransaction(session)); + assertEquals(error, e); - beginTransaction( session ); + beginTransaction(session); - verify( connectionProvider, times( 2 ) ).acquireConnection( any( ConnectionContext.class ) ); - verifyBeginTx( connection1 ); - verifyBeginTx( connection2 ); + verify(connectionProvider, times(2)).acquireConnection(any(ConnectionContext.class)); + verifyBeginTx(connection1); + verifyBeginTx(connection2); } @Test - void shouldBeginTxAfterRunFailureToAcquireConnection() - { - RuntimeException error = new RuntimeException( "Hi" ); - when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) - .thenReturn( failedFuture( error ) ).thenReturn( completedFuture( connection ) ); + void shouldBeginTxAfterRunFailureToAcquireConnection() { + RuntimeException error = new RuntimeException("Hi"); + when(connectionProvider.acquireConnection(any(ConnectionContext.class))) + .thenReturn(failedFuture(error)) + .thenReturn(completedFuture(connection)); - Exception e = assertThrows( Exception.class, () -> run( session, "RETURN 1" ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> run(session, "RETURN 1")); + assertEquals(error, e); - beginTransaction( session ); + beginTransaction(session); - verify( connectionProvider, times( 2 ) ).acquireConnection( any( ConnectionContext.class ) ); - verifyBeginTx( connection ); + verify(connectionProvider, times(2)).acquireConnection(any(ConnectionContext.class)); + verifyBeginTx(connection); } @Test - void shouldMarkTransactionAsTerminatedAndThenResetConnectionOnReset() - { - UnmanagedTransaction tx = beginTransaction( session ); + void shouldMarkTransactionAsTerminatedAndThenResetConnectionOnReset() { + UnmanagedTransaction tx = beginTransaction(session); - assertTrue( tx.isOpen() ); - verify( connection, never() ).reset(); + assertTrue(tx.isOpen()); + verify(connection, never()).reset(); - await( session.resetAsync() ); + await(session.resetAsync()); - verify( connection ).reset(); + verify(connection).reset(); } - private static ResultCursor run(NetworkSession session, String query ) - { - return await( session.runAsync( new Query( query ), TransactionConfig.empty() ) ); + private static ResultCursor run(NetworkSession session, String query) { + return await(session.runAsync(new Query(query), TransactionConfig.empty())); } - private static UnmanagedTransaction beginTransaction(NetworkSession session ) - { - return await( session.beginTransactionAsync( TransactionConfig.empty() ) ); + private static UnmanagedTransaction beginTransaction(NetworkSession session) { + return await(session.beginTransactionAsync(TransactionConfig.empty())); } - private static void close( NetworkSession session ) - { - await( session.closeAsync() ); + private static void close(NetworkSession session) { + await(session.closeAsync()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/ResultCursorsHolderTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/ResultCursorsHolderTest.java index b6d75e0ed9..150074f227 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/ResultCursorsHolderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/ResultCursorsHolderTest.java @@ -18,16 +18,6 @@ */ package org.neo4j.driver.internal.async; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeoutException; - -import org.neo4j.driver.internal.cursor.AsyncResultCursorImpl; -import org.neo4j.driver.internal.util.Futures; - import static java.util.concurrent.CompletableFuture.completedFuture; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -38,118 +28,116 @@ import static org.mockito.Mockito.when; import static org.neo4j.driver.util.TestUtil.await; -class ResultCursorsHolderTest -{ +import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.TimeoutException; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.cursor.AsyncResultCursorImpl; +import org.neo4j.driver.internal.util.Futures; + +class ResultCursorsHolderTest { @Test - void shouldReturnNoErrorWhenNoCursorStages() - { + void shouldReturnNoErrorWhenNoCursorStages() { ResultCursorsHolder holder = new ResultCursorsHolder(); - Throwable error = await( holder.retrieveNotConsumedError() ); - assertNull( error ); + Throwable error = await(holder.retrieveNotConsumedError()); + assertNull(error); } @Test - void shouldFailToAddNullCursorStage() - { + void shouldFailToAddNullCursorStage() { ResultCursorsHolder holder = new ResultCursorsHolder(); - assertThrows( NullPointerException.class, () -> holder.add( null ) ); + assertThrows(NullPointerException.class, () -> holder.add(null)); } @Test - void shouldReturnNoErrorWhenCursorStagesHaveNoErrors() - { + void shouldReturnNoErrorWhenCursorStagesHaveNoErrors() { ResultCursorsHolder holder = new ResultCursorsHolder(); - holder.add( cursorWithoutError() ); - holder.add( cursorWithoutError() ); - holder.add( cursorWithoutError() ); - holder.add( cursorWithoutError() ); + holder.add(cursorWithoutError()); + holder.add(cursorWithoutError()); + holder.add(cursorWithoutError()); + holder.add(cursorWithoutError()); - Throwable error = await( holder.retrieveNotConsumedError() ); - assertNull( error ); + Throwable error = await(holder.retrieveNotConsumedError()); + assertNull(error); } @Test - void shouldNotReturnStageErrors() - { + void shouldNotReturnStageErrors() { ResultCursorsHolder holder = new ResultCursorsHolder(); - holder.add( Futures.failedFuture( new RuntimeException( "Failed to acquire a connection" ) ) ); - holder.add( cursorWithoutError() ); - holder.add( cursorWithoutError() ); - holder.add( Futures.failedFuture( new IOException( "Failed to do IO" ) ) ); + holder.add(Futures.failedFuture(new RuntimeException("Failed to acquire a connection"))); + holder.add(cursorWithoutError()); + holder.add(cursorWithoutError()); + holder.add(Futures.failedFuture(new IOException("Failed to do IO"))); - Throwable error = await( holder.retrieveNotConsumedError() ); - assertNull( error ); + Throwable error = await(holder.retrieveNotConsumedError()); + assertNull(error); } @Test - void shouldReturnErrorWhenOneCursorFailed() - { - IOException error = new IOException( "IO failed" ); + void shouldReturnErrorWhenOneCursorFailed() { + IOException error = new IOException("IO failed"); ResultCursorsHolder holder = new ResultCursorsHolder(); - holder.add( cursorWithoutError() ); - holder.add( cursorWithoutError() ); - holder.add( cursorWithError( error ) ); - holder.add( cursorWithoutError() ); + holder.add(cursorWithoutError()); + holder.add(cursorWithoutError()); + holder.add(cursorWithError(error)); + holder.add(cursorWithoutError()); - Throwable retrievedError = await( holder.retrieveNotConsumedError() ); - assertEquals( error, retrievedError ); + Throwable retrievedError = await(holder.retrieveNotConsumedError()); + assertEquals(error, retrievedError); } @Test - void shouldReturnFirstError() - { - RuntimeException error1 = new RuntimeException( "Error 1" ); - IOException error2 = new IOException( "Error 2" ); - TimeoutException error3 = new TimeoutException( "Error 3" ); + void shouldReturnFirstError() { + RuntimeException error1 = new RuntimeException("Error 1"); + IOException error2 = new IOException("Error 2"); + TimeoutException error3 = new TimeoutException("Error 3"); ResultCursorsHolder holder = new ResultCursorsHolder(); - holder.add( cursorWithoutError() ); - holder.add( cursorWithError( error1 ) ); - holder.add( cursorWithError( error2 ) ); - holder.add( cursorWithError( error3 ) ); + holder.add(cursorWithoutError()); + holder.add(cursorWithError(error1)); + holder.add(cursorWithError(error2)); + holder.add(cursorWithError(error3)); - assertEquals( error1, await( holder.retrieveNotConsumedError() ) ); + assertEquals(error1, await(holder.retrieveNotConsumedError())); } @Test - void shouldWaitForAllFailuresToArrive() - { - RuntimeException error1 = new RuntimeException( "Error 1" ); + void shouldWaitForAllFailuresToArrive() { + RuntimeException error1 = new RuntimeException("Error 1"); CompletableFuture error2Future = new CompletableFuture<>(); ResultCursorsHolder holder = new ResultCursorsHolder(); - holder.add( cursorWithoutError() ); - holder.add( cursorWithError( error1 ) ); - holder.add( cursorWithFailureFuture( error2Future ) ); + holder.add(cursorWithoutError()); + holder.add(cursorWithError(error1)); + holder.add(cursorWithFailureFuture(error2Future)); - CompletableFuture failureFuture = holder.retrieveNotConsumedError().toCompletableFuture(); - assertFalse( failureFuture.isDone() ); + CompletableFuture failureFuture = + holder.retrieveNotConsumedError().toCompletableFuture(); + assertFalse(failureFuture.isDone()); - error2Future.complete( null ); - assertTrue( failureFuture.isDone() ); + error2Future.complete(null); + assertTrue(failureFuture.isDone()); - assertEquals( error1, await( failureFuture ) ); + assertEquals(error1, await(failureFuture)); } - private static CompletionStage cursorWithoutError() - { - return cursorWithError( null ); + private static CompletionStage cursorWithoutError() { + return cursorWithError(null); } - private static CompletionStage cursorWithError(Throwable error ) - { - return cursorWithFailureFuture( completedFuture( error ) ); + private static CompletionStage cursorWithError(Throwable error) { + return cursorWithFailureFuture(completedFuture(error)); } - private static CompletionStage cursorWithFailureFuture(CompletableFuture future ) - { - AsyncResultCursorImpl cursor = mock( AsyncResultCursorImpl.class ); - when( cursor.discardAllFailureAsync() ).thenReturn( future ); - return completedFuture( cursor ); + private static CompletionStage cursorWithFailureFuture(CompletableFuture future) { + AsyncResultCursorImpl cursor = mock(AsyncResultCursorImpl.class); + when(cursor.discardAllFailureAsync()).thenReturn(future); + return completedFuture(cursor); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java index f639565a66..92d3541be3 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java @@ -18,33 +18,6 @@ */ package org.neo4j.driver.internal.async; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InOrder; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import org.neo4j.driver.Bookmark; -import org.neo4j.driver.Query; -import org.neo4j.driver.TransactionConfig; -import org.neo4j.driver.exceptions.AuthorizationExpiredException; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; -import org.neo4j.driver.internal.DefaultBookmarkHolder; -import org.neo4j.driver.internal.FailableCursor; -import org.neo4j.driver.internal.InternalBookmark; -import org.neo4j.driver.internal.messaging.BoltProtocol; -import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ResponseHandler; - import static java.util.Collections.emptyMap; import static java.util.concurrent.CompletableFuture.completedFuture; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -77,443 +50,441 @@ import static org.neo4j.driver.util.TestUtil.verifyRunAndPull; import static org.neo4j.driver.util.TestUtil.verifyRunRx; -class UnmanagedTransactionTest -{ +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InOrder; +import org.neo4j.driver.Bookmark; +import org.neo4j.driver.Query; +import org.neo4j.driver.TransactionConfig; +import org.neo4j.driver.exceptions.AuthorizationExpiredException; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; +import org.neo4j.driver.internal.DefaultBookmarkHolder; +import org.neo4j.driver.internal.FailableCursor; +import org.neo4j.driver.internal.InternalBookmark; +import org.neo4j.driver.internal.messaging.BoltProtocol; +import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ResponseHandler; + +class UnmanagedTransactionTest { @Test - void shouldFlushOnRunAsync() - { + void shouldFlushOnRunAsync() { // Given - Connection connection = connectionMock( BoltProtocolV4.INSTANCE ); - UnmanagedTransaction tx = beginTx( connection ); - setupSuccessfulRunAndPull( connection ); + Connection connection = connectionMock(BoltProtocolV4.INSTANCE); + UnmanagedTransaction tx = beginTx(connection); + setupSuccessfulRunAndPull(connection); // When - await( tx.runAsync( new Query( "RETURN 1" ) ) ); + await(tx.runAsync(new Query("RETURN 1"))); // Then - verifyRunAndPull( connection, "RETURN 1" ); + verifyRunAndPull(connection, "RETURN 1"); } @Test - void shouldFlushOnRunRx() - { + void shouldFlushOnRunRx() { // Given - Connection connection = connectionMock( BoltProtocolV4.INSTANCE ); - UnmanagedTransaction tx = beginTx( connection ); - setupSuccessfulRunRx( connection ); + Connection connection = connectionMock(BoltProtocolV4.INSTANCE); + UnmanagedTransaction tx = beginTx(connection); + setupSuccessfulRunRx(connection); // When - await( tx.runRx( new Query( "RETURN 1" ) ) ); + await(tx.runRx(new Query("RETURN 1"))); // Then - verifyRunRx( connection, "RETURN 1" ); + verifyRunRx(connection, "RETURN 1"); } @Test - void shouldRollbackOnImplicitFailure() - { + void shouldRollbackOnImplicitFailure() { // Given Connection connection = connectionMock(); - UnmanagedTransaction tx = beginTx( connection ); + UnmanagedTransaction tx = beginTx(connection); // When - await( tx.closeAsync() ); + await(tx.closeAsync()); // Then - InOrder order = inOrder( connection ); - verifyBeginTx( connection ); - verifyRollbackTx( connection ); - order.verify( connection ).release(); + InOrder order = inOrder(connection); + verifyBeginTx(connection); + verifyRollbackTx(connection); + order.verify(connection).release(); } @Test - void shouldOnlyQueueMessagesWhenNoBookmarkGiven() - { + void shouldOnlyQueueMessagesWhenNoBookmarkGiven() { Connection connection = connectionMock(); - beginTx( connection, InternalBookmark.empty() ); + beginTx(connection, InternalBookmark.empty()); - verifyBeginTx( connection ); - verify( connection, never() ).writeAndFlush( any(), any(), any(), any() ); + verifyBeginTx(connection); + verify(connection, never()).writeAndFlush(any(), any(), any(), any()); } @Test - void shouldFlushWhenBookmarkGiven() - { - Bookmark bookmark = InternalBookmark.parse( "hi, I'm bookmark" ); + void shouldFlushWhenBookmarkGiven() { + Bookmark bookmark = InternalBookmark.parse("hi, I'm bookmark"); Connection connection = connectionMock(); - beginTx( connection, bookmark ); + beginTx(connection, bookmark); - verifyBeginTx( connection ); - verify( connection, never() ).write( any(), any(), any(), any() ); + verifyBeginTx(connection); + verify(connection, never()).write(any(), any(), any(), any()); } @Test - void shouldBeOpenAfterConstruction() - { - UnmanagedTransaction tx = beginTx( connectionMock() ); + void shouldBeOpenAfterConstruction() { + UnmanagedTransaction tx = beginTx(connectionMock()); - assertTrue( tx.isOpen() ); + assertTrue(tx.isOpen()); } @Test - void shouldBeClosedWhenMarkedAsTerminated() - { - UnmanagedTransaction tx = beginTx( connectionMock() ); + void shouldBeClosedWhenMarkedAsTerminated() { + UnmanagedTransaction tx = beginTx(connectionMock()); - tx.markTerminated( null ); + tx.markTerminated(null); - assertTrue( tx.isOpen() ); + assertTrue(tx.isOpen()); } @Test - void shouldBeClosedWhenMarkedTerminatedAndClosed() - { - UnmanagedTransaction tx = beginTx( connectionMock() ); + void shouldBeClosedWhenMarkedTerminatedAndClosed() { + UnmanagedTransaction tx = beginTx(connectionMock()); - tx.markTerminated( null ); - await( tx.closeAsync() ); + tx.markTerminated(null); + await(tx.closeAsync()); - assertFalse( tx.isOpen() ); + assertFalse(tx.isOpen()); } @Test - void shouldReleaseConnectionWhenBeginFails() - { - RuntimeException error = new RuntimeException( "Wrong bookmark!" ); - Connection connection = connectionWithBegin( handler -> handler.onFailure( error ) ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); + void shouldReleaseConnectionWhenBeginFails() { + RuntimeException error = new RuntimeException("Wrong bookmark!"); + Connection connection = connectionWithBegin(handler -> handler.onFailure(error)); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); - Bookmark bookmark = InternalBookmark.parse( "SomeBookmark" ); + Bookmark bookmark = InternalBookmark.parse("SomeBookmark"); TransactionConfig txConfig = TransactionConfig.empty(); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( tx.beginAsync( bookmark, txConfig ) ) ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(tx.beginAsync(bookmark, txConfig))); - assertEquals( error, e ); - verify( connection ).release(); + assertEquals(error, e); + verify(connection).release(); } @Test - void shouldNotReleaseConnectionWhenBeginSucceeds() - { - Connection connection = connectionWithBegin( handler -> handler.onSuccess( emptyMap() ) ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); + void shouldNotReleaseConnectionWhenBeginSucceeds() { + Connection connection = connectionWithBegin(handler -> handler.onSuccess(emptyMap())); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); - Bookmark bookmark = InternalBookmark.parse( "SomeBookmark" ); + Bookmark bookmark = InternalBookmark.parse("SomeBookmark"); TransactionConfig txConfig = TransactionConfig.empty(); - await( tx.beginAsync( bookmark, txConfig ) ); + await(tx.beginAsync(bookmark, txConfig)); - verify( connection, never() ).release(); + verify(connection, never()).release(); } @Test - void shouldReleaseConnectionWhenTerminatedAndCommitted() - { + void shouldReleaseConnectionWhenTerminatedAndCommitted() { Connection connection = connectionMock(); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); - tx.markTerminated( null ); + tx.markTerminated(null); - assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); + assertThrows(ClientException.class, () -> await(tx.commitAsync())); - assertFalse( tx.isOpen() ); - verify( connection ).release(); + assertFalse(tx.isOpen()); + verify(connection).release(); } @Test - void shouldNotCreateCircularExceptionWhenTerminationCauseEqualsToCursorFailure() - { + void shouldNotCreateCircularExceptionWhenTerminationCauseEqualsToCursorFailure() { Connection connection = connectionMock(); - ClientException terminationCause = new ClientException( "Custom exception" ); - ResultCursorsHolder resultCursorsHolder = mockResultCursorWith( terminationCause ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE, resultCursorsHolder ); + ClientException terminationCause = new ClientException("Custom exception"); + ResultCursorsHolder resultCursorsHolder = mockResultCursorWith(terminationCause); + UnmanagedTransaction tx = new UnmanagedTransaction( + connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE, resultCursorsHolder); - tx.markTerminated( terminationCause ); + tx.markTerminated(terminationCause); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertNoCircularReferences( e ); - assertEquals( terminationCause, e ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertNoCircularReferences(e); + assertEquals(terminationCause, e); } @Test - void shouldNotCreateCircularExceptionWhenTerminationCauseDifferentFromCursorFailure() - { + void shouldNotCreateCircularExceptionWhenTerminationCauseDifferentFromCursorFailure() { Connection connection = connectionMock(); - ClientException terminationCause = new ClientException( "Custom exception" ); - ResultCursorsHolder resultCursorsHolder = mockResultCursorWith( new ClientException( "Cursor error" ) ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE, resultCursorsHolder ); + ClientException terminationCause = new ClientException("Custom exception"); + ResultCursorsHolder resultCursorsHolder = mockResultCursorWith(new ClientException("Cursor error")); + UnmanagedTransaction tx = new UnmanagedTransaction( + connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE, resultCursorsHolder); - tx.markTerminated( terminationCause ); + tx.markTerminated(terminationCause); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertNoCircularReferences( e ); - assertEquals( 1, e.getSuppressed().length ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertNoCircularReferences(e); + assertEquals(1, e.getSuppressed().length); Throwable suppressed = e.getSuppressed()[0]; - assertEquals( terminationCause, suppressed.getCause() ); + assertEquals(terminationCause, suppressed.getCause()); } @Test - void shouldNotCreateCircularExceptionWhenTerminatedWithoutFailure() - { + void shouldNotCreateCircularExceptionWhenTerminatedWithoutFailure() { Connection connection = connectionMock(); - ClientException terminationCause = new ClientException( "Custom exception" ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); + ClientException terminationCause = new ClientException("Custom exception"); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); - tx.markTerminated( terminationCause ); + tx.markTerminated(terminationCause); - ClientException e = assertThrows( ClientException.class, () -> await( tx.commitAsync() ) ); - assertNoCircularReferences( e ); + ClientException e = assertThrows(ClientException.class, () -> await(tx.commitAsync())); + assertNoCircularReferences(e); - assertEquals( terminationCause, e.getCause() ); + assertEquals(terminationCause, e.getCause()); } @Test - void shouldReleaseConnectionWhenTerminatedAndRolledBack() - { + void shouldReleaseConnectionWhenTerminatedAndRolledBack() { Connection connection = connectionMock(); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); - tx.markTerminated( null ); - await( tx.rollbackAsync() ); + tx.markTerminated(null); + await(tx.rollbackAsync()); - verify( connection ).release(); + verify(connection).release(); } @Test - void shouldReleaseConnectionWhenClose() throws Throwable - { + void shouldReleaseConnectionWhenClose() throws Throwable { Connection connection = connectionMock(); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); - await( tx.closeAsync() ); + await(tx.closeAsync()); - verify( connection ).release(); + verify(connection).release(); } @Test - void shouldReleaseConnectionOnConnectionAuthorizationExpiredExceptionFailure() - { - AuthorizationExpiredException exception = new AuthorizationExpiredException( "code", "message" ); - Connection connection = connectionWithBegin( handler -> handler.onFailure( exception ) ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); - Bookmark bookmark = InternalBookmark.parse( "SomeBookmark" ); + void shouldReleaseConnectionOnConnectionAuthorizationExpiredExceptionFailure() { + AuthorizationExpiredException exception = new AuthorizationExpiredException("code", "message"); + Connection connection = connectionWithBegin(handler -> handler.onFailure(exception)); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); + Bookmark bookmark = InternalBookmark.parse("SomeBookmark"); TransactionConfig txConfig = TransactionConfig.empty(); - AuthorizationExpiredException actualException = assertThrows( AuthorizationExpiredException.class, () -> await( tx.beginAsync( bookmark, txConfig ) ) ); + AuthorizationExpiredException actualException = + assertThrows(AuthorizationExpiredException.class, () -> await(tx.beginAsync(bookmark, txConfig))); - assertSame( exception, actualException ); - verify( connection ).terminateAndRelease( AuthorizationExpiredException.DESCRIPTION ); - verify( connection, never() ).release(); + assertSame(exception, actualException); + verify(connection).terminateAndRelease(AuthorizationExpiredException.DESCRIPTION); + verify(connection, never()).release(); } @Test - void shouldReleaseConnectionOnConnectionReadTimeoutExceptionFailure() - { - Connection connection = connectionWithBegin( handler -> handler.onFailure( ConnectionReadTimeoutException.INSTANCE ) ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); - Bookmark bookmark = InternalBookmark.parse( "SomeBookmark" ); + void shouldReleaseConnectionOnConnectionReadTimeoutExceptionFailure() { + Connection connection = + connectionWithBegin(handler -> handler.onFailure(ConnectionReadTimeoutException.INSTANCE)); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); + Bookmark bookmark = InternalBookmark.parse("SomeBookmark"); TransactionConfig txConfig = TransactionConfig.empty(); ConnectionReadTimeoutException actualException = - assertThrows( ConnectionReadTimeoutException.class, () -> await( tx.beginAsync( bookmark, txConfig ) ) ); + assertThrows(ConnectionReadTimeoutException.class, () -> await(tx.beginAsync(bookmark, txConfig))); - assertSame( ConnectionReadTimeoutException.INSTANCE, actualException ); - verify( connection ).terminateAndRelease( ConnectionReadTimeoutException.INSTANCE.getMessage() ); - verify( connection, never() ).release(); + assertSame(ConnectionReadTimeoutException.INSTANCE, actualException); + verify(connection).terminateAndRelease(ConnectionReadTimeoutException.INSTANCE.getMessage()); + verify(connection, never()).release(); } - private static Stream similarTransactionCompletingActionArgs() - { + private static Stream similarTransactionCompletingActionArgs() { return Stream.of( - Arguments.of( true, "commit", "commit" ), - - Arguments.of( false, "rollback", "rollback" ), - Arguments.of( false, "rollback", "close" ), - - Arguments.of( false, "close", "rollback" ), - Arguments.of( false, "close", "close" ) - ); + Arguments.of(true, "commit", "commit"), + Arguments.of(false, "rollback", "rollback"), + Arguments.of(false, "rollback", "close"), + Arguments.of(false, "close", "rollback"), + Arguments.of(false, "close", "close")); } @ParameterizedTest - @MethodSource( "similarTransactionCompletingActionArgs" ) - void shouldReturnExistingStageOnSimilarCompletingAction( boolean protocolCommit, String initialAction, String similarAction ) - { - Connection connection = mock( Connection.class ); - BoltProtocol protocol = mock( BoltProtocol.class ); - given( connection.protocol() ).willReturn( protocol ); - given( protocolCommit ? protocol.commitTransaction( connection ) : protocol.rollbackTransaction( connection ) ).willReturn( new CompletableFuture<>() ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); - - CompletionStage initialStage = mapTransactionAction( initialAction, tx ).get(); - CompletionStage similarStage = mapTransactionAction( similarAction, tx ).get(); - - assertSame( initialStage, similarStage ); - if ( protocolCommit ) - { - then( protocol ).should( times( 1 ) ).commitTransaction( connection ); - } - else - { - then( protocol ).should( times( 1 ) ).rollbackTransaction( connection ); + @MethodSource("similarTransactionCompletingActionArgs") + void shouldReturnExistingStageOnSimilarCompletingAction( + boolean protocolCommit, String initialAction, String similarAction) { + Connection connection = mock(Connection.class); + BoltProtocol protocol = mock(BoltProtocol.class); + given(connection.protocol()).willReturn(protocol); + given(protocolCommit ? protocol.commitTransaction(connection) : protocol.rollbackTransaction(connection)) + .willReturn(new CompletableFuture<>()); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); + + CompletionStage initialStage = + mapTransactionAction(initialAction, tx).get(); + CompletionStage similarStage = + mapTransactionAction(similarAction, tx).get(); + + assertSame(initialStage, similarStage); + if (protocolCommit) { + then(protocol).should(times(1)).commitTransaction(connection); + } else { + then(protocol).should(times(1)).rollbackTransaction(connection); } } - private static Stream conflictingTransactionCompletingActionArgs() - { + private static Stream conflictingTransactionCompletingActionArgs() { return Stream.of( - Arguments.of( true, true, "commit", "commit", UnmanagedTransaction.CANT_COMMIT_COMMITTED_MSG ), - Arguments.of( true, true, "commit", "rollback", UnmanagedTransaction.CANT_ROLLBACK_COMMITTED_MSG ), - Arguments.of( true, false, "commit", "rollback", UnmanagedTransaction.CANT_ROLLBACK_COMMITTING_MSG ), - Arguments.of( true, false, "commit", "close", UnmanagedTransaction.CANT_ROLLBACK_COMMITTING_MSG ), - - Arguments.of( false, true, "rollback", "rollback", UnmanagedTransaction.CANT_ROLLBACK_ROLLED_BACK_MSG ), - Arguments.of( false, true, "rollback", "commit", UnmanagedTransaction.CANT_COMMIT_ROLLED_BACK_MSG ), - Arguments.of( false, false, "rollback", "commit", UnmanagedTransaction.CANT_COMMIT_ROLLING_BACK_MSG ), - - Arguments.of( false, true, "close", "commit", UnmanagedTransaction.CANT_COMMIT_ROLLED_BACK_MSG ), - Arguments.of( false, true, "close", "rollback", UnmanagedTransaction.CANT_ROLLBACK_ROLLED_BACK_MSG ), - Arguments.of( false, false, "close", "commit", UnmanagedTransaction.CANT_COMMIT_ROLLING_BACK_MSG ) - ); + Arguments.of(true, true, "commit", "commit", UnmanagedTransaction.CANT_COMMIT_COMMITTED_MSG), + Arguments.of(true, true, "commit", "rollback", UnmanagedTransaction.CANT_ROLLBACK_COMMITTED_MSG), + Arguments.of(true, false, "commit", "rollback", UnmanagedTransaction.CANT_ROLLBACK_COMMITTING_MSG), + Arguments.of(true, false, "commit", "close", UnmanagedTransaction.CANT_ROLLBACK_COMMITTING_MSG), + Arguments.of(false, true, "rollback", "rollback", UnmanagedTransaction.CANT_ROLLBACK_ROLLED_BACK_MSG), + Arguments.of(false, true, "rollback", "commit", UnmanagedTransaction.CANT_COMMIT_ROLLED_BACK_MSG), + Arguments.of(false, false, "rollback", "commit", UnmanagedTransaction.CANT_COMMIT_ROLLING_BACK_MSG), + Arguments.of(false, true, "close", "commit", UnmanagedTransaction.CANT_COMMIT_ROLLED_BACK_MSG), + Arguments.of(false, true, "close", "rollback", UnmanagedTransaction.CANT_ROLLBACK_ROLLED_BACK_MSG), + Arguments.of(false, false, "close", "commit", UnmanagedTransaction.CANT_COMMIT_ROLLING_BACK_MSG)); } @ParameterizedTest - @MethodSource( "conflictingTransactionCompletingActionArgs" ) - void shouldReturnFailingStageOnConflictingCompletingAction( boolean protocolCommit, boolean protocolActionCompleted, String initialAction, - String conflictingAction, String expectedErrorMsg ) - { - Connection connection = mock( Connection.class ); - BoltProtocol protocol = mock( BoltProtocol.class ); - given( connection.protocol() ).willReturn( protocol ); - given( protocolCommit ? protocol.commitTransaction( connection ) : protocol.rollbackTransaction( connection ) ) - .willReturn( protocolActionCompleted ? completedFuture( null ) : new CompletableFuture<>() ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); - - CompletionStage originalActionStage = mapTransactionAction( initialAction, tx ).get(); - CompletionStage conflictingActionStage = mapTransactionAction( conflictingAction, tx ).get(); - - assertNotNull( originalActionStage ); - if ( protocolCommit ) - { - then( protocol ).should( times( 1 ) ).commitTransaction( connection ); - } - else - { - then( protocol ).should( times( 1 ) ).rollbackTransaction( connection ); + @MethodSource("conflictingTransactionCompletingActionArgs") + void shouldReturnFailingStageOnConflictingCompletingAction( + boolean protocolCommit, + boolean protocolActionCompleted, + String initialAction, + String conflictingAction, + String expectedErrorMsg) { + Connection connection = mock(Connection.class); + BoltProtocol protocol = mock(BoltProtocol.class); + given(connection.protocol()).willReturn(protocol); + given(protocolCommit ? protocol.commitTransaction(connection) : protocol.rollbackTransaction(connection)) + .willReturn(protocolActionCompleted ? completedFuture(null) : new CompletableFuture<>()); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); + + CompletionStage originalActionStage = + mapTransactionAction(initialAction, tx).get(); + CompletionStage conflictingActionStage = + mapTransactionAction(conflictingAction, tx).get(); + + assertNotNull(originalActionStage); + if (protocolCommit) { + then(protocol).should(times(1)).commitTransaction(connection); + } else { + then(protocol).should(times(1)).rollbackTransaction(connection); } - assertTrue( conflictingActionStage.toCompletableFuture().isCompletedExceptionally() ); - Throwable throwable = assertThrows( ExecutionException.class, () -> conflictingActionStage.toCompletableFuture().get() ).getCause(); - assertTrue( throwable instanceof ClientException ); - assertEquals( expectedErrorMsg, throwable.getMessage() ); + assertTrue(conflictingActionStage.toCompletableFuture().isCompletedExceptionally()); + Throwable throwable = assertThrows( + ExecutionException.class, + () -> conflictingActionStage.toCompletableFuture().get()) + .getCause(); + assertTrue(throwable instanceof ClientException); + assertEquals(expectedErrorMsg, throwable.getMessage()); } - private static Stream closingNotActionTransactionArgs() - { + private static Stream closingNotActionTransactionArgs() { return Stream.of( - Arguments.of( true, 1, "commit", null ), - Arguments.of( false, 1, "rollback", null ), - Arguments.of( false, 0, "terminate", null ), - Arguments.of( true, 1, "commit", true ), - Arguments.of( false, 1, "rollback", true ), - Arguments.of( true, 1, "commit", false ), - Arguments.of( false, 1, "rollback", false ), - Arguments.of( false, 0, "terminate", false ) - ); + Arguments.of(true, 1, "commit", null), + Arguments.of(false, 1, "rollback", null), + Arguments.of(false, 0, "terminate", null), + Arguments.of(true, 1, "commit", true), + Arguments.of(false, 1, "rollback", true), + Arguments.of(true, 1, "commit", false), + Arguments.of(false, 1, "rollback", false), + Arguments.of(false, 0, "terminate", false)); } @ParameterizedTest - @MethodSource( "closingNotActionTransactionArgs" ) + @MethodSource("closingNotActionTransactionArgs") void shouldReturnCompletedWithNullStageOnClosingInactiveTransactionExceptCommittingAborted( - boolean protocolCommit, int expectedProtocolInvocations, String originalAction, Boolean commitOnClose ) - { - Connection connection = mock( Connection.class ); - BoltProtocol protocol = mock( BoltProtocol.class ); - given( connection.protocol() ).willReturn( protocol ); - given( protocolCommit ? protocol.commitTransaction( connection ) : protocol.rollbackTransaction( connection ) ) - .willReturn( completedFuture( null ) ); - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); - - CompletionStage originalActionStage = mapTransactionAction( originalAction, tx ).get(); - CompletionStage closeStage = commitOnClose != null ? tx.closeAsync( commitOnClose ) : tx.closeAsync(); - - assertTrue( originalActionStage.toCompletableFuture().isDone() ); - assertFalse( originalActionStage.toCompletableFuture().isCompletedExceptionally() ); - if ( protocolCommit ) - { - then( protocol ).should( times( expectedProtocolInvocations ) ).commitTransaction( connection ); + boolean protocolCommit, int expectedProtocolInvocations, String originalAction, Boolean commitOnClose) { + Connection connection = mock(Connection.class); + BoltProtocol protocol = mock(BoltProtocol.class); + given(connection.protocol()).willReturn(protocol); + given(protocolCommit ? protocol.commitTransaction(connection) : protocol.rollbackTransaction(connection)) + .willReturn(completedFuture(null)); + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); + + CompletionStage originalActionStage = + mapTransactionAction(originalAction, tx).get(); + CompletionStage closeStage = commitOnClose != null ? tx.closeAsync(commitOnClose) : tx.closeAsync(); + + assertTrue(originalActionStage.toCompletableFuture().isDone()); + assertFalse(originalActionStage.toCompletableFuture().isCompletedExceptionally()); + if (protocolCommit) { + then(protocol).should(times(expectedProtocolInvocations)).commitTransaction(connection); + } else { + then(protocol).should(times(expectedProtocolInvocations)).rollbackTransaction(connection); } - else - { - then( protocol ).should( times( expectedProtocolInvocations ) ).rollbackTransaction( connection ); - } - assertNull( closeStage.toCompletableFuture().join() ); + assertNull(closeStage.toCompletableFuture().join()); } - private static UnmanagedTransaction beginTx( Connection connection ) - { - return beginTx( connection, InternalBookmark.empty() ); + private static UnmanagedTransaction beginTx(Connection connection) { + return beginTx(connection, InternalBookmark.empty()); } - private static UnmanagedTransaction beginTx( Connection connection, Bookmark initialBookmark ) - { - UnmanagedTransaction tx = new UnmanagedTransaction( connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE ); - return await( tx.beginAsync( initialBookmark, TransactionConfig.empty() ) ); + private static UnmanagedTransaction beginTx(Connection connection, Bookmark initialBookmark) { + UnmanagedTransaction tx = + new UnmanagedTransaction(connection, new DefaultBookmarkHolder(), UNLIMITED_FETCH_SIZE); + return await(tx.beginAsync(initialBookmark, TransactionConfig.empty())); } - private static Connection connectionWithBegin( Consumer beginBehaviour ) - { + private static Connection connectionWithBegin(Consumer beginBehaviour) { Connection connection = connectionMock(); - doAnswer( invocation -> - { - ResponseHandler beginHandler = invocation.getArgument( 1 ); - beginBehaviour.accept( beginHandler ); - return null; - } ).when( connection ).writeAndFlush( argThat( beginMessage() ), any() ); + doAnswer(invocation -> { + ResponseHandler beginHandler = invocation.getArgument(1); + beginBehaviour.accept(beginHandler); + return null; + }) + .when(connection) + .writeAndFlush(argThat(beginMessage()), any()); return connection; } - private ResultCursorsHolder mockResultCursorWith( ClientException clientException ) - { + private ResultCursorsHolder mockResultCursorWith(ClientException clientException) { ResultCursorsHolder resultCursorsHolder = new ResultCursorsHolder(); - FailableCursor cursor = mock( FailableCursor.class ); - doReturn( completedFuture( clientException ) ) - .when( cursor ) - .discardAllFailureAsync(); - resultCursorsHolder.add( completedFuture( cursor ) ); + FailableCursor cursor = mock(FailableCursor.class); + doReturn(completedFuture(clientException)).when(cursor).discardAllFailureAsync(); + resultCursorsHolder.add(completedFuture(cursor)); return resultCursorsHolder; } - private Supplier> mapTransactionAction( String actionName, UnmanagedTransaction tx ) - { + private Supplier> mapTransactionAction(String actionName, UnmanagedTransaction tx) { Supplier> action; - if ( "commit".equals( actionName ) ) - { + if ("commit".equals(actionName)) { action = tx::commitAsync; - } - else if ( "rollback".equals( actionName ) ) - { + } else if ("rollback".equals(actionName)) { action = tx::rollbackAsync; - } - else if ( "terminate".equals( actionName ) ) - { - action = () -> - { - tx.markTerminated( mock( Throwable.class ) ); - return completedFuture( null ); + } else if ("terminate".equals(actionName)) { + action = () -> { + tx.markTerminated(mock(Throwable.class)); + return completedFuture(null); }; - } - else if ( "close".equals( actionName ) ) - { + } else if ("close".equals(actionName)) { action = tx::closeAsync; - } - else - { - throw new RuntimeException( String.format( "Unknown completing action type '%s'", actionName ) ); + } else { + throw new RuntimeException(String.format("Unknown completing action type '%s'", actionName)); } return action; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java index eb4a22c00b..20075c00e5 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java @@ -18,15 +18,6 @@ */ package org.neo4j.driver.internal.async.connection; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; -import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; -import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41; -import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.BOLT_MAGIC_PREAMBLE; import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.handshakeBuf; @@ -36,61 +27,65 @@ import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.writeMessageBoundary; import static org.neo4j.driver.util.TestUtil.assertByteBufContains; -class BoltProtocolUtilTest -{ +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; +import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; +import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41; +import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44; + +class BoltProtocolUtilTest { @Test - void shouldReturnHandshakeBuf() - { + void shouldReturnHandshakeBuf() { assertByteBufContains( handshakeBuf(), - BOLT_MAGIC_PREAMBLE, (2 << 16) | BoltProtocolV44.VERSION.toInt(), BoltProtocolV41.VERSION.toInt(), - BoltProtocolV4.VERSION.toInt(), BoltProtocolV3.VERSION.toInt() - ); + BOLT_MAGIC_PREAMBLE, + (2 << 16) | BoltProtocolV44.VERSION.toInt(), + BoltProtocolV41.VERSION.toInt(), + BoltProtocolV4.VERSION.toInt(), + BoltProtocolV3.VERSION.toInt()); } @Test - void shouldReturnHandshakeString() - { - assertEquals( "[0x6060b017, 132100, 260, 4, 3]", handshakeString() ); + void shouldReturnHandshakeString() { + assertEquals("[0x6060b017, 132100, 260, 4, 3]", handshakeString()); } @Test - void shouldWriteMessageBoundary() - { + void shouldWriteMessageBoundary() { ByteBuf buf = Unpooled.buffer(); - buf.writeInt( 1 ); - buf.writeInt( 2 ); - buf.writeInt( 3 ); - writeMessageBoundary( buf ); + buf.writeInt(1); + buf.writeInt(2); + buf.writeInt(3); + writeMessageBoundary(buf); - assertByteBufContains( buf, 1, 2, 3, (byte) 0, (byte) 0 ); + assertByteBufContains(buf, 1, 2, 3, (byte) 0, (byte) 0); } @Test - void shouldWriteEmptyChunkHeader() - { + void shouldWriteEmptyChunkHeader() { ByteBuf buf = Unpooled.buffer(); - writeEmptyChunkHeader( buf ); - buf.writeInt( 1 ); - buf.writeInt( 2 ); - buf.writeInt( 3 ); + writeEmptyChunkHeader(buf); + buf.writeInt(1); + buf.writeInt(2); + buf.writeInt(3); - assertByteBufContains( buf, (byte) 0, (byte) 0, 1, 2, 3 ); + assertByteBufContains(buf, (byte) 0, (byte) 0, 1, 2, 3); } @Test - void shouldWriteChunkHeader() - { + void shouldWriteChunkHeader() { ByteBuf buf = Unpooled.buffer(); - writeEmptyChunkHeader( buf ); - buf.writeInt( 1 ); - buf.writeInt( 2 ); - buf.writeInt( 3 ); - writeChunkHeader( buf, 0, 42 ); + writeEmptyChunkHeader(buf); + buf.writeInt(1); + buf.writeInt(2); + buf.writeInt(3); + writeChunkHeader(buf, 0, 42); - assertByteBufContains( buf, (short) 42, 1, 2, 3 ); + assertByteBufContains(buf, (short) 42, 1, 2, 3); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelAttributesTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelAttributesTest.java index fef5808d8a..3e6e13c51d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelAttributesTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelAttributesTest.java @@ -18,14 +18,6 @@ */ package org.neo4j.driver.internal.async.connection; -import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; -import org.neo4j.driver.internal.messaging.BoltProtocolVersion; -import org.neo4j.driver.internal.util.ServerVersion; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -54,186 +46,171 @@ import static org.neo4j.driver.internal.async.connection.ChannelAttributes.terminationReason; import static org.neo4j.driver.internal.util.ServerVersion.version; -class ChannelAttributesTest -{ +import io.netty.channel.embedded.EmbeddedChannel; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; +import org.neo4j.driver.internal.messaging.BoltProtocolVersion; +import org.neo4j.driver.internal.util.ServerVersion; + +class ChannelAttributesTest { private final EmbeddedChannel channel = new EmbeddedChannel(); @Test - void shouldSetAndGetConnectionId() - { - setConnectionId( channel, "bolt-42" ); - assertEquals( "bolt-42", connectionId( channel ) ); + void shouldSetAndGetConnectionId() { + setConnectionId(channel, "bolt-42"); + assertEquals("bolt-42", connectionId(channel)); } @Test - void shouldFailToSetConnectionIdTwice() - { - setConnectionId( channel, "bolt-42" ); + void shouldFailToSetConnectionIdTwice() { + setConnectionId(channel, "bolt-42"); - assertThrows( IllegalStateException.class, () -> setConnectionId( channel, "bolt-4242" ) ); + assertThrows(IllegalStateException.class, () -> setConnectionId(channel, "bolt-4242")); } @Test - void shouldSetAndGetProtocolVersion() - { - setProtocolVersion( channel, new BoltProtocolVersion( 42, 0 ) ); - assertEquals( new BoltProtocolVersion( 42, 0 ), protocolVersion( channel ) ); + void shouldSetAndGetProtocolVersion() { + setProtocolVersion(channel, new BoltProtocolVersion(42, 0)); + assertEquals(new BoltProtocolVersion(42, 0), protocolVersion(channel)); } @Test - void shouldFailToSetProtocolVersionTwice() - { - setProtocolVersion( channel, new BoltProtocolVersion( 42, 0 ) ); + void shouldFailToSetProtocolVersionTwice() { + setProtocolVersion(channel, new BoltProtocolVersion(42, 0)); - assertThrows( IllegalStateException.class, () -> setProtocolVersion( channel, new BoltProtocolVersion( 43, 0 ) ) ); + assertThrows(IllegalStateException.class, () -> setProtocolVersion(channel, new BoltProtocolVersion(43, 0))); } @Test - void shouldSetAndGetServerAgent() - { + void shouldSetAndGetServerAgent() { String agent = "Neo4j/4.2.5"; - setServerAgent( channel, agent ); - assertEquals( agent, serverAgent( channel ) ); + setServerAgent(channel, agent); + assertEquals(agent, serverAgent(channel)); } @Test - void shouldFailToSetServerAgentTwice() - { + void shouldFailToSetServerAgentTwice() { String agent = "Neo4j/4.2.5"; - setServerAgent( channel, agent ); + setServerAgent(channel, agent); - assertThrows( IllegalStateException.class, () -> setServerAgent( channel, agent ) ); + assertThrows(IllegalStateException.class, () -> setServerAgent(channel, agent)); } @Test - void shouldSetAndGetAddress() - { - BoltServerAddress address = new BoltServerAddress( "local:42" ); - setServerAddress( channel, address ); - assertEquals( address, serverAddress( channel ) ); + void shouldSetAndGetAddress() { + BoltServerAddress address = new BoltServerAddress("local:42"); + setServerAddress(channel, address); + assertEquals(address, serverAddress(channel)); } @Test - void shouldFailToSetAddressTwice() - { - setServerAddress( channel, BoltServerAddress.LOCAL_DEFAULT ); + void shouldFailToSetAddressTwice() { + setServerAddress(channel, BoltServerAddress.LOCAL_DEFAULT); - assertThrows( IllegalStateException.class, () -> setServerAddress( channel, BoltServerAddress.LOCAL_DEFAULT ) ); + assertThrows(IllegalStateException.class, () -> setServerAddress(channel, BoltServerAddress.LOCAL_DEFAULT)); } @Test - void shouldSetAndGetCreationTimestamp() - { - setCreationTimestamp( channel, 42L ); - assertEquals( 42L, creationTimestamp( channel ) ); + void shouldSetAndGetCreationTimestamp() { + setCreationTimestamp(channel, 42L); + assertEquals(42L, creationTimestamp(channel)); } @Test - void shouldFailToSetCreationTimestampTwice() - { - setCreationTimestamp( channel, 42L ); + void shouldFailToSetCreationTimestampTwice() { + setCreationTimestamp(channel, 42L); - assertThrows( IllegalStateException.class, () -> setCreationTimestamp( channel, 42L ) ); + assertThrows(IllegalStateException.class, () -> setCreationTimestamp(channel, 42L)); } @Test - void shouldSetAndGetLastUsedTimestamp() - { - assertNull( lastUsedTimestamp( channel ) ); - setLastUsedTimestamp( channel, 42L ); - assertEquals( 42L, lastUsedTimestamp( channel ).longValue() ); + void shouldSetAndGetLastUsedTimestamp() { + assertNull(lastUsedTimestamp(channel)); + setLastUsedTimestamp(channel, 42L); + assertEquals(42L, lastUsedTimestamp(channel).longValue()); } @Test - void shouldAllowSettingLastUsedTimestampMultipleTimes() - { - setLastUsedTimestamp( channel, 42L ); - setLastUsedTimestamp( channel, 4242L ); - setLastUsedTimestamp( channel, 424242L ); + void shouldAllowSettingLastUsedTimestampMultipleTimes() { + setLastUsedTimestamp(channel, 42L); + setLastUsedTimestamp(channel, 4242L); + setLastUsedTimestamp(channel, 424242L); - assertEquals( 424242L, lastUsedTimestamp( channel ).longValue() ); + assertEquals(424242L, lastUsedTimestamp(channel).longValue()); } @Test - void shouldSetAndGetMessageDispatcher() - { - InboundMessageDispatcher dispatcher = mock( InboundMessageDispatcher.class ); - setMessageDispatcher( channel, dispatcher ); - assertEquals( dispatcher, messageDispatcher( channel ) ); + void shouldSetAndGetMessageDispatcher() { + InboundMessageDispatcher dispatcher = mock(InboundMessageDispatcher.class); + setMessageDispatcher(channel, dispatcher); + assertEquals(dispatcher, messageDispatcher(channel)); } @Test - void shouldFailToSetMessageDispatcherTwice() - { - setMessageDispatcher( channel, mock( InboundMessageDispatcher.class ) ); + void shouldFailToSetMessageDispatcherTwice() { + setMessageDispatcher(channel, mock(InboundMessageDispatcher.class)); - assertThrows( IllegalStateException.class, () -> setMessageDispatcher( channel, mock( InboundMessageDispatcher.class ) ) ); + assertThrows( + IllegalStateException.class, () -> setMessageDispatcher(channel, mock(InboundMessageDispatcher.class))); } @Test - void shouldSetAndGetServerVersion() - { - ServerVersion version = version( "Neo4j/3.2.1" ); - setServerVersion( channel, version ); - assertEquals( version, serverVersion( channel ) ); + void shouldSetAndGetServerVersion() { + ServerVersion version = version("Neo4j/3.2.1"); + setServerVersion(channel, version); + assertEquals(version, serverVersion(channel)); } @Test - void shouldFailToSetServerVersionTwice() - { - setServerVersion( channel, version( "Neo4j/3.2.2" ) ); + void shouldFailToSetServerVersionTwice() { + setServerVersion(channel, version("Neo4j/3.2.2")); - assertThrows( IllegalStateException.class, () -> setServerVersion( channel, version( "Neo4j/3.2.3" ) ) ); + assertThrows(IllegalStateException.class, () -> setServerVersion(channel, version("Neo4j/3.2.3"))); } @Test - void shouldSetAndGetTerminationReason() - { + void shouldSetAndGetTerminationReason() { String reason = "This channel has been terminated"; - setTerminationReason( channel, reason ); - assertEquals( reason, terminationReason( channel ) ); + setTerminationReason(channel, reason); + assertEquals(reason, terminationReason(channel)); } @Test - void shouldFailToSetTerminationReasonTwice() - { - setTerminationReason( channel, "Reason 1" ); + void shouldFailToSetTerminationReasonTwice() { + setTerminationReason(channel, "Reason 1"); - assertThrows( IllegalStateException.class, () -> setTerminationReason( channel, "Reason 2" ) ); + assertThrows(IllegalStateException.class, () -> setTerminationReason(channel, "Reason 2")); } @Test - void shouldSetAndGetAuthorizationStateListener() - { - AuthorizationStateListener listener = mock( AuthorizationStateListener.class ); - setAuthorizationStateListener( channel, listener ); - assertEquals( listener, authorizationStateListener( channel ) ); + void shouldSetAndGetAuthorizationStateListener() { + AuthorizationStateListener listener = mock(AuthorizationStateListener.class); + setAuthorizationStateListener(channel, listener); + assertEquals(listener, authorizationStateListener(channel)); } @Test - void shouldAllowOverridingAuthorizationStateListener() - { - AuthorizationStateListener listener = mock( AuthorizationStateListener.class ); - setAuthorizationStateListener( channel, listener ); - assertEquals( listener, authorizationStateListener( channel ) ); - AuthorizationStateListener newListener = mock( AuthorizationStateListener.class ); - setAuthorizationStateListener( channel, newListener ); - assertEquals( newListener, authorizationStateListener( channel ) ); + void shouldAllowOverridingAuthorizationStateListener() { + AuthorizationStateListener listener = mock(AuthorizationStateListener.class); + setAuthorizationStateListener(channel, listener); + assertEquals(listener, authorizationStateListener(channel)); + AuthorizationStateListener newListener = mock(AuthorizationStateListener.class); + setAuthorizationStateListener(channel, newListener); + assertEquals(newListener, authorizationStateListener(channel)); } @Test - void shouldSetAndGetConnectionReadTimeout() - { + void shouldSetAndGetConnectionReadTimeout() { long timeout = 15L; - setConnectionReadTimeout( channel, timeout ); - assertEquals( timeout, connectionReadTimeout( channel ).orElse( null ) ); + setConnectionReadTimeout(channel, timeout); + assertEquals(timeout, connectionReadTimeout(channel).orElse(null)); } @Test - void shouldFailToSetConnectionReadTimeoutTwice() - { + void shouldFailToSetConnectionReadTimeoutTwice() { long timeout = 15L; - setConnectionReadTimeout( channel, timeout ); - assertThrows( IllegalStateException.class, () -> setConnectionReadTimeout( channel, timeout ) ); + setConnectionReadTimeout(channel, timeout); + assertThrows(IllegalStateException.class, () -> setConnectionReadTimeout(channel, timeout)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelConnectedListenerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelConnectedListenerTest.java index ca454adf1e..7f35473b4a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelConnectedListenerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelConnectedListenerTest.java @@ -18,15 +18,6 @@ */ package org.neo4j.driver.internal.async.connection; -import io.netty.channel.ChannelPromise; -import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import org.neo4j.driver.exceptions.ServiceUnavailableException; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -36,51 +27,54 @@ import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.util.TestUtil.await; -class ChannelConnectedListenerTest -{ +import io.netty.channel.ChannelPromise; +import io.netty.channel.embedded.EmbeddedChannel; +import java.io.IOException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.ServiceUnavailableException; + +class ChannelConnectedListenerTest { private final EmbeddedChannel channel = new EmbeddedChannel(); @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldFailPromiseWhenChannelConnectionFails() - { + void shouldFailPromiseWhenChannelConnectionFails() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - ChannelConnectedListener listener = newListener( handshakeCompletedPromise ); + ChannelConnectedListener listener = newListener(handshakeCompletedPromise); ChannelPromise channelConnectedPromise = channel.newPromise(); - IOException cause = new IOException( "Unable to connect!" ); - channelConnectedPromise.setFailure( cause ); + IOException cause = new IOException("Unable to connect!"); + channelConnectedPromise.setFailure(cause); - listener.operationComplete( channelConnectedPromise ); + listener.operationComplete(channelConnectedPromise); - ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, () -> await( handshakeCompletedPromise ) ); - assertEquals( cause, error.getCause() ); + ServiceUnavailableException error = + assertThrows(ServiceUnavailableException.class, () -> await(handshakeCompletedPromise)); + assertEquals(cause, error.getCause()); } @Test - void shouldWriteHandshakeWhenChannelConnected() - { + void shouldWriteHandshakeWhenChannelConnected() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - ChannelConnectedListener listener = newListener( handshakeCompletedPromise ); + ChannelConnectedListener listener = newListener(handshakeCompletedPromise); ChannelPromise channelConnectedPromise = channel.newPromise(); channelConnectedPromise.setSuccess(); - listener.operationComplete( channelConnectedPromise ); + listener.operationComplete(channelConnectedPromise); - assertNotNull( channel.pipeline().get( HandshakeHandler.class ) ); - assertTrue( channel.finish() ); - assertEquals( handshakeBuf(), channel.readOutbound() ); + assertNotNull(channel.pipeline().get(HandshakeHandler.class)); + assertTrue(channel.finish()); + assertEquals(handshakeBuf(), channel.readOutbound()); } - private static ChannelConnectedListener newListener( ChannelPromise handshakeCompletedPromise ) - { - return new ChannelConnectedListener( LOCAL_DEFAULT, new ChannelPipelineBuilderImpl(), - handshakeCompletedPromise, DEV_NULL_LOGGING ); + private static ChannelConnectedListener newListener(ChannelPromise handshakeCompletedPromise) { + return new ChannelConnectedListener( + LOCAL_DEFAULT, new ChannelPipelineBuilderImpl(), handshakeCompletedPromise, DEV_NULL_LOGGING); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelErrorHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelErrorHandlerTest.java index 65f89d26c1..04f51e1d65 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelErrorHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelErrorHandlerTest.java @@ -18,18 +18,6 @@ */ package org.neo4j.driver.internal.async.connection; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.codec.CodecException; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import org.neo4j.driver.internal.async.inbound.ChannelErrorHandler; -import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; -import org.neo4j.driver.exceptions.ServiceUnavailableException; - import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.startsWith; @@ -40,132 +28,130 @@ import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setTerminationReason; import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -class ChannelErrorHandlerTest -{ +import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.handler.codec.CodecException; +import java.io.IOException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.ServiceUnavailableException; +import org.neo4j.driver.internal.async.inbound.ChannelErrorHandler; +import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; + +class ChannelErrorHandlerTest { private EmbeddedChannel channel; private InboundMessageDispatcher messageDispatcher; @BeforeEach - void setUp() - { + void setUp() { channel = new EmbeddedChannel(); - messageDispatcher = new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ); - setMessageDispatcher( channel, messageDispatcher ); - channel.pipeline().addLast( new ChannelErrorHandler( DEV_NULL_LOGGING ) ); + messageDispatcher = new InboundMessageDispatcher(channel, DEV_NULL_LOGGING); + setMessageDispatcher(channel, messageDispatcher); + channel.pipeline().addLast(new ChannelErrorHandler(DEV_NULL_LOGGING)); } @AfterEach - void tearDown() - { - if ( channel != null ) - { + void tearDown() { + if (channel != null) { channel.close(); } } @Test - void shouldHandleChannelInactive() - { + void shouldHandleChannelInactive() { channel.pipeline().fireChannelInactive(); Throwable error = messageDispatcher.currentError(); - assertThat( error, instanceOf( ServiceUnavailableException.class ) ); - assertThat( error.getMessage(), startsWith( "Connection to the database terminated" ) ); - assertFalse( channel.isOpen() ); + assertThat(error, instanceOf(ServiceUnavailableException.class)); + assertThat(error.getMessage(), startsWith("Connection to the database terminated")); + assertFalse(channel.isOpen()); } @Test - void shouldHandleChannelInactiveAfterExceptionCaught() - { - RuntimeException originalError = new RuntimeException( "Hi!" ); - channel.pipeline().fireExceptionCaught( originalError ); + void shouldHandleChannelInactiveAfterExceptionCaught() { + RuntimeException originalError = new RuntimeException("Hi!"); + channel.pipeline().fireExceptionCaught(originalError); channel.pipeline().fireChannelInactive(); Throwable error = messageDispatcher.currentError(); - assertEquals( originalError, error ); - assertFalse( channel.isOpen() ); + assertEquals(originalError, error); + assertFalse(channel.isOpen()); } @Test - void shouldHandleChannelInactiveWhenTerminationReasonSet() - { + void shouldHandleChannelInactiveWhenTerminationReasonSet() { String terminationReason = "Something really bad happened"; - setTerminationReason( channel, terminationReason ); + setTerminationReason(channel, terminationReason); channel.pipeline().fireChannelInactive(); Throwable error = messageDispatcher.currentError(); - assertThat( error, instanceOf( ServiceUnavailableException.class ) ); - assertThat( error.getMessage(), startsWith( "Connection to the database terminated" ) ); - assertThat( error.getMessage(), containsString( terminationReason ) ); - assertFalse( channel.isOpen() ); + assertThat(error, instanceOf(ServiceUnavailableException.class)); + assertThat(error.getMessage(), startsWith("Connection to the database terminated")); + assertThat(error.getMessage(), containsString(terminationReason)); + assertFalse(channel.isOpen()); } @Test - void shouldHandleCodecException() - { - RuntimeException cause = new RuntimeException( "Hi!" ); - CodecException codecException = new CodecException( "Unable to encode or decode message", cause ); - channel.pipeline().fireExceptionCaught( codecException ); + void shouldHandleCodecException() { + RuntimeException cause = new RuntimeException("Hi!"); + CodecException codecException = new CodecException("Unable to encode or decode message", cause); + channel.pipeline().fireExceptionCaught(codecException); Throwable error = messageDispatcher.currentError(); - assertEquals( cause, error ); - assertFalse( channel.isOpen() ); + assertEquals(cause, error); + assertFalse(channel.isOpen()); } @Test - void shouldHandleCodecExceptionWithoutCause() - { - CodecException codecException = new CodecException( "Unable to encode or decode message" ); - channel.pipeline().fireExceptionCaught( codecException ); + void shouldHandleCodecExceptionWithoutCause() { + CodecException codecException = new CodecException("Unable to encode or decode message"); + channel.pipeline().fireExceptionCaught(codecException); Throwable error = messageDispatcher.currentError(); - assertEquals( codecException, error ); - assertFalse( channel.isOpen() ); + assertEquals(codecException, error); + assertFalse(channel.isOpen()); } @Test - void shouldHandleIOException() - { - IOException ioException = new IOException( "Write or read failed" ); - channel.pipeline().fireExceptionCaught( ioException ); + void shouldHandleIOException() { + IOException ioException = new IOException("Write or read failed"); + channel.pipeline().fireExceptionCaught(ioException); Throwable error = messageDispatcher.currentError(); - assertThat( error, instanceOf( ServiceUnavailableException.class ) ); - assertEquals( ioException, error.getCause() ); - assertFalse( channel.isOpen() ); + assertThat(error, instanceOf(ServiceUnavailableException.class)); + assertEquals(ioException, error.getCause()); + assertFalse(channel.isOpen()); } @Test - void shouldHandleException() - { - RuntimeException originalError = new RuntimeException( "Random failure" ); - channel.pipeline().fireExceptionCaught( originalError ); + void shouldHandleException() { + RuntimeException originalError = new RuntimeException("Random failure"); + channel.pipeline().fireExceptionCaught(originalError); Throwable error = messageDispatcher.currentError(); - assertEquals( originalError, error ); - assertFalse( channel.isOpen() ); + assertEquals(originalError, error); + assertFalse(channel.isOpen()); } @Test - void shouldHandleMultipleExceptions() - { - RuntimeException error1 = new RuntimeException( "Failure 1" ); - RuntimeException error2 = new RuntimeException( "Failure 2" ); + void shouldHandleMultipleExceptions() { + RuntimeException error1 = new RuntimeException("Failure 1"); + RuntimeException error2 = new RuntimeException("Failure 2"); - channel.pipeline().fireExceptionCaught( error1 ); - channel.pipeline().fireExceptionCaught( error2 ); + channel.pipeline().fireExceptionCaught(error1); + channel.pipeline().fireExceptionCaught(error2); Throwable error = messageDispatcher.currentError(); - assertEquals( error1, error ); - assertFalse( channel.isOpen() ); + assertEquals(error1, error); + assertFalse(channel.isOpen()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilderImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilderImplTest.java index e4bc87b16e..6296f9a6b0 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilderImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/ChannelPipelineBuilderImplTest.java @@ -18,13 +18,16 @@ */ package org.neo4j.driver.internal.async.connection; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; + import io.netty.channel.ChannelHandler; import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.Test; - import java.util.Iterator; import java.util.Map; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.async.inbound.ChannelErrorHandler; import org.neo4j.driver.internal.async.inbound.ChunkDecoder; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; @@ -33,30 +36,24 @@ import org.neo4j.driver.internal.async.outbound.OutboundMessageHandler; import org.neo4j.driver.internal.messaging.v3.MessageFormatV3; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; - -class ChannelPipelineBuilderImplTest -{ +class ChannelPipelineBuilderImplTest { @Test - void shouldBuildPipeline() - { + void shouldBuildPipeline() { EmbeddedChannel channel = new EmbeddedChannel(); - ChannelAttributes.setMessageDispatcher( channel, new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ) ); + ChannelAttributes.setMessageDispatcher(channel, new InboundMessageDispatcher(channel, DEV_NULL_LOGGING)); - new ChannelPipelineBuilderImpl().build( new MessageFormatV3(), channel.pipeline(), DEV_NULL_LOGGING ); + new ChannelPipelineBuilderImpl().build(new MessageFormatV3(), channel.pipeline(), DEV_NULL_LOGGING); - Iterator> iterator = channel.pipeline().iterator(); - assertThat( iterator.next().getValue(), instanceOf( ChunkDecoder.class ) ); - assertThat( iterator.next().getValue(), instanceOf( MessageDecoder.class ) ); - assertThat( iterator.next().getValue(), instanceOf( InboundMessageHandler.class ) ); + Iterator> iterator = + channel.pipeline().iterator(); + assertThat(iterator.next().getValue(), instanceOf(ChunkDecoder.class)); + assertThat(iterator.next().getValue(), instanceOf(MessageDecoder.class)); + assertThat(iterator.next().getValue(), instanceOf(InboundMessageHandler.class)); - assertThat( iterator.next().getValue(), instanceOf( OutboundMessageHandler.class ) ); + assertThat(iterator.next().getValue(), instanceOf(OutboundMessageHandler.class)); - assertThat( iterator.next().getValue(), instanceOf( ChannelErrorHandler.class ) ); + assertThat(iterator.next().getValue(), instanceOf(ChannelErrorHandler.class)); - assertFalse( iterator.hasNext() ); + assertFalse(iterator.hasNext()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/DecoratedConnectionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/DecoratedConnectionTest.java index 3892160fa8..e868bb9372 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/DecoratedConnectionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/DecoratedConnectionTest.java @@ -18,11 +18,18 @@ */ package org.neo4j.driver.internal.async.connection; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; + import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.ValueSource; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.messaging.BoltProtocol; @@ -32,200 +39,175 @@ import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.net.ServerAddress; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; - -class DecoratedConnectionTest -{ +class DecoratedConnectionTest { @ParameterizedTest - @ValueSource( strings = {"true", "false"} ) - void shouldDelegateIsOpen( String open ) - { - Connection mockConnection = mock( Connection.class ); - when( mockConnection.isOpen() ).thenReturn( Boolean.valueOf( open ) ); + @ValueSource(strings = {"true", "false"}) + void shouldDelegateIsOpen(String open) { + Connection mockConnection = mock(Connection.class); + when(mockConnection.isOpen()).thenReturn(Boolean.valueOf(open)); - DirectConnection connection = newConnection( mockConnection ); + DirectConnection connection = newConnection(mockConnection); - assertEquals( Boolean.valueOf( open ).booleanValue(), connection.isOpen() ); - verify( mockConnection ).isOpen(); + assertEquals(Boolean.valueOf(open).booleanValue(), connection.isOpen()); + verify(mockConnection).isOpen(); } @Test - void shouldDelegateEnableAutoRead() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateEnableAutoRead() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); connection.enableAutoRead(); - verify( mockConnection ).enableAutoRead(); + verify(mockConnection).enableAutoRead(); } @Test - void shouldDelegateDisableAutoRead() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateDisableAutoRead() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); connection.disableAutoRead(); - verify( mockConnection ).disableAutoRead(); + verify(mockConnection).disableAutoRead(); } @Test - void shouldDelegateWrite() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateWrite() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); - Message message = mock( Message.class ); - ResponseHandler handler = mock( ResponseHandler.class ); + Message message = mock(Message.class); + ResponseHandler handler = mock(ResponseHandler.class); - connection.write( message, handler ); + connection.write(message, handler); - verify( mockConnection ).write( message, handler ); + verify(mockConnection).write(message, handler); } @Test - void shouldDelegateWriteTwoMessages() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateWriteTwoMessages() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); - Message message1 = mock( Message.class ); - ResponseHandler handler1 = mock( ResponseHandler.class ); - Message message2 = mock( Message.class ); - ResponseHandler handler2 = mock( ResponseHandler.class ); + Message message1 = mock(Message.class); + ResponseHandler handler1 = mock(ResponseHandler.class); + Message message2 = mock(Message.class); + ResponseHandler handler2 = mock(ResponseHandler.class); - connection.write( message1, handler1, message2, handler2 ); + connection.write(message1, handler1, message2, handler2); - verify( mockConnection ).write( message1, handler1, message2, handler2 ); + verify(mockConnection).write(message1, handler1, message2, handler2); } @Test - void shouldDelegateWriteAndFlush() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateWriteAndFlush() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); - Message message = mock( Message.class ); - ResponseHandler handler = mock( ResponseHandler.class ); + Message message = mock(Message.class); + ResponseHandler handler = mock(ResponseHandler.class); - connection.writeAndFlush( message, handler ); + connection.writeAndFlush(message, handler); - verify( mockConnection ).writeAndFlush( message, handler ); + verify(mockConnection).writeAndFlush(message, handler); } @Test - void shouldDelegateWriteAndFlush1() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateWriteAndFlush1() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); - Message message1 = mock( Message.class ); - ResponseHandler handler1 = mock( ResponseHandler.class ); - Message message2 = mock( Message.class ); - ResponseHandler handler2 = mock( ResponseHandler.class ); + Message message1 = mock(Message.class); + ResponseHandler handler1 = mock(ResponseHandler.class); + Message message2 = mock(Message.class); + ResponseHandler handler2 = mock(ResponseHandler.class); - connection.writeAndFlush( message1, handler1, message2, handler2 ); + connection.writeAndFlush(message1, handler1, message2, handler2); - verify( mockConnection ).writeAndFlush( message1, handler1, message2, handler2 ); + verify(mockConnection).writeAndFlush(message1, handler1, message2, handler2); } @Test - void shouldDelegateReset() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateReset() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); connection.reset(); - verify( mockConnection ).reset(); + verify(mockConnection).reset(); } @Test - void shouldDelegateRelease() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateRelease() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); connection.release(); - verify( mockConnection ).release(); + verify(mockConnection).release(); } @Test - void shouldDelegateTerminateAndRelease() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateTerminateAndRelease() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); - connection.terminateAndRelease( "a reason" ); + connection.terminateAndRelease("a reason"); - verify( mockConnection ).terminateAndRelease( "a reason" ); + verify(mockConnection).terminateAndRelease("a reason"); } @Test - void shouldDelegateServerAddress() - { - BoltServerAddress address = BoltServerAddress.from( ServerAddress.of( "localhost", 9999 ) ); - Connection mockConnection = mock( Connection.class ); - when( mockConnection.serverAddress() ).thenReturn( address ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateServerAddress() { + BoltServerAddress address = BoltServerAddress.from(ServerAddress.of("localhost", 9999)); + Connection mockConnection = mock(Connection.class); + when(mockConnection.serverAddress()).thenReturn(address); + DirectConnection connection = newConnection(mockConnection); - assertSame( address, connection.serverAddress() ); - verify( mockConnection ).serverAddress(); + assertSame(address, connection.serverAddress()); + verify(mockConnection).serverAddress(); } @Test - void shouldDelegateServerVersion() - { - ServerVersion version = ServerVersion.version( "Neo4j/3.5.3" ); - Connection mockConnection = mock( Connection.class ); - when( mockConnection.serverVersion() ).thenReturn( version ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateServerVersion() { + ServerVersion version = ServerVersion.version("Neo4j/3.5.3"); + Connection mockConnection = mock(Connection.class); + when(mockConnection.serverVersion()).thenReturn(version); + DirectConnection connection = newConnection(mockConnection); - assertSame( version, connection.serverVersion() ); - verify( mockConnection ).serverVersion(); + assertSame(version, connection.serverVersion()); + verify(mockConnection).serverVersion(); } @Test - void shouldDelegateProtocol() - { - BoltProtocol protocol = mock( BoltProtocol.class ); - Connection mockConnection = mock( Connection.class ); - when( mockConnection.protocol() ).thenReturn( protocol ); - DirectConnection connection = newConnection( mockConnection ); + void shouldDelegateProtocol() { + BoltProtocol protocol = mock(BoltProtocol.class); + Connection mockConnection = mock(Connection.class); + when(mockConnection.protocol()).thenReturn(protocol); + DirectConnection connection = newConnection(mockConnection); - assertSame( protocol, connection.protocol() ); - verify( mockConnection ).protocol(); + assertSame(protocol, connection.protocol()); + verify(mockConnection).protocol(); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldReturnModeFromConstructor( AccessMode mode ) - { - DirectConnection connection = new DirectConnection( mock( Connection.class ), defaultDatabase(), mode, null ); + @EnumSource(AccessMode.class) + void shouldReturnModeFromConstructor(AccessMode mode) { + DirectConnection connection = new DirectConnection(mock(Connection.class), defaultDatabase(), mode, null); - assertEquals( mode, connection.mode() ); + assertEquals(mode, connection.mode()); } @Test - void shouldReturnConnection() - { - Connection mockConnection = mock( Connection.class ); - DirectConnection connection = newConnection( mockConnection ); + void shouldReturnConnection() { + Connection mockConnection = mock(Connection.class); + DirectConnection connection = newConnection(mockConnection); - assertSame( mockConnection, connection.connection() ); + assertSame(mockConnection, connection.connection()); } - - private static DirectConnection newConnection( Connection connection ) - { - return new DirectConnection( connection, defaultDatabase(), READ, null ); + + private static DirectConnection newConnection(Connection connection) { + return new DirectConnection(connection, defaultDatabase(), READ, null); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/DirectConnectionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/DirectConnectionTest.java index 4997cbdcb7..9dc25116b0 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/DirectConnectionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/DirectConnectionTest.java @@ -18,10 +18,6 @@ */ package org.neo4j.driver.internal.async.connection; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.spi.Connection; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; @@ -29,22 +25,23 @@ import static org.neo4j.driver.AccessMode.READ; import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -public class DirectConnectionTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.spi.Connection; + +public class DirectConnectionTest { @Test - void shouldReturnServerAgent() - { + void shouldReturnServerAgent() { // given - Connection connection = mock( Connection.class ); - DirectConnection directConnection = new DirectConnection( connection, defaultDatabase(), READ, null ); + Connection connection = mock(Connection.class); + DirectConnection directConnection = new DirectConnection(connection, defaultDatabase(), READ, null); String agent = "Neo4j/4.2.5"; - given( connection.serverAgent() ).willReturn( agent ); + given(connection.serverAgent()).willReturn(agent); // when String actualAgent = directConnection.serverAgent(); // then - assertEquals( agent, actualAgent ); - then( connection ).should().serverAgent(); + assertEquals(agent, actualAgent); + then(connection).should().serverAgent(); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/EventLoopGroupFactoryTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/EventLoopGroupFactoryTest.java index 3a3eac3508..b430e598ff 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/EventLoopGroupFactoryTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/EventLoopGroupFactoryTest.java @@ -18,15 +18,6 @@ */ package org.neo4j.driver.internal.async.connection; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.util.concurrent.Future; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.ExecutionException; - import static java.util.concurrent.TimeUnit.SECONDS; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; @@ -38,55 +29,57 @@ import static org.neo4j.driver.internal.util.Iterables.count; import static org.neo4j.driver.internal.util.Matchers.blockingOperationInEventLoopError; -class EventLoopGroupFactoryTest -{ +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.util.concurrent.Future; +import java.util.concurrent.ExecutionException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class EventLoopGroupFactoryTest { private EventLoopGroup eventLoopGroup; @AfterEach - void tearDown() - { - shutdown( eventLoopGroup ); + void tearDown() { + shutdown(eventLoopGroup); } @Test - void shouldReturnCorrectChannelClass() - { - assertEquals( NioSocketChannel.class, EventLoopGroupFactory.channelClass() ); + void shouldReturnCorrectChannelClass() { + assertEquals(NioSocketChannel.class, EventLoopGroupFactory.channelClass()); } @Test - void shouldCreateEventLoopGroupWithSpecifiedThreadCount() - { + void shouldCreateEventLoopGroupWithSpecifiedThreadCount() { int threadCount = 2; - eventLoopGroup = EventLoopGroupFactory.newEventLoopGroup( threadCount ); - assertEquals( threadCount, count( eventLoopGroup ) ); - assertThat( eventLoopGroup, instanceOf( NioEventLoopGroup.class ) ); + eventLoopGroup = EventLoopGroupFactory.newEventLoopGroup(threadCount); + assertEquals(threadCount, count(eventLoopGroup)); + assertThat(eventLoopGroup, instanceOf(NioEventLoopGroup.class)); } @Test - void shouldAssertNotInEventLoopThread() throws Exception - { - eventLoopGroup = EventLoopGroupFactory.newEventLoopGroup( 1 ); + void shouldAssertNotInEventLoopThread() throws Exception { + eventLoopGroup = EventLoopGroupFactory.newEventLoopGroup(1); // current thread is not an event loop thread, assertion should not throw EventLoopGroupFactory.assertNotInEventLoopThread(); // submit assertion to the event loop thread, it should fail there - Future assertFuture = eventLoopGroup.submit( EventLoopGroupFactory::assertNotInEventLoopThread ); + Future assertFuture = eventLoopGroup.submit(EventLoopGroupFactory::assertNotInEventLoopThread); - ExecutionException error = assertThrows( ExecutionException.class, () -> assertFuture.get( 30, SECONDS ) ); - assertThat( error.getCause(), is( blockingOperationInEventLoopError() ) ); + ExecutionException error = assertThrows(ExecutionException.class, () -> assertFuture.get(30, SECONDS)); + assertThat(error.getCause(), is(blockingOperationInEventLoopError())); } @Test - void shouldCheckIfEventLoopThread() throws Exception - { - eventLoopGroup = EventLoopGroupFactory.newEventLoopGroup( 1 ); + void shouldCheckIfEventLoopThread() throws Exception { + eventLoopGroup = EventLoopGroupFactory.newEventLoopGroup(1); - Thread eventLoopThread = getThread( eventLoopGroup ); - assertTrue( EventLoopGroupFactory.isEventLoopThread( eventLoopThread ) ); + Thread eventLoopThread = getThread(eventLoopGroup); + assertTrue(EventLoopGroupFactory.isEventLoopThread(eventLoopThread)); - assertFalse( EventLoopGroupFactory.isEventLoopThread( Thread.currentThread() ) ); + assertFalse(EventLoopGroupFactory.isEventLoopThread(Thread.currentThread())); } /** @@ -94,39 +87,29 @@ void shouldCheckIfEventLoopThread() throws Exception * It's needed because default Netty setup has good performance. */ @Test - void shouldUseSameThreadClassAsNioEventLoopGroupDoesByDefault() throws Exception - { - NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup( 1 ); - eventLoopGroup = EventLoopGroupFactory.newEventLoopGroup( 1 ); - try - { - Thread defaultThread = getThread( nioEventLoopGroup ); - Thread driverThread = getThread( eventLoopGroup ); - - assertEquals( defaultThread.getClass(), driverThread.getClass().getSuperclass() ); - assertEquals( defaultThread.getPriority(), driverThread.getPriority() ); - } - finally - { - shutdown( nioEventLoopGroup ); + void shouldUseSameThreadClassAsNioEventLoopGroupDoesByDefault() throws Exception { + NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(1); + eventLoopGroup = EventLoopGroupFactory.newEventLoopGroup(1); + try { + Thread defaultThread = getThread(nioEventLoopGroup); + Thread driverThread = getThread(eventLoopGroup); + + assertEquals(defaultThread.getClass(), driverThread.getClass().getSuperclass()); + assertEquals(defaultThread.getPriority(), driverThread.getPriority()); + } finally { + shutdown(nioEventLoopGroup); } } - private static Thread getThread( EventLoopGroup eventLoopGroup ) throws Exception - { - return eventLoopGroup.submit( Thread::currentThread ).get( 10, SECONDS ); + private static Thread getThread(EventLoopGroup eventLoopGroup) throws Exception { + return eventLoopGroup.submit(Thread::currentThread).get(10, SECONDS); } - private static void shutdown( EventLoopGroup group ) - { - if ( group != null ) - { - try - { + private static void shutdown(EventLoopGroup group) { + if (group != null) { + try { group.shutdownGracefully().syncUninterruptibly(); - } - catch ( Throwable ignore ) - { + } catch (Throwable ignore) { } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListenerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListenerTest.java index 15a0639059..2ed8bbe606 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListenerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeCompletedListenerTest.java @@ -18,14 +18,22 @@ */ package org.neo4j.driver.internal.async.connection; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setProtocolVersion; +import static org.neo4j.driver.util.TestUtil.await; + import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - import java.io.IOException; import java.util.Collections; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.cluster.RoutingContext; @@ -37,74 +45,64 @@ import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.spi.ResponseHandler; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setProtocolVersion; -import static org.neo4j.driver.util.TestUtil.await; - -class HandshakeCompletedListenerTest -{ +class HandshakeCompletedListenerTest { private static final String USER_AGENT = "user-agent"; private final EmbeddedChannel channel = new EmbeddedChannel(); @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldFailConnectionInitializedPromiseWhenHandshakeFails() - { + void shouldFailConnectionInitializedPromiseWhenHandshakeFails() { ChannelPromise channelInitializedPromise = channel.newPromise(); - HandshakeCompletedListener listener = new HandshakeCompletedListener( "user-agent", authToken(), RoutingContext.EMPTY, - channelInitializedPromise ); + HandshakeCompletedListener listener = new HandshakeCompletedListener( + "user-agent", authToken(), RoutingContext.EMPTY, channelInitializedPromise); ChannelPromise handshakeCompletedPromise = channel.newPromise(); - IOException cause = new IOException( "Bad handshake" ); - handshakeCompletedPromise.setFailure( cause ); + IOException cause = new IOException("Bad handshake"); + handshakeCompletedPromise.setFailure(cause); - listener.operationComplete( handshakeCompletedPromise ); + listener.operationComplete(handshakeCompletedPromise); - Exception error = assertThrows( Exception.class, () -> await( channelInitializedPromise ) ); - assertEquals( cause, error ); + Exception error = assertThrows(Exception.class, () -> await(channelInitializedPromise)); + assertEquals(cause, error); } @Test - void shouldWriteInitializationMessageInBoltV3WhenHandshakeCompleted() - { - testWritingOfInitializationMessage( BoltProtocolV3.VERSION, new HelloMessage( USER_AGENT, authToken().toMap(), Collections.emptyMap() ), HelloResponseHandler.class ); + void shouldWriteInitializationMessageInBoltV3WhenHandshakeCompleted() { + testWritingOfInitializationMessage( + BoltProtocolV3.VERSION, + new HelloMessage(USER_AGENT, authToken().toMap(), Collections.emptyMap()), + HelloResponseHandler.class); } - private void testWritingOfInitializationMessage( BoltProtocolVersion protocolVersion, Message expectedMessage, Class handlerType ) - { - InboundMessageDispatcher messageDispatcher = mock( InboundMessageDispatcher.class ); - setProtocolVersion( channel, protocolVersion ); - setMessageDispatcher( channel, messageDispatcher ); + private void testWritingOfInitializationMessage( + BoltProtocolVersion protocolVersion, + Message expectedMessage, + Class handlerType) { + InboundMessageDispatcher messageDispatcher = mock(InboundMessageDispatcher.class); + setProtocolVersion(channel, protocolVersion); + setMessageDispatcher(channel, messageDispatcher); ChannelPromise channelInitializedPromise = channel.newPromise(); - HandshakeCompletedListener listener = new HandshakeCompletedListener( USER_AGENT, authToken(), RoutingContext.EMPTY, - channelInitializedPromise ); + HandshakeCompletedListener listener = new HandshakeCompletedListener( + USER_AGENT, authToken(), RoutingContext.EMPTY, channelInitializedPromise); ChannelPromise handshakeCompletedPromise = channel.newPromise(); handshakeCompletedPromise.setSuccess(); - listener.operationComplete( handshakeCompletedPromise ); - assertTrue( channel.finish() ); + listener.operationComplete(handshakeCompletedPromise); + assertTrue(channel.finish()); - verify( messageDispatcher ).enqueue( any( handlerType ) ); + verify(messageDispatcher).enqueue(any(handlerType)); Object outboundMessage = channel.readOutbound(); - assertEquals( expectedMessage, outboundMessage ); + assertEquals(expectedMessage, outboundMessage); } - private static InternalAuthToken authToken() - { - return (InternalAuthToken) AuthTokens.basic( "neo4j", "secret" ); + private static InternalAuthToken authToken() { + return (InternalAuthToken) AuthTokens.basic("neo4j", "secret"); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeHandlerTest.java index 4650e9fa29..cf048f1b7b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeHandlerTest.java @@ -18,21 +18,33 @@ */ package org.neo4j.driver.internal.async.connection; +import static io.netty.buffer.Unpooled.copyInt; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.params.provider.Arguments.arguments; +import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.NO_PROTOCOL_VERSION; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.util.TestUtil.await; + import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.codec.DecoderException; +import java.io.IOException; +import java.util.stream.Stream; +import javax.net.ssl.SSLHandshakeException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - -import java.io.IOException; -import java.util.stream.Stream; -import javax.net.ssl.SSLHandshakeException; - import org.neo4j.driver.Logging; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.SecurityException; @@ -52,259 +64,234 @@ import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42; import org.neo4j.driver.internal.util.ErrorUtil; -import static io.netty.buffer.Unpooled.copyInt; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.params.provider.Arguments.arguments; -import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.NO_PROTOCOL_VERSION; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.util.TestUtil.await; - -class HandshakeHandlerTest -{ +class HandshakeHandlerTest { private final EmbeddedChannel channel = new EmbeddedChannel(); @BeforeEach - void setUp() - { - setMessageDispatcher( channel, new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ) ); + void setUp() { + setMessageDispatcher(channel, new InboundMessageDispatcher(channel, DEV_NULL_LOGGING)); } @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldFailGivenPromiseWhenExceptionCaught() - { + void shouldFailGivenPromiseWhenExceptionCaught() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeHandler handler = newHandler( handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(handshakeCompletedPromise); + channel.pipeline().addLast(handler); - RuntimeException cause = new RuntimeException( "Error!" ); - channel.pipeline().fireExceptionCaught( cause ); + RuntimeException cause = new RuntimeException("Error!"); + channel.pipeline().fireExceptionCaught(cause); // promise should fail - ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, () -> await( handshakeCompletedPromise ) ); - assertEquals( cause, error.getCause() ); + ServiceUnavailableException error = + assertThrows(ServiceUnavailableException.class, () -> await(handshakeCompletedPromise)); + assertEquals(cause, error.getCause()); // channel should be closed - assertNull( await( channel.closeFuture() ) ); + assertNull(await(channel.closeFuture())); } @Test - void shouldFailGivenPromiseWhenServiceUnavailableExceptionCaught() - { + void shouldFailGivenPromiseWhenServiceUnavailableExceptionCaught() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeHandler handler = newHandler( handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(handshakeCompletedPromise); + channel.pipeline().addLast(handler); - ServiceUnavailableException error = new ServiceUnavailableException( "Bad error" ); - channel.pipeline().fireExceptionCaught( error ); + ServiceUnavailableException error = new ServiceUnavailableException("Bad error"); + channel.pipeline().fireExceptionCaught(error); // promise should fail - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, () -> await( handshakeCompletedPromise ) ); - assertEquals( error, e ); + ServiceUnavailableException e = + assertThrows(ServiceUnavailableException.class, () -> await(handshakeCompletedPromise)); + assertEquals(error, e); // channel should be closed - assertNull( await( channel.closeFuture() ) ); + assertNull(await(channel.closeFuture())); } @Test - void shouldFailGivenPromiseWhenMultipleExceptionsCaught() - { + void shouldFailGivenPromiseWhenMultipleExceptionsCaught() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeHandler handler = newHandler( handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(handshakeCompletedPromise); + channel.pipeline().addLast(handler); - RuntimeException error1 = new RuntimeException( "Error 1" ); - RuntimeException error2 = new RuntimeException( "Error 2" ); - channel.pipeline().fireExceptionCaught( error1 ); - channel.pipeline().fireExceptionCaught( error2 ); + RuntimeException error1 = new RuntimeException("Error 1"); + RuntimeException error2 = new RuntimeException("Error 2"); + channel.pipeline().fireExceptionCaught(error1); + channel.pipeline().fireExceptionCaught(error2); // promise should fail - ServiceUnavailableException e1 = assertThrows( ServiceUnavailableException.class, () -> await( handshakeCompletedPromise ) ); - assertEquals( error1, e1.getCause() ); + ServiceUnavailableException e1 = + assertThrows(ServiceUnavailableException.class, () -> await(handshakeCompletedPromise)); + assertEquals(error1, e1.getCause()); // channel should be closed - assertNull( await( channel.closeFuture() ) ); + assertNull(await(channel.closeFuture())); - RuntimeException e2 = assertThrows( RuntimeException.class, channel::checkException ); - assertEquals( error2, e2 ); + RuntimeException e2 = assertThrows(RuntimeException.class, channel::checkException); + assertEquals(error2, e2); } @Test - void shouldUnwrapDecoderException() - { + void shouldUnwrapDecoderException() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeHandler handler = newHandler( handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(handshakeCompletedPromise); + channel.pipeline().addLast(handler); - IOException cause = new IOException( "Error!" ); - channel.pipeline().fireExceptionCaught( new DecoderException( cause ) ); + IOException cause = new IOException("Error!"); + channel.pipeline().fireExceptionCaught(new DecoderException(cause)); // promise should fail - ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, () -> await( handshakeCompletedPromise ) ); - assertEquals( cause, error.getCause() ); + ServiceUnavailableException error = + assertThrows(ServiceUnavailableException.class, () -> await(handshakeCompletedPromise)); + assertEquals(cause, error.getCause()); // channel should be closed - assertNull( await( channel.closeFuture() ) ); + assertNull(await(channel.closeFuture())); } @Test - void shouldHandleDecoderExceptionWithoutCause() - { + void shouldHandleDecoderExceptionWithoutCause() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeHandler handler = newHandler( handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(handshakeCompletedPromise); + channel.pipeline().addLast(handler); - DecoderException decoderException = new DecoderException( "Unable to decode a message" ); - channel.pipeline().fireExceptionCaught( decoderException ); + DecoderException decoderException = new DecoderException("Unable to decode a message"); + channel.pipeline().fireExceptionCaught(decoderException); - ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, () -> await( handshakeCompletedPromise ) ); - assertEquals( decoderException, error.getCause() ); + ServiceUnavailableException error = + assertThrows(ServiceUnavailableException.class, () -> await(handshakeCompletedPromise)); + assertEquals(decoderException, error.getCause()); // channel should be closed - assertNull( await( channel.closeFuture() ) ); + assertNull(await(channel.closeFuture())); } @Test - void shouldTranslateSSLHandshakeException() - { + void shouldTranslateSSLHandshakeException() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeHandler handler = newHandler( handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(handshakeCompletedPromise); + channel.pipeline().addLast(handler); - SSLHandshakeException error = new SSLHandshakeException( "Invalid certificate" ); - channel.pipeline().fireExceptionCaught( error ); + SSLHandshakeException error = new SSLHandshakeException("Invalid certificate"); + channel.pipeline().fireExceptionCaught(error); // promise should fail - SecurityException e = assertThrows( SecurityException.class, () -> await( handshakeCompletedPromise ) ); - assertEquals( error, e.getCause() ); + SecurityException e = assertThrows(SecurityException.class, () -> await(handshakeCompletedPromise)); + assertEquals(error, e.getCause()); // channel should be closed - assertNull( await( channel.closeFuture() ) ); + assertNull(await(channel.closeFuture())); } @ParameterizedTest - @MethodSource( "protocolVersions" ) - public void testProtocolSelection( BoltProtocolVersion protocolVersion, Class expectedMessageFormatClass ) - { + @MethodSource("protocolVersions") + public void testProtocolSelection( + BoltProtocolVersion protocolVersion, Class expectedMessageFormatClass) { ChannelPromise handshakeCompletedPromise = channel.newPromise(); MemorizingChannelPipelineBuilder pipelineBuilder = new MemorizingChannelPipelineBuilder(); - HandshakeHandler handler = newHandler( pipelineBuilder, handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(pipelineBuilder, handshakeCompletedPromise); + channel.pipeline().addLast(handler); - channel.pipeline().fireChannelRead( copyInt( protocolVersion.toInt() ) ); + channel.pipeline().fireChannelRead(copyInt(protocolVersion.toInt())); // expected message format should've been used - assertThat( pipelineBuilder.usedMessageFormat, instanceOf( expectedMessageFormatClass ) ); + assertThat(pipelineBuilder.usedMessageFormat, instanceOf(expectedMessageFormatClass)); // handshake handler itself should be removed - assertNull( channel.pipeline().get( HandshakeHandler.class ) ); + assertNull(channel.pipeline().get(HandshakeHandler.class)); // all inbound handlers should be set - assertNotNull( channel.pipeline().get( ChunkDecoder.class ) ); - assertNotNull( channel.pipeline().get( MessageDecoder.class ) ); - assertNotNull( channel.pipeline().get( InboundMessageHandler.class ) ); + assertNotNull(channel.pipeline().get(ChunkDecoder.class)); + assertNotNull(channel.pipeline().get(MessageDecoder.class)); + assertNotNull(channel.pipeline().get(InboundMessageHandler.class)); // all outbound handlers should be set - assertNotNull( channel.pipeline().get( OutboundMessageHandler.class ) ); + assertNotNull(channel.pipeline().get(OutboundMessageHandler.class)); // promise should be successful - assertNull( await( handshakeCompletedPromise ) ); + assertNull(await(handshakeCompletedPromise)); } @Test - void shouldFailGivenPromiseWhenServerSuggestsNoProtocol() - { - testFailure( NO_PROTOCOL_VERSION, "The server does not support any of the protocol versions" ); + void shouldFailGivenPromiseWhenServerSuggestsNoProtocol() { + testFailure(NO_PROTOCOL_VERSION, "The server does not support any of the protocol versions"); } @Test - void shouldFailGivenPromiseWhenServerSuggestsHttp() - { - testFailure( new BoltProtocolVersion( 80, 84 ), "Server responded HTTP" ); + void shouldFailGivenPromiseWhenServerSuggestsHttp() { + testFailure(new BoltProtocolVersion(80, 84), "Server responded HTTP"); } @Test - void shouldFailGivenPromiseWhenServerSuggestsUnknownProtocol() - { - testFailure( new BoltProtocolVersion( 42, 0 ), "Protocol error" ); + void shouldFailGivenPromiseWhenServerSuggestsUnknownProtocol() { + testFailure(new BoltProtocolVersion(42, 0), "Protocol error"); } @Test - void shouldFailGivenPromiseWhenChannelInactive() - { + void shouldFailGivenPromiseWhenChannelInactive() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeHandler handler = newHandler( handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(handshakeCompletedPromise); + channel.pipeline().addLast(handler); channel.pipeline().fireChannelInactive(); // promise should fail - ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, () -> await( handshakeCompletedPromise ) ); - assertEquals( ErrorUtil.newConnectionTerminatedError().getMessage(), error.getMessage() ); + ServiceUnavailableException error = + assertThrows(ServiceUnavailableException.class, () -> await(handshakeCompletedPromise)); + assertEquals(ErrorUtil.newConnectionTerminatedError().getMessage(), error.getMessage()); // channel should be closed - assertNull( await( channel.closeFuture() ) ); + assertNull(await(channel.closeFuture())); } - private void testFailure( BoltProtocolVersion serverSuggestedVersion, String expectedMessagePrefix ) - { + private void testFailure(BoltProtocolVersion serverSuggestedVersion, String expectedMessagePrefix) { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeHandler handler = newHandler( handshakeCompletedPromise ); - channel.pipeline().addLast( handler ); + HandshakeHandler handler = newHandler(handshakeCompletedPromise); + channel.pipeline().addLast(handler); - channel.pipeline().fireChannelRead( copyInt( serverSuggestedVersion.toInt() ) ); + channel.pipeline().fireChannelRead(copyInt(serverSuggestedVersion.toInt())); // handshake handler itself should be removed - assertNull( channel.pipeline().get( HandshakeHandler.class ) ); + assertNull(channel.pipeline().get(HandshakeHandler.class)); // promise should fail - Exception error = assertThrows( Exception.class, () -> await( handshakeCompletedPromise ) ); - assertThat( error, instanceOf( ClientException.class ) ); - assertThat( error.getMessage(), startsWith( expectedMessagePrefix ) ); + Exception error = assertThrows(Exception.class, () -> await(handshakeCompletedPromise)); + assertThat(error, instanceOf(ClientException.class)); + assertThat(error.getMessage(), startsWith(expectedMessagePrefix)); // channel should be closed - assertNull( await( channel.closeFuture() ) ); + assertNull(await(channel.closeFuture())); } - private static Stream protocolVersions() - { - return Stream.of( arguments( BoltProtocolV3.VERSION, MessageFormatV3.class ), - arguments( BoltProtocolV4.VERSION, MessageFormatV4.class ), - arguments( BoltProtocolV41.VERSION, MessageFormatV4.class ), - arguments( BoltProtocolV42.VERSION, MessageFormatV4.class ) ); + private static Stream protocolVersions() { + return Stream.of( + arguments(BoltProtocolV3.VERSION, MessageFormatV3.class), + arguments(BoltProtocolV4.VERSION, MessageFormatV4.class), + arguments(BoltProtocolV41.VERSION, MessageFormatV4.class), + arguments(BoltProtocolV42.VERSION, MessageFormatV4.class)); } - private static HandshakeHandler newHandler( ChannelPromise handshakeCompletedPromise ) - { - return newHandler( new ChannelPipelineBuilderImpl(), handshakeCompletedPromise ); + private static HandshakeHandler newHandler(ChannelPromise handshakeCompletedPromise) { + return newHandler(new ChannelPipelineBuilderImpl(), handshakeCompletedPromise); } - private static HandshakeHandler newHandler( ChannelPipelineBuilder pipelineBuilder, ChannelPromise handshakeCompletedPromise ) - { - return new HandshakeHandler( pipelineBuilder, handshakeCompletedPromise, DEV_NULL_LOGGING ); + private static HandshakeHandler newHandler( + ChannelPipelineBuilder pipelineBuilder, ChannelPromise handshakeCompletedPromise) { + return new HandshakeHandler(pipelineBuilder, handshakeCompletedPromise, DEV_NULL_LOGGING); } - private static class MemorizingChannelPipelineBuilder extends ChannelPipelineBuilderImpl - { + private static class MemorizingChannelPipelineBuilder extends ChannelPipelineBuilderImpl { MessageFormat usedMessageFormat; @Override - public void build( MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging ) - { + public void build(MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging) { usedMessageFormat = messageFormat; - super.build( messageFormat, pipeline, logging ); + super.build(messageFormat, pipeline, logging); } } } 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 fbf15f712d..4ca4ee2ab7 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 @@ -18,25 +18,6 @@ */ package org.neo4j.driver.internal.async.connection; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.handler.ssl.SslHandler; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import java.security.GeneralSecurityException; -import java.util.List; -import javax.net.ssl.SNIHostName; -import javax.net.ssl.SNIServerName; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLParameters; - -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.RevocationStrategy; -import org.neo4j.driver.internal.security.SecurityPlanImpl; -import org.neo4j.driver.internal.security.SecurityPlan; -import org.neo4j.driver.internal.util.Clock; -import org.neo4j.driver.internal.util.FakeClock; - import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.instanceOf; @@ -52,127 +33,131 @@ import static org.neo4j.driver.internal.async.connection.ChannelAttributes.serverAddress; import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -class NettyChannelInitializerTest -{ +import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.handler.ssl.SslHandler; +import java.security.GeneralSecurityException; +import java.util.List; +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIServerName; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.RevocationStrategy; +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 { private final EmbeddedChannel channel = new EmbeddedChannel(); @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldAddSslHandlerWhenRequiresEncryption() throws Exception - { + void shouldAddSslHandlerWhenRequiresEncryption() throws Exception { SecurityPlan security = trustAllCertificates(); - NettyChannelInitializer initializer = newInitializer( security ); + NettyChannelInitializer initializer = newInitializer(security); - initializer.initChannel( channel ); + initializer.initChannel(channel); - assertNotNull( channel.pipeline().get( SslHandler.class ) ); + assertNotNull(channel.pipeline().get(SslHandler.class)); } @Test - void shouldNotAddSslHandlerWhenDoesNotRequireEncryption() - { + void shouldNotAddSslHandlerWhenDoesNotRequireEncryption() { SecurityPlan security = SecurityPlanImpl.insecure(); - NettyChannelInitializer initializer = newInitializer( security ); + NettyChannelInitializer initializer = newInitializer(security); - initializer.initChannel( channel ); + initializer.initChannel(channel); - assertNull( channel.pipeline().get( SslHandler.class ) ); + assertNull(channel.pipeline().get(SslHandler.class)); } @Test - void shouldAddSslHandlerWithHandshakeTimeout() throws Exception - { + void shouldAddSslHandlerWithHandshakeTimeout() throws Exception { int timeoutMillis = 424242; SecurityPlan security = trustAllCertificates(); - NettyChannelInitializer initializer = newInitializer( security, timeoutMillis ); + NettyChannelInitializer initializer = newInitializer(security, timeoutMillis); - initializer.initChannel( channel ); + initializer.initChannel(channel); - SslHandler sslHandler = channel.pipeline().get( SslHandler.class ); - assertNotNull( sslHandler ); - assertEquals( timeoutMillis, sslHandler.getHandshakeTimeoutMillis() ); + SslHandler sslHandler = channel.pipeline().get(SslHandler.class); + assertNotNull(sslHandler); + assertEquals(timeoutMillis, sslHandler.getHandshakeTimeoutMillis()); } @Test - void shouldUpdateChannelAttributes() - { - Clock clock = mock( Clock.class ); - when( clock.millis() ).thenReturn( 42L ); + void shouldUpdateChannelAttributes() { + Clock clock = mock(Clock.class); + when(clock.millis()).thenReturn(42L); SecurityPlan security = SecurityPlanImpl.insecure(); - NettyChannelInitializer initializer = newInitializer( security, Integer.MAX_VALUE, clock ); + NettyChannelInitializer initializer = newInitializer(security, Integer.MAX_VALUE, clock); - initializer.initChannel( channel ); + initializer.initChannel(channel); - assertEquals( LOCAL_DEFAULT, serverAddress( channel ) ); - assertEquals( 42L, creationTimestamp( channel ) ); - assertNotNull( messageDispatcher( channel ) ); + assertEquals(LOCAL_DEFAULT, serverAddress(channel)); + assertEquals(42L, creationTimestamp(channel)); + assertNotNull(messageDispatcher(channel)); } @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 ); + void shouldIncludeSniHostName() throws Exception { + BoltServerAddress address = new BoltServerAddress("database.neo4j.com", 8989); + NettyChannelInitializer initializer = + new NettyChannelInitializer(address, trustAllCertificates(), 10000, Clock.SYSTEM, DEV_NULL_LOGGING); - initializer.initChannel( channel ); + initializer.initChannel(channel); - SslHandler sslHandler = channel.pipeline().get( SslHandler.class ); + SslHandler sslHandler = channel.pipeline().get(SslHandler.class); SSLEngine sslEngine = sslHandler.engine(); SSLParameters sslParameters = sslEngine.getSSLParameters(); List sniServerNames = sslParameters.getServerNames(); - assertThat( sniServerNames, hasSize( 1 ) ); - assertThat( sniServerNames.get( 0 ), instanceOf( SNIHostName.class ) ); - assertThat( ((SNIHostName) sniServerNames.get( 0 )).getAsciiName(), equalTo( address.host() ) ); + assertThat(sniServerNames, hasSize(1)); + assertThat(sniServerNames.get(0), instanceOf(SNIHostName.class)); + assertThat(((SNIHostName) sniServerNames.get(0)).getAsciiName(), equalTo(address.host())); } @Test - void shouldEnableHostnameVerificationWhenConfigured() throws Exception - { - testHostnameVerificationSetting( true, "HTTPS" ); + void shouldEnableHostnameVerificationWhenConfigured() throws Exception { + testHostnameVerificationSetting(true, "HTTPS"); } @Test - void shouldNotEnableHostnameVerificationWhenNotConfigured() throws Exception - { - testHostnameVerificationSetting( false, null ); + void shouldNotEnableHostnameVerificationWhenNotConfigured() throws Exception { + testHostnameVerificationSetting(false, null); } - private void testHostnameVerificationSetting( boolean enabled, String expectedValue ) throws Exception - { - NettyChannelInitializer initializer = newInitializer( SecurityPlanImpl.forAllCertificates( enabled, RevocationStrategy.NO_CHECKS ) ); + private void testHostnameVerificationSetting(boolean enabled, String expectedValue) throws Exception { + NettyChannelInitializer initializer = + newInitializer(SecurityPlanImpl.forAllCertificates(enabled, RevocationStrategy.NO_CHECKS)); - initializer.initChannel( channel ); + initializer.initChannel(channel); - SslHandler sslHandler = channel.pipeline().get( SslHandler.class ); + SslHandler sslHandler = channel.pipeline().get(SslHandler.class); SSLEngine sslEngine = sslHandler.engine(); SSLParameters sslParameters = sslEngine.getSSLParameters(); - assertEquals( expectedValue, sslParameters.getEndpointIdentificationAlgorithm() ); + assertEquals(expectedValue, sslParameters.getEndpointIdentificationAlgorithm()); } - private static NettyChannelInitializer newInitializer( SecurityPlan securityPlan ) - { - return newInitializer( securityPlan, Integer.MAX_VALUE ); + private static NettyChannelInitializer newInitializer(SecurityPlan securityPlan) { + return newInitializer(securityPlan, Integer.MAX_VALUE); } - private static NettyChannelInitializer newInitializer( SecurityPlan securityPlan, int connectTimeoutMillis ) - { - return newInitializer( securityPlan, connectTimeoutMillis, new FakeClock() ); + private static NettyChannelInitializer newInitializer(SecurityPlan securityPlan, int connectTimeoutMillis) { + return newInitializer(securityPlan, connectTimeoutMillis, new FakeClock()); } - private static NettyChannelInitializer newInitializer( SecurityPlan securityPlan, int connectTimeoutMillis, - Clock clock ) - { - return new NettyChannelInitializer( LOCAL_DEFAULT, securityPlan, connectTimeoutMillis, clock, - DEV_NULL_LOGGING ); + private static NettyChannelInitializer newInitializer( + SecurityPlan securityPlan, int connectTimeoutMillis, Clock clock) { + return new NettyChannelInitializer(LOCAL_DEFAULT, securityPlan, connectTimeoutMillis, clock, DEV_NULL_LOGGING); } - private static SecurityPlan trustAllCertificates() throws GeneralSecurityException - { - return SecurityPlanImpl.forAllCertificates( false, RevocationStrategy.NO_CHECKS ); + private static SecurityPlan trustAllCertificates() throws GeneralSecurityException { + return SecurityPlanImpl.forAllCertificates(false, RevocationStrategy.NO_CHECKS); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/connection/RoutingConnectionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/connection/RoutingConnectionTest.java index 2aa59c69c0..f8a3bd4341 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/connection/RoutingConnectionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/connection/RoutingConnectionTest.java @@ -18,14 +18,6 @@ */ package org.neo4j.driver.internal.async.connection; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import org.neo4j.driver.internal.RoutingErrorHandler; -import org.neo4j.driver.internal.handlers.RoutingResponseHandler; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ResponseHandler; - import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -39,107 +31,99 @@ import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; -class RoutingConnectionTest -{ +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.neo4j.driver.internal.RoutingErrorHandler; +import org.neo4j.driver.internal.handlers.RoutingResponseHandler; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ResponseHandler; + +class RoutingConnectionTest { @Test - void shouldWrapHandlersWhenWritingSingleMessage() - { - testHandlersWrappingWithSingleMessage( false ); + void shouldWrapHandlersWhenWritingSingleMessage() { + testHandlersWrappingWithSingleMessage(false); } @Test - void shouldWrapHandlersWhenWritingAndFlushingSingleMessage() - { - testHandlersWrappingWithSingleMessage( true ); + void shouldWrapHandlersWhenWritingAndFlushingSingleMessage() { + testHandlersWrappingWithSingleMessage(true); } @Test - void shouldWrapHandlersWhenWritingMultipleMessages() - { - testHandlersWrappingWithMultipleMessages( false ); + void shouldWrapHandlersWhenWritingMultipleMessages() { + testHandlersWrappingWithMultipleMessages(false); } @Test - void shouldWrapHandlersWhenWritingAndFlushingMultipleMessages() - { - testHandlersWrappingWithMultipleMessages( true ); + void shouldWrapHandlersWhenWritingAndFlushingMultipleMessages() { + testHandlersWrappingWithMultipleMessages(true); } @Test - void shouldReturnServerAgent() - { + void shouldReturnServerAgent() { // given - Connection connection = mock( Connection.class ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); - RoutingConnection routingConnection = new RoutingConnection( connection, defaultDatabase(), READ, null, errorHandler ); + Connection connection = mock(Connection.class); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); + RoutingConnection routingConnection = + new RoutingConnection(connection, defaultDatabase(), READ, null, errorHandler); String agent = "Neo4j/4.2.5"; - given( connection.serverAgent() ).willReturn( agent ); + given(connection.serverAgent()).willReturn(agent); // when String actualAgent = routingConnection.serverAgent(); // then - assertEquals( agent, actualAgent ); - then( connection ).should().serverAgent(); + assertEquals(agent, actualAgent); + then(connection).should().serverAgent(); } - private static void testHandlersWrappingWithSingleMessage( boolean flush ) - { - Connection connection = mock( Connection.class ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); - RoutingConnection routingConnection = new RoutingConnection( connection, defaultDatabase(), READ, null, errorHandler ); + private static void testHandlersWrappingWithSingleMessage(boolean flush) { + Connection connection = mock(Connection.class); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); + RoutingConnection routingConnection = + new RoutingConnection(connection, defaultDatabase(), READ, null, errorHandler); - if ( flush ) - { - routingConnection.writeAndFlush( PULL_ALL, mock( ResponseHandler.class ) ); - } - else - { - routingConnection.write( PULL_ALL, mock( ResponseHandler.class ) ); + if (flush) { + routingConnection.writeAndFlush(PULL_ALL, mock(ResponseHandler.class)); + } else { + routingConnection.write(PULL_ALL, mock(ResponseHandler.class)); } - ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); + ArgumentCaptor handlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); - if ( flush ) - { - verify( connection ).writeAndFlush( eq( PULL_ALL ), handlerCaptor.capture() ); - } - else - { - verify( connection ).write( eq( PULL_ALL ), handlerCaptor.capture() ); + if (flush) { + verify(connection).writeAndFlush(eq(PULL_ALL), handlerCaptor.capture()); + } else { + verify(connection).write(eq(PULL_ALL), handlerCaptor.capture()); } - assertThat( handlerCaptor.getValue(), instanceOf( RoutingResponseHandler.class ) ); + assertThat(handlerCaptor.getValue(), instanceOf(RoutingResponseHandler.class)); } - private static void testHandlersWrappingWithMultipleMessages( boolean flush ) - { - Connection connection = mock( Connection.class ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); - RoutingConnection routingConnection = new RoutingConnection( connection, defaultDatabase(), READ, null, errorHandler ); - - if ( flush ) - { - routingConnection.writeAndFlush( PULL_ALL, mock( ResponseHandler.class ), DISCARD_ALL, mock( ResponseHandler.class ) ); - } - else - { - routingConnection.write( PULL_ALL, mock( ResponseHandler.class ), DISCARD_ALL, mock( ResponseHandler.class ) ); + private static void testHandlersWrappingWithMultipleMessages(boolean flush) { + Connection connection = mock(Connection.class); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); + RoutingConnection routingConnection = + new RoutingConnection(connection, defaultDatabase(), READ, null, errorHandler); + + if (flush) { + routingConnection.writeAndFlush( + PULL_ALL, mock(ResponseHandler.class), DISCARD_ALL, mock(ResponseHandler.class)); + } else { + routingConnection.write(PULL_ALL, mock(ResponseHandler.class), DISCARD_ALL, mock(ResponseHandler.class)); } - ArgumentCaptor handlerCaptor1 = ArgumentCaptor.forClass( ResponseHandler.class ); - ArgumentCaptor handlerCaptor2 = ArgumentCaptor.forClass( ResponseHandler.class ); + ArgumentCaptor handlerCaptor1 = ArgumentCaptor.forClass(ResponseHandler.class); + ArgumentCaptor handlerCaptor2 = ArgumentCaptor.forClass(ResponseHandler.class); - if ( flush ) - { - verify( connection ).writeAndFlush( eq( PULL_ALL ), handlerCaptor1.capture(), eq( DISCARD_ALL ), handlerCaptor2.capture() ); - } - else - { - verify( connection ).write( eq( PULL_ALL ), handlerCaptor1.capture(), eq( DISCARD_ALL ), handlerCaptor2.capture() ); + if (flush) { + verify(connection) + .writeAndFlush(eq(PULL_ALL), handlerCaptor1.capture(), eq(DISCARD_ALL), handlerCaptor2.capture()); + } else { + verify(connection).write(eq(PULL_ALL), handlerCaptor1.capture(), eq(DISCARD_ALL), handlerCaptor2.capture()); } - assertThat( handlerCaptor1.getValue(), instanceOf( RoutingResponseHandler.class ) ); - assertThat( handlerCaptor2.getValue(), instanceOf( RoutingResponseHandler.class ) ); + assertThat(handlerCaptor1.getValue(), instanceOf(RoutingResponseHandler.class)); + assertThat(handlerCaptor2.getValue(), instanceOf(RoutingResponseHandler.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ByteBufInputTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ByteBufInputTest.java index a236fd85f3..abc55cae9c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ByteBufInputTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ByteBufInputTest.java @@ -18,9 +18,6 @@ */ package org.neo4j.driver.internal.async.inbound; -import io.netty.buffer.ByteBuf; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyInt; @@ -28,100 +25,93 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -class ByteBufInputTest -{ +import io.netty.buffer.ByteBuf; +import org.junit.jupiter.api.Test; + +class ByteBufInputTest { @Test - void shouldThrowWhenStartedWithNullBuf() - { + void shouldThrowWhenStartedWithNullBuf() { ByteBufInput input = new ByteBufInput(); - assertThrows( NullPointerException.class, () -> input.start( null ) ); + assertThrows(NullPointerException.class, () -> input.start(null)); } @Test - void shouldThrowWhenStartedTwice() - { + void shouldThrowWhenStartedTwice() { ByteBufInput input = new ByteBufInput(); - input.start( mock( ByteBuf.class ) ); + input.start(mock(ByteBuf.class)); - assertThrows( IllegalStateException.class, () -> input.start( mock( ByteBuf.class ) ) ); + assertThrows(IllegalStateException.class, () -> input.start(mock(ByteBuf.class))); } @Test - void shouldDelegateReadByte() - { + void shouldDelegateReadByte() { ByteBufInput input = new ByteBufInput(); - ByteBuf buf = mock( ByteBuf.class ); - when( buf.readByte() ).thenReturn( (byte) 42 ); - input.start( buf ); + ByteBuf buf = mock(ByteBuf.class); + when(buf.readByte()).thenReturn((byte) 42); + input.start(buf); - assertEquals( (byte) 42, input.readByte() ); + assertEquals((byte) 42, input.readByte()); } @Test - void shouldDelegateReadShort() - { + void shouldDelegateReadShort() { ByteBufInput input = new ByteBufInput(); - ByteBuf buf = mock( ByteBuf.class ); - when( buf.readShort() ).thenReturn( (short) -42 ); - input.start( buf ); + ByteBuf buf = mock(ByteBuf.class); + when(buf.readShort()).thenReturn((short) -42); + input.start(buf); - assertEquals( (short) -42, input.readShort() ); + assertEquals((short) -42, input.readShort()); } @Test - void shouldDelegateReadInt() - { + void shouldDelegateReadInt() { ByteBufInput input = new ByteBufInput(); - ByteBuf buf = mock( ByteBuf.class ); - when( buf.readInt() ).thenReturn( 15 ); - input.start( buf ); + ByteBuf buf = mock(ByteBuf.class); + when(buf.readInt()).thenReturn(15); + input.start(buf); - assertEquals( 15, input.readInt() ); + assertEquals(15, input.readInt()); } @Test - void shouldDelegateReadLong() - { + void shouldDelegateReadLong() { ByteBufInput input = new ByteBufInput(); - ByteBuf buf = mock( ByteBuf.class ); - when( buf.readLong() ).thenReturn( 4242L ); - input.start( buf ); + ByteBuf buf = mock(ByteBuf.class); + when(buf.readLong()).thenReturn(4242L); + input.start(buf); - assertEquals( 4242L, input.readLong() ); + assertEquals(4242L, input.readLong()); } @Test - void shouldDelegateReadDouble() - { + void shouldDelegateReadDouble() { ByteBufInput input = new ByteBufInput(); - ByteBuf buf = mock( ByteBuf.class ); - when( buf.readDouble() ).thenReturn( 42.42D ); - input.start( buf ); + ByteBuf buf = mock(ByteBuf.class); + when(buf.readDouble()).thenReturn(42.42D); + input.start(buf); - assertEquals( 42.42D, input.readDouble(), 0.00001 ); + assertEquals(42.42D, input.readDouble(), 0.00001); } @Test - void shouldDelegateReadBytes() - { + void shouldDelegateReadBytes() { ByteBufInput input = new ByteBufInput(); - ByteBuf buf = mock( ByteBuf.class ); - input.start( buf ); + ByteBuf buf = mock(ByteBuf.class); + input.start(buf); - input.readBytes( new byte[10], 3, 5 ); + input.readBytes(new byte[10], 3, 5); - verify( buf ).readBytes( new byte[10], 3, 5 ); + verify(buf).readBytes(new byte[10], 3, 5); } @Test - void shouldDelegatePeekByte() - { + void shouldDelegatePeekByte() { ByteBufInput input = new ByteBufInput(); - ByteBuf buf = mock( ByteBuf.class ); - when( buf.getByte( anyInt() ) ).thenReturn( (byte) 42 ); - input.start( buf ); + ByteBuf buf = mock(ByteBuf.class); + when(buf.getByte(anyInt())).thenReturn((byte) 42); + input.start(buf); - assertEquals( (byte) 42, input.peekByte() ); + assertEquals((byte) 42, input.peekByte()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ChunkDecoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ChunkDecoderTest.java index 0ee94b7c06..5d3a3c6a32 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ChunkDecoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ChunkDecoderTest.java @@ -18,15 +18,6 @@ */ package org.neo4j.driver.internal.async.inbound; -import io.netty.buffer.ByteBuf; -import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import org.neo4j.driver.Logger; -import org.neo4j.driver.Logging; - import static io.netty.buffer.ByteBufUtil.hexDump; import static io.netty.buffer.Unpooled.buffer; import static io.netty.buffer.Unpooled.copyShort; @@ -42,179 +33,174 @@ import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.util.TestUtil.assertByteBufEquals; -class ChunkDecoderTest -{ +import io.netty.buffer.ByteBuf; +import io.netty.channel.embedded.EmbeddedChannel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.neo4j.driver.Logger; +import org.neo4j.driver.Logging; + +class ChunkDecoderTest { private ByteBuf buffer; - private EmbeddedChannel channel = new EmbeddedChannel( newChunkDecoder() ); + private EmbeddedChannel channel = new EmbeddedChannel(newChunkDecoder()); @AfterEach - void tearDown() - { - if ( buffer != null ) - { - buffer.release( buffer.refCnt() ); + void tearDown() { + if (buffer != null) { + buffer.release(buffer.refCnt()); } - if ( channel != null ) - { + if (channel != null) { channel.finishAndReleaseAll(); } } @Test - void shouldDecodeFullChunk() - { + void shouldDecodeFullChunk() { // whole chunk with header and body arrives at once ByteBuf input = buffer(); - input.writeShort( 7 ); - input.writeByte( 1 ); - input.writeByte( 11 ); - input.writeByte( 2 ); - input.writeByte( 22 ); - input.writeByte( 3 ); - input.writeByte( 33 ); - input.writeByte( 4 ); + input.writeShort(7); + input.writeByte(1); + input.writeByte(11); + input.writeByte(2); + input.writeByte(22); + input.writeByte(3); + input.writeByte(33); + input.writeByte(4); // after buffer is written there should be something to read on the other side - assertTrue( channel.writeInbound( input ) ); - assertTrue( channel.finish() ); + assertTrue(channel.writeInbound(input)); + assertTrue(channel.finish()); // there should only be a single chunk available for reading - assertEquals( 1, channel.inboundMessages().size() ); + assertEquals(1, channel.inboundMessages().size()); // it should have no size header and expected body - assertByteBufEquals( input.slice( 2, 7 ), channel.readInbound() ); + assertByteBufEquals(input.slice(2, 7), channel.readInbound()); } @Test - void shouldDecodeSplitChunk() - { + void shouldDecodeSplitChunk() { // first part of the chunk contains size header and some bytes ByteBuf input1 = buffer(); - input1.writeShort( 9 ); - input1.writeByte( 1 ); - input1.writeByte( 11 ); - input1.writeByte( 2 ); + input1.writeShort(9); + input1.writeByte(1); + input1.writeByte(11); + input1.writeByte(2); // nothing should be available for reading - assertFalse( channel.writeInbound( input1 ) ); + assertFalse(channel.writeInbound(input1)); // second part contains just a single byte ByteBuf input2 = buffer(); - input2.writeByte( 22 ); + input2.writeByte(22); // nothing should be available for reading - assertFalse( channel.writeInbound( input2 ) ); + assertFalse(channel.writeInbound(input2)); // third part contains couple more bytes ByteBuf input3 = buffer(); - input3.writeByte( 3 ); - input3.writeByte( 33 ); - input3.writeByte( 4 ); + input3.writeByte(3); + input3.writeByte(33); + input3.writeByte(4); // nothing should be available for reading - assertFalse( channel.writeInbound( input3 ) ); + assertFalse(channel.writeInbound(input3)); // fourth part contains couple more bytes, and the chunk is now complete ByteBuf input4 = buffer(); - input4.writeByte( 44 ); - input4.writeByte( 5 ); + input4.writeByte(44); + input4.writeByte(5); // there should be something to read now - assertTrue( channel.writeInbound( input4 ) ); + assertTrue(channel.writeInbound(input4)); - assertTrue( channel.finish() ); + assertTrue(channel.finish()); // there should only be a single chunk available for reading - assertEquals( 1, channel.inboundMessages().size() ); + assertEquals(1, channel.inboundMessages().size()); // it should have no size header and expected body - assertByteBufEquals( wrappedBuffer( new byte[]{1, 11, 2, 22, 3, 33, 4, 44, 5} ), channel.readInbound() ); + assertByteBufEquals(wrappedBuffer(new byte[] {1, 11, 2, 22, 3, 33, 4, 44, 5}), channel.readInbound()); } @Test - void shouldDecodeEmptyChunk() - { + void shouldDecodeEmptyChunk() { // chunk contains just the size header which is zero - ByteBuf input = copyShort( 0 ); - assertTrue( channel.writeInbound( input ) ); - assertTrue( channel.finish() ); + ByteBuf input = copyShort(0); + assertTrue(channel.writeInbound(input)); + assertTrue(channel.finish()); // there should only be a single chunk available for reading - assertEquals( 1, channel.inboundMessages().size() ); + assertEquals(1, channel.inboundMessages().size()); // it should have no size header and empty body - assertByteBufEquals( wrappedBuffer( new byte[0] ), channel.readInbound() ); + assertByteBufEquals(wrappedBuffer(new byte[0]), channel.readInbound()); } @Test - void shouldLogEmptyChunkOnTraceLevel() - { + void shouldLogEmptyChunkOnTraceLevel() { Logger logger = newTraceLogger(); - channel = new EmbeddedChannel( new ChunkDecoder( newLogging( logger ) ) ); + channel = new EmbeddedChannel(new ChunkDecoder(newLogging(logger))); - buffer = copyShort( 0 ); - assertTrue( channel.writeInbound( buffer.copy() ) ); // copy buffer so we can verify against it later - assertTrue( channel.finish() ); + buffer = copyShort(0); + assertTrue(channel.writeInbound(buffer.copy())); // copy buffer so we can verify against it later + assertTrue(channel.finish()); - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass( String.class ); - verify( logger ).trace( anyString(), messageCaptor.capture() ); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(logger).trace(anyString(), messageCaptor.capture()); // pretty hex dump should be logged - assertEquals( hexDump( buffer ), messageCaptor.getValue() ); + assertEquals(hexDump(buffer), messageCaptor.getValue()); // single empty chunk should be available for reading - assertEquals( 1, channel.inboundMessages().size() ); - assertByteBufEquals( wrappedBuffer( new byte[0] ), channel.readInbound() ); + assertEquals(1, channel.inboundMessages().size()); + assertByteBufEquals(wrappedBuffer(new byte[0]), channel.readInbound()); } @Test - void shouldLogNonEmptyChunkOnTraceLevel() - { + void shouldLogNonEmptyChunkOnTraceLevel() { Logger logger = newTraceLogger(); - channel = new EmbeddedChannel( new ChunkDecoder( newLogging( logger ) ) ); + channel = new EmbeddedChannel(new ChunkDecoder(newLogging(logger))); byte[] bytes = "Hello".getBytes(); buffer = buffer(); - buffer.writeShort( bytes.length ); - buffer.writeBytes( bytes ); + buffer.writeShort(bytes.length); + buffer.writeBytes(bytes); - assertTrue( channel.writeInbound( buffer.copy() ) ); // copy buffer so we can verify against it later - assertTrue( channel.finish() ); + assertTrue(channel.writeInbound(buffer.copy())); // copy buffer so we can verify against it later + assertTrue(channel.finish()); - ArgumentCaptor messageCaptor = ArgumentCaptor.forClass( String.class ); - verify( logger ).trace( anyString(), messageCaptor.capture() ); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(logger).trace(anyString(), messageCaptor.capture()); // pretty hex dump should be logged - assertEquals( hexDump( buffer ), messageCaptor.getValue() ); + assertEquals(hexDump(buffer), messageCaptor.getValue()); // single chunk should be available for reading - assertEquals( 1, channel.inboundMessages().size() ); - assertByteBufEquals( wrappedBuffer( bytes ), channel.readInbound() ); + assertEquals(1, channel.inboundMessages().size()); + assertByteBufEquals(wrappedBuffer(bytes), channel.readInbound()); } @Test - public void shouldDecodeMaxSizeChunk() - { + public void shouldDecodeMaxSizeChunk() { byte[] message = new byte[0xFFFF]; ByteBuf input = buffer(); - input.writeShort( message.length ); // chunk header - input.writeBytes( message ); // chunk body + input.writeShort(message.length); // chunk header + input.writeBytes(message); // chunk body - assertTrue( channel.writeInbound( input ) ); - assertTrue( channel.finish() ); + assertTrue(channel.writeInbound(input)); + assertTrue(channel.finish()); - assertEquals( 1, channel.inboundMessages().size() ); - assertByteBufEquals( wrappedBuffer( message ), channel.readInbound() ); + assertEquals(1, channel.inboundMessages().size()); + assertByteBufEquals(wrappedBuffer(message), channel.readInbound()); } - private static ChunkDecoder newChunkDecoder() - { - return new ChunkDecoder( DEV_NULL_LOGGING ); + private static ChunkDecoder newChunkDecoder() { + return new ChunkDecoder(DEV_NULL_LOGGING); } - private static Logger newTraceLogger() - { - Logger logger = mock( Logger.class ); - when( logger.isTraceEnabled() ).thenReturn( true ); + private static Logger newTraceLogger() { + Logger logger = mock(Logger.class); + when(logger.isTraceEnabled()).thenReturn(true); return logger; } - private static Logging newLogging( Logger logger ) - { - Logging logging = mock( Logging.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + private static Logging newLogging(Logger logger) { + Logging logging = mock(Logging.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); return logging; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ConnectTimeoutHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ConnectTimeoutHandlerTest.java index b812f2e1a3..cacdb48d6b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ConnectTimeoutHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ConnectTimeoutHandlerTest.java @@ -18,54 +18,49 @@ */ package org.neo4j.driver.internal.async.inbound; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import io.netty.channel.embedded.EmbeddedChannel; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; - import org.neo4j.driver.exceptions.ServiceUnavailableException; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class ConnectTimeoutHandlerTest -{ +class ConnectTimeoutHandlerTest { private final EmbeddedChannel channel = new EmbeddedChannel(); @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldFireExceptionOnTimeout() throws Exception - { + void shouldFireExceptionOnTimeout() throws Exception { int timeoutMillis = 100; - channel.pipeline().addLast( new ConnectTimeoutHandler( timeoutMillis ) ); + channel.pipeline().addLast(new ConnectTimeoutHandler(timeoutMillis)); // sleep for more than the timeout value - Thread.sleep( timeoutMillis * 4 ); + Thread.sleep(timeoutMillis * 4); channel.runPendingTasks(); - ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, channel::checkException ); - assertEquals( error.getMessage(), "Unable to establish connection in " + timeoutMillis + "ms" ); + ServiceUnavailableException error = assertThrows(ServiceUnavailableException.class, channel::checkException); + assertEquals(error.getMessage(), "Unable to establish connection in " + timeoutMillis + "ms"); } @Test - void shouldNotFireExceptionMultipleTimes() throws Exception - { + void shouldNotFireExceptionMultipleTimes() throws Exception { int timeoutMillis = 70; - channel.pipeline().addLast( new ConnectTimeoutHandler( timeoutMillis ) ); + channel.pipeline().addLast(new ConnectTimeoutHandler(timeoutMillis)); // sleep for more than the timeout value - Thread.sleep( timeoutMillis * 4 ); + Thread.sleep(timeoutMillis * 4); channel.runPendingTasks(); - ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, channel::checkException ); - assertEquals( error.getMessage(), "Unable to establish connection in " + timeoutMillis + "ms" ); + ServiceUnavailableException error = assertThrows(ServiceUnavailableException.class, channel::checkException); + assertEquals(error.getMessage(), "Unable to establish connection in " + timeoutMillis + "ms"); // sleep even more - Thread.sleep( timeoutMillis * 4 ); + Thread.sleep(timeoutMillis * 4); channel.runPendingTasks(); // no more exceptions should occur diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ConnectionReadTimeoutHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ConnectionReadTimeoutHandlerTest.java index e0aaec2488..12d966613a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ConnectionReadTimeoutHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/ConnectionReadTimeoutHandlerTest.java @@ -18,32 +18,28 @@ */ package org.neo4j.driver.internal.async.inbound; -import io.netty.channel.ChannelHandlerContext; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.TimeUnit; -import java.util.stream.IntStream; - -import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; - import static org.mockito.BDDMockito.any; import static org.mockito.BDDMockito.then; import static org.mockito.BDDMockito.times; import static org.mockito.Mockito.mock; -public class ConnectionReadTimeoutHandlerTest -{ - ConnectionReadTimeoutHandler handler = new ConnectionReadTimeoutHandler( 15L, TimeUnit.SECONDS ); - ChannelHandlerContext context = mock( ChannelHandlerContext.class ); +import io.netty.channel.ChannelHandlerContext; +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; + +public class ConnectionReadTimeoutHandlerTest { + ConnectionReadTimeoutHandler handler = new ConnectionReadTimeoutHandler(15L, TimeUnit.SECONDS); + ChannelHandlerContext context = mock(ChannelHandlerContext.class); @Test - void shouldFireConnectionReadTimeoutExceptionAndCloseChannelOnReadTimeOutOnce() - { + void shouldFireConnectionReadTimeoutExceptionAndCloseChannelOnReadTimeOutOnce() { // WHEN - IntStream.range( 0, 10 ).forEach( i -> handler.readTimedOut( context ) ); + IntStream.range(0, 10).forEach(i -> handler.readTimedOut(context)); // THEN - then( context ).should( times( 1 ) ).fireExceptionCaught( any( ConnectionReadTimeoutException.class ) ); - then( context ).should( times( 1 ) ).close(); + then(context).should(times(1)).fireExceptionCaught(any(ConnectionReadTimeoutException.class)); + then(context).should(times(1)).close(); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcherTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcherTest.java index da209b48d9..2b9abfbf59 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcherTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageDispatcherTest.java @@ -18,19 +18,39 @@ */ package org.neo4j.driver.internal.async.inbound; +import static java.util.Collections.emptyMap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.contains; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.only; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; + import io.netty.channel.Channel; import io.netty.channel.ChannelConfig; import io.netty.channel.DefaultChannelId; import io.netty.util.Attribute; +import java.util.HashMap; +import java.util.Map; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; - -import java.util.HashMap; -import java.util.Map; - import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.Value; @@ -47,433 +67,378 @@ import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.internal.value.IntegerValue; -import static java.util.Collections.emptyMap; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.contains; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.only; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; - -class InboundMessageDispatcherTest -{ +class InboundMessageDispatcherTest { private static final String FAILURE_CODE = "Neo.ClientError.Security.Unauthorized"; private static final String FAILURE_MESSAGE = "Error Message"; @Test - void shouldFailWhenCreatedWithNullChannel() - { - assertThrows( NullPointerException.class, () -> new InboundMessageDispatcher( null, DEV_NULL_LOGGING ) ); + void shouldFailWhenCreatedWithNullChannel() { + assertThrows(NullPointerException.class, () -> new InboundMessageDispatcher(null, DEV_NULL_LOGGING)); } @Test - void shouldFailWhenCreatedWithNullLogging() - { - assertThrows( NullPointerException.class, () -> new InboundMessageDispatcher( newChannelMock(), null ) ); + void shouldFailWhenCreatedWithNullLogging() { + assertThrows(NullPointerException.class, () -> new InboundMessageDispatcher(newChannelMock(), null)); } @Test - void shouldDequeHandlerOnSuccess() - { + void shouldDequeHandlerOnSuccess() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler = mock( ResponseHandler.class ); - dispatcher.enqueue( handler ); - assertEquals( 1, dispatcher.queuedHandlersCount() ); + ResponseHandler handler = mock(ResponseHandler.class); + dispatcher.enqueue(handler); + assertEquals(1, dispatcher.queuedHandlersCount()); - Map metadata = new HashMap<>(); - metadata.put( "key1", value( 1 ) ); - metadata.put( "key2", value( "2" ) ); - dispatcher.handleSuccessMessage( metadata ); + Map metadata = new HashMap<>(); + metadata.put("key1", value(1)); + metadata.put("key2", value("2")); + dispatcher.handleSuccessMessage(metadata); - assertEquals( 0, dispatcher.queuedHandlersCount() ); - verify( handler ).onSuccess( metadata ); + assertEquals(0, dispatcher.queuedHandlersCount()); + verify(handler).onSuccess(metadata); } @Test - void shouldDequeHandlerOnFailure() - { + void shouldDequeHandlerOnFailure() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler = mock( ResponseHandler.class ); - dispatcher.enqueue( handler ); - assertEquals( 1, dispatcher.queuedHandlersCount() ); + ResponseHandler handler = mock(ResponseHandler.class); + dispatcher.enqueue(handler); + assertEquals(1, dispatcher.queuedHandlersCount()); - dispatcher.handleFailureMessage( FAILURE_CODE, FAILURE_MESSAGE ); + dispatcher.handleFailureMessage(FAILURE_CODE, FAILURE_MESSAGE); // "RESET after failure" handler should remain queued - assertEquals( 1, dispatcher.queuedHandlersCount() ); - verifyFailure( handler ); - assertEquals( FAILURE_CODE, ((Neo4jException) dispatcher.currentError()).code() ); - assertEquals( FAILURE_MESSAGE, dispatcher.currentError().getMessage() ); + assertEquals(1, dispatcher.queuedHandlersCount()); + verifyFailure(handler); + assertEquals(FAILURE_CODE, ((Neo4jException) dispatcher.currentError()).code()); + assertEquals(FAILURE_MESSAGE, dispatcher.currentError().getMessage()); } @Test - void shouldSendResetOnFailure() - { + void shouldSendResetOnFailure() { Channel channel = newChannelMock(); - InboundMessageDispatcher dispatcher = newDispatcher( channel ); + InboundMessageDispatcher dispatcher = newDispatcher(channel); - dispatcher.enqueue( mock( ResponseHandler.class ) ); - assertEquals( 1, dispatcher.queuedHandlersCount() ); + dispatcher.enqueue(mock(ResponseHandler.class)); + assertEquals(1, dispatcher.queuedHandlersCount()); - dispatcher.handleFailureMessage( FAILURE_CODE, FAILURE_MESSAGE ); + dispatcher.handleFailureMessage(FAILURE_CODE, FAILURE_MESSAGE); - verify( channel ).writeAndFlush( eq( RESET ), any() ); + verify(channel).writeAndFlush(eq(RESET), any()); } @Test - void shouldClearFailureOnSuccessOfResetAfterFailure() - { + void shouldClearFailureOnSuccessOfResetAfterFailure() { InboundMessageDispatcher dispatcher = newDispatcher(); - dispatcher.enqueue( mock( ResponseHandler.class ) ); - assertEquals( 1, dispatcher.queuedHandlersCount() ); + dispatcher.enqueue(mock(ResponseHandler.class)); + assertEquals(1, dispatcher.queuedHandlersCount()); - dispatcher.handleFailureMessage( FAILURE_CODE, FAILURE_MESSAGE ); - dispatcher.handleSuccessMessage( emptyMap() ); + dispatcher.handleFailureMessage(FAILURE_CODE, FAILURE_MESSAGE); + dispatcher.handleSuccessMessage(emptyMap()); - assertNull( dispatcher.currentError() ); + assertNull(dispatcher.currentError()); } @Test - void shouldPeekHandlerOnRecord() - { + void shouldPeekHandlerOnRecord() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler = mock( ResponseHandler.class ); - dispatcher.enqueue( handler ); - assertEquals( 1, dispatcher.queuedHandlersCount() ); + ResponseHandler handler = mock(ResponseHandler.class); + dispatcher.enqueue(handler); + assertEquals(1, dispatcher.queuedHandlersCount()); - Value[] fields1 = {new IntegerValue( 1 )}; - Value[] fields2 = {new IntegerValue( 2 )}; - Value[] fields3 = {new IntegerValue( 3 )}; + Value[] fields1 = {new IntegerValue(1)}; + Value[] fields2 = {new IntegerValue(2)}; + Value[] fields3 = {new IntegerValue(3)}; - dispatcher.handleRecordMessage( fields1 ); - dispatcher.handleRecordMessage( fields2 ); - dispatcher.handleRecordMessage( fields3 ); + dispatcher.handleRecordMessage(fields1); + dispatcher.handleRecordMessage(fields2); + dispatcher.handleRecordMessage(fields3); - verify( handler ).onRecord( fields1 ); - verify( handler ).onRecord( fields2 ); - verify( handler ).onRecord( fields3 ); - assertEquals( 1, dispatcher.queuedHandlersCount() ); + verify(handler).onRecord(fields1); + verify(handler).onRecord(fields2); + verify(handler).onRecord(fields3); + assertEquals(1, dispatcher.queuedHandlersCount()); } @Test - void shouldFailAllHandlersOnChannelError() - { + void shouldFailAllHandlersOnChannelError() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler1 = mock( ResponseHandler.class ); - ResponseHandler handler2 = mock( ResponseHandler.class ); - ResponseHandler handler3 = mock( ResponseHandler.class ); + ResponseHandler handler1 = mock(ResponseHandler.class); + ResponseHandler handler2 = mock(ResponseHandler.class); + ResponseHandler handler3 = mock(ResponseHandler.class); - dispatcher.enqueue( handler1 ); - dispatcher.enqueue( handler2 ); - dispatcher.enqueue( handler3 ); + dispatcher.enqueue(handler1); + dispatcher.enqueue(handler2); + dispatcher.enqueue(handler3); - RuntimeException fatalError = new RuntimeException( "Fatal!" ); - dispatcher.handleChannelError( fatalError ); + RuntimeException fatalError = new RuntimeException("Fatal!"); + dispatcher.handleChannelError(fatalError); - InOrder inOrder = inOrder( handler1, handler2, handler3 ); - inOrder.verify( handler1 ).onFailure( fatalError ); - inOrder.verify( handler2 ).onFailure( fatalError ); - inOrder.verify( handler3 ).onFailure( fatalError ); + InOrder inOrder = inOrder(handler1, handler2, handler3); + inOrder.verify(handler1).onFailure(fatalError); + inOrder.verify(handler2).onFailure(fatalError); + inOrder.verify(handler3).onFailure(fatalError); } @Test - void shouldFailNewHandlerAfterChannelError() - { + void shouldFailNewHandlerAfterChannelError() { InboundMessageDispatcher dispatcher = newDispatcher(); - RuntimeException fatalError = new RuntimeException( "Fatal!" ); - dispatcher.handleChannelError( fatalError ); + RuntimeException fatalError = new RuntimeException("Fatal!"); + dispatcher.handleChannelError(fatalError); - ResponseHandler handler = mock( ResponseHandler.class ); - dispatcher.enqueue( handler ); + ResponseHandler handler = mock(ResponseHandler.class); + dispatcher.enqueue(handler); - verify( handler ).onFailure( fatalError ); + verify(handler).onFailure(fatalError); } @Test - void shouldAttachChannelErrorOnExistingError() - { + void shouldAttachChannelErrorOnExistingError() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler = mock( ResponseHandler.class ); - dispatcher.enqueue( handler ); + ResponseHandler handler = mock(ResponseHandler.class); + dispatcher.enqueue(handler); - dispatcher.handleFailureMessage( "Neo.ClientError", "First error!" ); - RuntimeException fatalError = new RuntimeException( "Second Error!" ); - dispatcher.handleChannelError( fatalError ); + dispatcher.handleFailureMessage("Neo.ClientError", "First error!"); + RuntimeException fatalError = new RuntimeException("Second Error!"); + dispatcher.handleChannelError(fatalError); - verify( handler ).onFailure( argThat( - error -> error instanceof ClientException && error.getMessage().equals( "First error!" ) && - error.getSuppressed().length == 1 && error.getSuppressed()[0].getMessage().equals( "Second Error!" ) ) ); + verify(handler) + .onFailure(argThat(error -> error instanceof ClientException + && error.getMessage().equals("First error!") + && error.getSuppressed().length == 1 + && error.getSuppressed()[0].getMessage().equals("Second Error!"))); } @Test - void shouldDequeHandlerOnIgnored() - { + void shouldDequeHandlerOnIgnored() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler = mock( ResponseHandler.class ); + ResponseHandler handler = mock(ResponseHandler.class); - dispatcher.enqueue( handler ); + dispatcher.enqueue(handler); dispatcher.handleIgnoredMessage(); - assertEquals( 0, dispatcher.queuedHandlersCount() ); + assertEquals(0, dispatcher.queuedHandlersCount()); } @Test - void shouldFailHandlerOnIgnoredMessageWithExistingError() - { + void shouldFailHandlerOnIgnoredMessageWithExistingError() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler1 = mock( ResponseHandler.class ); - ResponseHandler handler2 = mock( ResponseHandler.class ); + ResponseHandler handler1 = mock(ResponseHandler.class); + ResponseHandler handler2 = mock(ResponseHandler.class); - dispatcher.enqueue( handler1 ); - dispatcher.enqueue( handler2 ); + dispatcher.enqueue(handler1); + dispatcher.enqueue(handler2); - dispatcher.handleFailureMessage( FAILURE_CODE, FAILURE_MESSAGE ); - verifyFailure( handler1 ); - verify( handler2, only() ).canManageAutoRead(); + dispatcher.handleFailureMessage(FAILURE_CODE, FAILURE_MESSAGE); + verifyFailure(handler1); + verify(handler2, only()).canManageAutoRead(); dispatcher.handleIgnoredMessage(); - verifyFailure( handler2 ); + verifyFailure(handler2); } @Test - void shouldFailHandlerOnIgnoredMessageWhenNoErrorAndNotHandlingReset() - { + void shouldFailHandlerOnIgnoredMessageWhenNoErrorAndNotHandlingReset() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler = mock( ResponseHandler.class ); - dispatcher.enqueue( handler ); + ResponseHandler handler = mock(ResponseHandler.class); + dispatcher.enqueue(handler); dispatcher.handleIgnoredMessage(); - verify( handler ).onFailure( any( ClientException.class ) ); + verify(handler).onFailure(any(ClientException.class)); } @Test - void shouldDequeAndFailHandlerOnIgnoredWhenErrorHappened() - { + void shouldDequeAndFailHandlerOnIgnoredWhenErrorHappened() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler1 = mock( ResponseHandler.class ); - ResponseHandler handler2 = mock( ResponseHandler.class ); + ResponseHandler handler1 = mock(ResponseHandler.class); + ResponseHandler handler2 = mock(ResponseHandler.class); - dispatcher.enqueue( handler1 ); - dispatcher.enqueue( handler2 ); - dispatcher.handleFailureMessage( FAILURE_CODE, FAILURE_MESSAGE ); + dispatcher.enqueue(handler1); + dispatcher.enqueue(handler2); + dispatcher.handleFailureMessage(FAILURE_CODE, FAILURE_MESSAGE); dispatcher.handleIgnoredMessage(); // "RESET after failure" handler should remain queued - assertEquals( 1, dispatcher.queuedHandlersCount() ); - verifyFailure( handler1 ); - verifyFailure( handler2 ); + assertEquals(1, dispatcher.queuedHandlersCount()); + verifyFailure(handler1); + verifyFailure(handler2); } @Test - void shouldThrowWhenNoHandlerToHandleRecordMessage() - { + void shouldThrowWhenNoHandlerToHandleRecordMessage() { InboundMessageDispatcher dispatcher = newDispatcher(); - assertThrows( IllegalStateException.class, () -> dispatcher.handleRecordMessage( new Value[]{value( 1 ), value( 2 )} ) ); + assertThrows( + IllegalStateException.class, () -> dispatcher.handleRecordMessage(new Value[] {value(1), value(2)})); } @Test - void shouldKeepSingleAutoReadManagingHandler() - { + void shouldKeepSingleAutoReadManagingHandler() { InboundMessageDispatcher dispatcher = newDispatcher(); ResponseHandler handler1 = newAutoReadManagingResponseHandler(); ResponseHandler handler2 = newAutoReadManagingResponseHandler(); ResponseHandler handler3 = newAutoReadManagingResponseHandler(); - dispatcher.enqueue( handler1 ); - dispatcher.enqueue( handler2 ); - dispatcher.enqueue( handler3 ); + dispatcher.enqueue(handler1); + dispatcher.enqueue(handler2); + dispatcher.enqueue(handler3); - InOrder inOrder = inOrder( handler1, handler2, handler3 ); - inOrder.verify( handler1 ).disableAutoReadManagement(); - inOrder.verify( handler2 ).disableAutoReadManagement(); - inOrder.verify( handler3, never() ).disableAutoReadManagement(); + InOrder inOrder = inOrder(handler1, handler2, handler3); + inOrder.verify(handler1).disableAutoReadManagement(); + inOrder.verify(handler2).disableAutoReadManagement(); + inOrder.verify(handler3, never()).disableAutoReadManagement(); } @Test - void shouldKeepTrackOfAutoReadManagingHandler() - { + void shouldKeepTrackOfAutoReadManagingHandler() { InboundMessageDispatcher dispatcher = newDispatcher(); ResponseHandler handler1 = newAutoReadManagingResponseHandler(); ResponseHandler handler2 = newAutoReadManagingResponseHandler(); - assertNull( dispatcher.autoReadManagingHandler() ); + assertNull(dispatcher.autoReadManagingHandler()); - dispatcher.enqueue( handler1 ); - assertEquals( handler1, dispatcher.autoReadManagingHandler() ); + dispatcher.enqueue(handler1); + assertEquals(handler1, dispatcher.autoReadManagingHandler()); - dispatcher.enqueue( handler2 ); - assertEquals( handler2, dispatcher.autoReadManagingHandler() ); + dispatcher.enqueue(handler2); + assertEquals(handler2, dispatcher.autoReadManagingHandler()); } @Test - void shouldForgetAutoReadManagingHandlerWhenItIsRemoved() - { + void shouldForgetAutoReadManagingHandlerWhenItIsRemoved() { InboundMessageDispatcher dispatcher = newDispatcher(); - ResponseHandler handler1 = mock( ResponseHandler.class ); - ResponseHandler handler2 = mock( ResponseHandler.class ); + ResponseHandler handler1 = mock(ResponseHandler.class); + ResponseHandler handler2 = mock(ResponseHandler.class); ResponseHandler handler3 = newAutoReadManagingResponseHandler(); - dispatcher.enqueue( handler1 ); - dispatcher.enqueue( handler2 ); - dispatcher.enqueue( handler3 ); - assertEquals( handler3, dispatcher.autoReadManagingHandler() ); + dispatcher.enqueue(handler1); + dispatcher.enqueue(handler2); + dispatcher.enqueue(handler3); + assertEquals(handler3, dispatcher.autoReadManagingHandler()); - dispatcher.handleSuccessMessage( emptyMap() ); - dispatcher.handleSuccessMessage( emptyMap() ); - dispatcher.handleSuccessMessage( emptyMap() ); + dispatcher.handleSuccessMessage(emptyMap()); + dispatcher.handleSuccessMessage(emptyMap()); + dispatcher.handleSuccessMessage(emptyMap()); - assertNull( dispatcher.autoReadManagingHandler() ); + assertNull(dispatcher.autoReadManagingHandler()); } @Test - void shouldReEnableAutoReadWhenAutoReadManagingHandlerIsRemoved() - { + void shouldReEnableAutoReadWhenAutoReadManagingHandlerIsRemoved() { Channel channel = newChannelMock(); - InboundMessageDispatcher dispatcher = newDispatcher( channel ); + InboundMessageDispatcher dispatcher = newDispatcher(channel); ResponseHandler handler = newAutoReadManagingResponseHandler(); - dispatcher.enqueue( handler ); - assertEquals( handler, dispatcher.autoReadManagingHandler() ); - verify( handler, never() ).disableAutoReadManagement(); - verify( channel.config(), never() ).setAutoRead( anyBoolean() ); + dispatcher.enqueue(handler); + assertEquals(handler, dispatcher.autoReadManagingHandler()); + verify(handler, never()).disableAutoReadManagement(); + verify(channel.config(), never()).setAutoRead(anyBoolean()); - dispatcher.handleSuccessMessage( emptyMap() ); + dispatcher.handleSuccessMessage(emptyMap()); - assertNull( dispatcher.autoReadManagingHandler() ); - verify( handler ).disableAutoReadManagement(); - verify( channel.config() ).setAutoRead( anyBoolean() ); + assertNull(dispatcher.autoReadManagingHandler()); + verify(handler).disableAutoReadManagement(); + verify(channel.config()).setAutoRead(anyBoolean()); } @ParameterizedTest - @ValueSource( classes = {SuccessMessage.class, FailureMessage.class, RecordMessage.class, IgnoredMessage.class} ) - void shouldCreateChannelActivityLoggerAndLogDebugMessageOnMessageHandling( Class message ) - { + @ValueSource(classes = {SuccessMessage.class, FailureMessage.class, RecordMessage.class, IgnoredMessage.class}) + void shouldCreateChannelActivityLoggerAndLogDebugMessageOnMessageHandling(Class message) { // GIVEN Channel channel = newChannelMock(); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logger.isDebugEnabled() ).thenReturn( true ); - when( logging.getLog( InboundMessageDispatcher.class ) ).thenReturn( logger ); - ChannelErrorLogger errorLogger = mock( ChannelErrorLogger.class ); - when( logging.getLog( ChannelErrorLogger.class ) ).thenReturn( errorLogger ); - InboundMessageDispatcher dispatcher = new InboundMessageDispatcher( channel, logging ); - ResponseHandler handler = mock( ResponseHandler.class ); - dispatcher.enqueue( handler ); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logger.isDebugEnabled()).thenReturn(true); + when(logging.getLog(InboundMessageDispatcher.class)).thenReturn(logger); + ChannelErrorLogger errorLogger = mock(ChannelErrorLogger.class); + when(logging.getLog(ChannelErrorLogger.class)).thenReturn(errorLogger); + InboundMessageDispatcher dispatcher = new InboundMessageDispatcher(channel, logging); + ResponseHandler handler = mock(ResponseHandler.class); + dispatcher.enqueue(handler); // WHEN - if ( SuccessMessage.class.isAssignableFrom( message ) ) - { - dispatcher.handleSuccessMessage( new HashMap<>() ); - } - else if ( FailureMessage.class.isAssignableFrom( message ) ) - { - dispatcher.handleFailureMessage( FAILURE_CODE, FAILURE_MESSAGE ); - } - else if ( RecordMessage.class.isAssignableFrom( message ) ) - { - dispatcher.handleRecordMessage( Values.values() ); - } - else if ( IgnoredMessage.class.isAssignableFrom( message ) ) - { + if (SuccessMessage.class.isAssignableFrom(message)) { + dispatcher.handleSuccessMessage(new HashMap<>()); + } else if (FailureMessage.class.isAssignableFrom(message)) { + dispatcher.handleFailureMessage(FAILURE_CODE, FAILURE_MESSAGE); + } else if (RecordMessage.class.isAssignableFrom(message)) { + dispatcher.handleRecordMessage(Values.values()); + } else if (IgnoredMessage.class.isAssignableFrom(message)) { dispatcher.handleIgnoredMessage(); - } - else - { - fail( "Unexpected message type parameter provided" ); + } else { + fail("Unexpected message type parameter provided"); } // THEN - assertTrue( dispatcher.getLog() instanceof ChannelActivityLogger ); - assertTrue( dispatcher.getErrorLog() instanceof ChannelErrorLogger ); - verify( logger ).debug( anyString(), any( Object.class ) ); + assertTrue(dispatcher.getLog() instanceof ChannelActivityLogger); + assertTrue(dispatcher.getErrorLog() instanceof ChannelErrorLogger); + verify(logger).debug(anyString(), any(Object.class)); } @Test - void shouldCreateChannelErrorLoggerAndLogDebugMessageOnChannelError() - { + void shouldCreateChannelErrorLoggerAndLogDebugMessageOnChannelError() { // GIVEN Channel channel = newChannelMock(); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logger.isDebugEnabled() ).thenReturn( true ); - when( logging.getLog( InboundMessageDispatcher.class ) ).thenReturn( logger ); - ChannelErrorLogger errorLogger = mock( ChannelErrorLogger.class ); - when( errorLogger.isDebugEnabled() ).thenReturn( true ); - when( logging.getLog( ChannelErrorLogger.class ) ).thenReturn( errorLogger ); - InboundMessageDispatcher dispatcher = new InboundMessageDispatcher( channel, logging ); - ResponseHandler handler = mock( ResponseHandler.class ); - dispatcher.enqueue( handler ); - Throwable throwable = mock( Throwable.class ); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logger.isDebugEnabled()).thenReturn(true); + when(logging.getLog(InboundMessageDispatcher.class)).thenReturn(logger); + ChannelErrorLogger errorLogger = mock(ChannelErrorLogger.class); + when(errorLogger.isDebugEnabled()).thenReturn(true); + when(logging.getLog(ChannelErrorLogger.class)).thenReturn(errorLogger); + InboundMessageDispatcher dispatcher = new InboundMessageDispatcher(channel, logging); + ResponseHandler handler = mock(ResponseHandler.class); + dispatcher.enqueue(handler); + Throwable throwable = mock(Throwable.class); // WHEN - dispatcher.handleChannelError( throwable ); + dispatcher.handleChannelError(throwable); // THEN - assertTrue( dispatcher.getLog() instanceof ChannelActivityLogger ); - assertTrue( dispatcher.getErrorLog() instanceof ChannelErrorLogger ); - verify( errorLogger ).debug( contains( throwable.getClass().toString() ) ); + assertTrue(dispatcher.getLog() instanceof ChannelActivityLogger); + assertTrue(dispatcher.getErrorLog() instanceof ChannelErrorLogger); + verify(errorLogger).debug(contains(throwable.getClass().toString())); } - private static void verifyFailure( ResponseHandler handler ) - { - ArgumentCaptor captor = ArgumentCaptor.forClass( Neo4jException.class ); - verify( handler ).onFailure( captor.capture() ); - assertEquals( FAILURE_CODE, captor.getValue().code() ); - assertEquals( FAILURE_MESSAGE, captor.getValue().getMessage() ); + private static void verifyFailure(ResponseHandler handler) { + ArgumentCaptor captor = ArgumentCaptor.forClass(Neo4jException.class); + verify(handler).onFailure(captor.capture()); + assertEquals(FAILURE_CODE, captor.getValue().code()); + assertEquals(FAILURE_MESSAGE, captor.getValue().getMessage()); } - private static InboundMessageDispatcher newDispatcher() - { - return newDispatcher( newChannelMock() ); + private static InboundMessageDispatcher newDispatcher() { + return newDispatcher(newChannelMock()); } - private static InboundMessageDispatcher newDispatcher( Channel channel ) - { - return new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ); + private static InboundMessageDispatcher newDispatcher(Channel channel) { + return new InboundMessageDispatcher(channel, DEV_NULL_LOGGING); } - @SuppressWarnings( "unchecked" ) - private static Channel newChannelMock() - { - Channel channel = mock( Channel.class ); - when( channel.id() ).thenReturn( DefaultChannelId.newInstance() ); - ChannelConfig channelConfig = mock( ChannelConfig.class ); - when( channel.config() ).thenReturn( channelConfig ); - Attribute attribute = mock( Attribute.class ); - when( channel.attr( any() ) ).thenReturn( attribute ); + @SuppressWarnings("unchecked") + private static Channel newChannelMock() { + Channel channel = mock(Channel.class); + when(channel.id()).thenReturn(DefaultChannelId.newInstance()); + ChannelConfig channelConfig = mock(ChannelConfig.class); + when(channel.config()).thenReturn(channelConfig); + Attribute attribute = mock(Attribute.class); + when(channel.attr(any())).thenReturn(attribute); return channel; } - private static ResponseHandler newAutoReadManagingResponseHandler() - { - ResponseHandler handler = mock( ResponseHandler.class ); - when( handler.canManageAutoRead() ).thenReturn( true ); + private static ResponseHandler newAutoReadManagingResponseHandler() { + ResponseHandler handler = mock(ResponseHandler.class); + when(handler.canManageAutoRead()).thenReturn(true); return handler; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageHandlerTest.java index 4e316797a8..ec2f87033e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/InboundMessageHandlerTest.java @@ -18,17 +18,28 @@ */ package org.neo4j.driver.internal.async.inbound; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; + import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.codec.DecoderException; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - import org.neo4j.driver.Value; import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.internal.async.connection.ChannelAttributes; @@ -43,111 +54,89 @@ import org.neo4j.driver.internal.util.io.MessageToByteBufWriter; import org.neo4j.driver.internal.util.messaging.KnowledgeableMessageFormat; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; - -class InboundMessageHandlerTest -{ +class InboundMessageHandlerTest { private EmbeddedChannel channel; private InboundMessageDispatcher messageDispatcher; private MessageToByteBufWriter writer; @BeforeEach - void setUp() - { + void setUp() { channel = new EmbeddedChannel(); - messageDispatcher = new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ); - writer = new MessageToByteBufWriter( new KnowledgeableMessageFormat() ); - ChannelAttributes.setMessageDispatcher( channel, messageDispatcher ); + messageDispatcher = new InboundMessageDispatcher(channel, DEV_NULL_LOGGING); + writer = new MessageToByteBufWriter(new KnowledgeableMessageFormat()); + ChannelAttributes.setMessageDispatcher(channel, messageDispatcher); - InboundMessageHandler handler = new InboundMessageHandler( new MessageFormatV3(), DEV_NULL_LOGGING ); - channel.pipeline().addFirst( handler ); + InboundMessageHandler handler = new InboundMessageHandler(new MessageFormatV3(), DEV_NULL_LOGGING); + channel.pipeline().addFirst(handler); } @AfterEach - void tearDown() - { - if ( channel != null ) - { + void tearDown() { + if (channel != null) { channel.finishAndReleaseAll(); } } @Test - void shouldReadSuccessMessage() - { - ResponseHandler responseHandler = mock( ResponseHandler.class ); - messageDispatcher.enqueue( responseHandler ); + void shouldReadSuccessMessage() { + ResponseHandler responseHandler = mock(ResponseHandler.class); + messageDispatcher.enqueue(responseHandler); - Map metadata = new HashMap<>(); - metadata.put( "key1", value( 1 ) ); - metadata.put( "key2", value( 2 ) ); - channel.writeInbound( writer.asByteBuf( new SuccessMessage( metadata ) ) ); + Map metadata = new HashMap<>(); + metadata.put("key1", value(1)); + metadata.put("key2", value(2)); + channel.writeInbound(writer.asByteBuf(new SuccessMessage(metadata))); - verify( responseHandler ).onSuccess( metadata ); + verify(responseHandler).onSuccess(metadata); } @Test - void shouldReadFailureMessage() - { - ResponseHandler responseHandler = mock( ResponseHandler.class ); - messageDispatcher.enqueue( responseHandler ); + void shouldReadFailureMessage() { + ResponseHandler responseHandler = mock(ResponseHandler.class); + messageDispatcher.enqueue(responseHandler); - channel.writeInbound( writer.asByteBuf( new FailureMessage( "Neo.TransientError.General.ReadOnly", "Hi!" ) ) ); + channel.writeInbound(writer.asByteBuf(new FailureMessage("Neo.TransientError.General.ReadOnly", "Hi!"))); - ArgumentCaptor captor = ArgumentCaptor.forClass( Neo4jException.class ); - verify( responseHandler ).onFailure( captor.capture() ); - assertEquals( "Neo.TransientError.General.ReadOnly", captor.getValue().code() ); - assertEquals( "Hi!", captor.getValue().getMessage() ); + ArgumentCaptor captor = ArgumentCaptor.forClass(Neo4jException.class); + verify(responseHandler).onFailure(captor.capture()); + assertEquals("Neo.TransientError.General.ReadOnly", captor.getValue().code()); + assertEquals("Hi!", captor.getValue().getMessage()); } @Test - void shouldReadRecordMessage() - { - ResponseHandler responseHandler = mock( ResponseHandler.class ); - messageDispatcher.enqueue( responseHandler ); + void shouldReadRecordMessage() { + ResponseHandler responseHandler = mock(ResponseHandler.class); + messageDispatcher.enqueue(responseHandler); - Value[] fields = {value( 1 ), value( 2 ), value( 3 )}; - channel.writeInbound( writer.asByteBuf( new RecordMessage( fields ) ) ); + Value[] fields = {value(1), value(2), value(3)}; + channel.writeInbound(writer.asByteBuf(new RecordMessage(fields))); - verify( responseHandler ).onRecord( fields ); + verify(responseHandler).onRecord(fields); } @Test - void shouldReadIgnoredMessage() - { - ResponseHandler responseHandler = mock( ResponseHandler.class ); - messageDispatcher.enqueue( responseHandler ); + void shouldReadIgnoredMessage() { + ResponseHandler responseHandler = mock(ResponseHandler.class); + messageDispatcher.enqueue(responseHandler); - channel.writeInbound( writer.asByteBuf( IgnoredMessage.IGNORED ) ); - assertEquals( 0, messageDispatcher.queuedHandlersCount() ); + channel.writeInbound(writer.asByteBuf(IgnoredMessage.IGNORED)); + assertEquals(0, messageDispatcher.queuedHandlersCount()); } @Test - void shouldRethrowReadErrors() throws IOException - { - MessageFormat messageFormat = mock( MessageFormat.class ); - Reader reader = mock( Reader.class ); - RuntimeException error = new RuntimeException( "Unable to decode!" ); - doThrow( error ).when( reader ).read( any() ); - when( messageFormat.newReader( any() ) ).thenReturn( reader ); + void shouldRethrowReadErrors() throws IOException { + MessageFormat messageFormat = mock(MessageFormat.class); + Reader reader = mock(Reader.class); + RuntimeException error = new RuntimeException("Unable to decode!"); + doThrow(error).when(reader).read(any()); + when(messageFormat.newReader(any())).thenReturn(reader); - InboundMessageHandler handler = new InboundMessageHandler( messageFormat, DEV_NULL_LOGGING ); + InboundMessageHandler handler = new InboundMessageHandler(messageFormat, DEV_NULL_LOGGING); - channel.pipeline().remove( InboundMessageHandler.class ); - channel.pipeline().addLast( handler ); + channel.pipeline().remove(InboundMessageHandler.class); + channel.pipeline().addLast(handler); - DecoderException e = assertThrows( DecoderException.class, () -> channel.writeInbound( writer.asByteBuf( RESET ) ) ); - assertThat( e.getMessage(), startsWith( "Failed to read inbound message" ) ); + DecoderException e = assertThrows(DecoderException.class, () -> channel.writeInbound(writer.asByteBuf(RESET))); + assertThat(e.getMessage(), startsWith("Failed to read inbound message")); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/MessageDecoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/MessageDecoderTest.java index 61e9380757..c8ec08ef74 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/inbound/MessageDecoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/inbound/MessageDecoderTest.java @@ -18,67 +18,62 @@ */ package org.neo4j.driver.internal.async.inbound; -import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - import static io.netty.buffer.Unpooled.wrappedBuffer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.neo4j.driver.util.TestUtil.assertByteBufEquals; -class MessageDecoderTest -{ - private final EmbeddedChannel channel = new EmbeddedChannel( new MessageDecoder() ); +import io.netty.channel.embedded.EmbeddedChannel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class MessageDecoderTest { + private final EmbeddedChannel channel = new EmbeddedChannel(new MessageDecoder()); @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldDecodeMessageWithSingleChunk() - { - assertFalse( channel.writeInbound( wrappedBuffer( new byte[]{1, 2, 3, 4, 5} ) ) ); - assertTrue( channel.writeInbound( wrappedBuffer( new byte[0] ) ) ); - assertTrue( channel.finish() ); + void shouldDecodeMessageWithSingleChunk() { + assertFalse(channel.writeInbound(wrappedBuffer(new byte[] {1, 2, 3, 4, 5}))); + assertTrue(channel.writeInbound(wrappedBuffer(new byte[0]))); + assertTrue(channel.finish()); - assertEquals( 1, channel.inboundMessages().size() ); - assertByteBufEquals( wrappedBuffer( new byte[]{1, 2, 3, 4, 5} ), channel.readInbound() ); + assertEquals(1, channel.inboundMessages().size()); + assertByteBufEquals(wrappedBuffer(new byte[] {1, 2, 3, 4, 5}), channel.readInbound()); } @Test - void shouldDecodeMessageWithMultipleChunks() - { - assertFalse( channel.writeInbound( wrappedBuffer( new byte[]{1, 2, 3} ) ) ); - assertFalse( channel.writeInbound( wrappedBuffer( new byte[]{4, 5} ) ) ); - assertFalse( channel.writeInbound( wrappedBuffer( new byte[]{6, 7, 8} ) ) ); - assertTrue( channel.writeInbound( wrappedBuffer( new byte[0] ) ) ); - assertTrue( channel.finish() ); + void shouldDecodeMessageWithMultipleChunks() { + assertFalse(channel.writeInbound(wrappedBuffer(new byte[] {1, 2, 3}))); + assertFalse(channel.writeInbound(wrappedBuffer(new byte[] {4, 5}))); + assertFalse(channel.writeInbound(wrappedBuffer(new byte[] {6, 7, 8}))); + assertTrue(channel.writeInbound(wrappedBuffer(new byte[0]))); + assertTrue(channel.finish()); - assertEquals( 1, channel.inboundMessages().size() ); - assertByteBufEquals( wrappedBuffer( new byte[]{1, 2, 3, 4, 5, 6, 7, 8} ), channel.readInbound() ); + assertEquals(1, channel.inboundMessages().size()); + assertByteBufEquals(wrappedBuffer(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}), channel.readInbound()); } @Test - void shouldDecodeMultipleConsecutiveMessages() - { - channel.writeInbound( wrappedBuffer( new byte[]{1, 2, 3} ) ); - channel.writeInbound( wrappedBuffer( new byte[0] ) ); + void shouldDecodeMultipleConsecutiveMessages() { + channel.writeInbound(wrappedBuffer(new byte[] {1, 2, 3})); + channel.writeInbound(wrappedBuffer(new byte[0])); - channel.writeInbound( wrappedBuffer( new byte[]{4, 5} ) ); - channel.writeInbound( wrappedBuffer( new byte[]{6} ) ); - channel.writeInbound( wrappedBuffer( new byte[0] ) ); + channel.writeInbound(wrappedBuffer(new byte[] {4, 5})); + channel.writeInbound(wrappedBuffer(new byte[] {6})); + channel.writeInbound(wrappedBuffer(new byte[0])); - channel.writeInbound( wrappedBuffer( new byte[]{7, 8} ) ); - channel.writeInbound( wrappedBuffer( new byte[]{9, 10} ) ); - channel.writeInbound( wrappedBuffer( new byte[0] ) ); + channel.writeInbound(wrappedBuffer(new byte[] {7, 8})); + channel.writeInbound(wrappedBuffer(new byte[] {9, 10})); + channel.writeInbound(wrappedBuffer(new byte[0])); - assertEquals( 3, channel.inboundMessages().size() ); - assertByteBufEquals( wrappedBuffer( new byte[]{1, 2, 3} ), channel.readInbound() ); - assertByteBufEquals( wrappedBuffer( new byte[]{4, 5, 6} ), channel.readInbound() ); - assertByteBufEquals( wrappedBuffer( new byte[]{7, 8, 9, 10} ), channel.readInbound() ); + assertEquals(3, channel.inboundMessages().size()); + assertByteBufEquals(wrappedBuffer(new byte[] {1, 2, 3}), channel.readInbound()); + assertByteBufEquals(wrappedBuffer(new byte[] {4, 5, 6}), channel.readInbound()); + assertByteBufEquals(wrappedBuffer(new byte[] {7, 8, 9, 10}), channel.readInbound()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/outbound/ChunkAwareByteBufOutputTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/outbound/ChunkAwareByteBufOutputTest.java index a02b3d87e8..5382860941 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/outbound/ChunkAwareByteBufOutputTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/outbound/ChunkAwareByteBufOutputTest.java @@ -18,399 +18,464 @@ */ package org.neo4j.driver.internal.async.outbound; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.util.TestUtil.assertByteBufContains; + import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import java.util.stream.IntStream; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.util.TestUtil.assertByteBufContains; - -class ChunkAwareByteBufOutputTest -{ - private static Stream testBuffers() - { - return IntStream.iterate( 1, size -> size * 2 ) - .limit( 20 ) - .mapToObj( Unpooled::buffer ); +class ChunkAwareByteBufOutputTest { + private static Stream testBuffers() { + return IntStream.iterate(1, size -> size * 2).limit(20).mapToObj(Unpooled::buffer); } @Test - void shouldThrowForIllegalMaxChunkSize() - { - assertThrows( IllegalArgumentException.class, () -> new ChunkAwareByteBufOutput( -42 ) ); + void shouldThrowForIllegalMaxChunkSize() { + assertThrows(IllegalArgumentException.class, () -> new ChunkAwareByteBufOutput(-42)); } @Test - void shouldThrowWhenStartedWithNullBuf() - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 16 ); - assertThrows( NullPointerException.class, () -> output.start( null ) ); + void shouldThrowWhenStartedWithNullBuf() { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(16); + assertThrows(NullPointerException.class, () -> output.start(null)); } @Test - void shouldThrowWhenStartedTwice() - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 16 ); - output.start( mock( ByteBuf.class ) ); + void shouldThrowWhenStartedTwice() { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(16); + output.start(mock(ByteBuf.class)); - assertThrows( IllegalStateException.class, () -> output.start( mock( ByteBuf.class ) ) ); + assertThrows(IllegalStateException.class, () -> output.start(mock(ByteBuf.class))); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteByteAtTheBeginningOfChunk( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 16 ); + @MethodSource("testBuffers") + void shouldWriteByteAtTheBeginningOfChunk(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(16); - output.start( buf ); - output.writeByte( (byte) 42 ); + output.start(buf); + output.writeByte((byte) 42); output.stop(); - assertByteBufContains( buf, (short) 1, (byte) 42 ); + assertByteBufContains(buf, (short) 1, (byte) 42); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteByteWhenCurrentChunkContainsSpace( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 16 ); + @MethodSource("testBuffers") + void shouldWriteByteWhenCurrentChunkContainsSpace(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(16); - output.start( buf ); - output.writeByte( (byte) 1 ); - output.writeByte( (byte) 2 ); - output.writeByte( (byte) -24 ); + output.start(buf); + output.writeByte((byte) 1); + output.writeByte((byte) 2); + output.writeByte((byte) -24); - output.writeByte( (byte) 42 ); + output.writeByte((byte) 42); output.stop(); - assertByteBufContains( buf, (short) 4, (byte) 1, (byte) 2, (byte) -24, (byte) 42 ); + assertByteBufContains(buf, (short) 4, (byte) 1, (byte) 2, (byte) -24, (byte) 42); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteByteWhenCurrentChunkIsFull( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 5 ); + @MethodSource("testBuffers") + void shouldWriteByteWhenCurrentChunkIsFull(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(5); - output.start( buf ); - output.writeByte( (byte) 5 ); - output.writeByte( (byte) 3 ); - output.writeByte( (byte) -5 ); + output.start(buf); + output.writeByte((byte) 5); + output.writeByte((byte) 3); + output.writeByte((byte) -5); - output.writeByte( (byte) 42 ); + output.writeByte((byte) 42); output.stop(); - assertByteBufContains( buf, - (short) 3, (byte) 5, (byte) 3, (byte) -5, // chunk 1 - (short) 1, (byte) 42 // chunk 2 - ); + assertByteBufContains( + buf, + (short) 3, + (byte) 5, + (byte) 3, + (byte) -5, // chunk 1 + (short) 1, + (byte) 42 // chunk 2 + ); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteShortAtTheBeginningOfChunk( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 10 ); + @MethodSource("testBuffers") + void shouldWriteShortAtTheBeginningOfChunk(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(10); - output.start( buf ); - output.writeShort( Short.MAX_VALUE ); + output.start(buf); + output.writeShort(Short.MAX_VALUE); output.stop(); - assertByteBufContains( buf, (short) 2, Short.MAX_VALUE ); + assertByteBufContains(buf, (short) 2, Short.MAX_VALUE); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteShortWhenCurrentChunkContainsSpace( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 12 ); - - output.start( buf ); - output.writeShort( (short) 1 ); - output.writeShort( (short) 42 ); - output.writeShort( (short) 4242 ); - output.writeShort( (short) 4242 ); - - output.writeShort( (short) -30 ); + @MethodSource("testBuffers") + void shouldWriteShortWhenCurrentChunkContainsSpace(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(12); + + output.start(buf); + output.writeShort((short) 1); + output.writeShort((short) 42); + output.writeShort((short) 4242); + output.writeShort((short) 4242); + + output.writeShort((short) -30); output.stop(); - assertByteBufContains( buf, (short) 10, (short) 1, (short) 42, (short) 4242, (short) 4242, (short) -30 ); + assertByteBufContains(buf, (short) 10, (short) 1, (short) 42, (short) 4242, (short) 4242, (short) -30); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteShortWhenCurrentChunkIsFull( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 8 ); + @MethodSource("testBuffers") + void shouldWriteShortWhenCurrentChunkIsFull(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(8); - output.start( buf ); - output.writeShort( (short) 14 ); - output.writeShort( (short) -99 ); - output.writeShort( (short) 202 ); + output.start(buf); + output.writeShort((short) 14); + output.writeShort((short) -99); + output.writeShort((short) 202); - output.writeShort( Short.MIN_VALUE ); + output.writeShort(Short.MIN_VALUE); output.stop(); - assertByteBufContains( buf, - (short) 6, (short) 14, (short) -99, (short) 202, // chunk 1 - (short) 2, Short.MIN_VALUE // chunk 2 - ); + assertByteBufContains( + buf, + (short) 6, + (short) 14, + (short) -99, + (short) 202, // chunk 1 + (short) 2, + Short.MIN_VALUE // chunk 2 + ); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteIntAtTheBeginningOfChunk( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 18 ); + @MethodSource("testBuffers") + void shouldWriteIntAtTheBeginningOfChunk(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(18); - output.start( buf ); - output.writeInt( 73649 ); + output.start(buf); + output.writeInt(73649); output.stop(); - assertByteBufContains( buf, (short) 4, 73649 ); + assertByteBufContains(buf, (short) 4, 73649); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteIntWhenCurrentChunkContainsSpace( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 40 ); + @MethodSource("testBuffers") + void shouldWriteIntWhenCurrentChunkContainsSpace(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(40); - output.start( buf ); - output.writeInt( Integer.MAX_VALUE ); - output.writeInt( 20 ); - output.writeInt( -173 ); + output.start(buf); + output.writeInt(Integer.MAX_VALUE); + output.writeInt(20); + output.writeInt(-173); - output.writeInt( Integer.MIN_VALUE ); + output.writeInt(Integer.MIN_VALUE); output.stop(); - assertByteBufContains( buf, (short) 16, Integer.MAX_VALUE, 20, -173, Integer.MIN_VALUE ); + assertByteBufContains(buf, (short) 16, Integer.MAX_VALUE, 20, -173, Integer.MIN_VALUE); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteIntWhenCurrentChunkIsFull( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 27 ); - - output.start( buf ); - output.writeInt( 42 ); - output.writeInt( -73467193 ); - output.writeInt( 373 ); - output.writeInt( -93 ); - output.writeInt( 1312345 ); - output.writeInt( 785 ); - - output.writeInt( 42 ); + @MethodSource("testBuffers") + void shouldWriteIntWhenCurrentChunkIsFull(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(27); + + output.start(buf); + output.writeInt(42); + output.writeInt(-73467193); + output.writeInt(373); + output.writeInt(-93); + output.writeInt(1312345); + output.writeInt(785); + + output.writeInt(42); output.stop(); - assertByteBufContains( buf, - (short) 24, 42, -73467193, 373, -93, 1312345, 785, // chunk 1 - (short) 4, 42 // chunk 2 - ); + assertByteBufContains( + buf, + (short) 24, + 42, + -73467193, + 373, + -93, + 1312345, + 785, // chunk 1 + (short) 4, + 42 // chunk 2 + ); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteLongAtTheBeginningOfChunk( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 12 ); + @MethodSource("testBuffers") + void shouldWriteLongAtTheBeginningOfChunk(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(12); - output.start( buf ); - output.writeLong( 15 ); + output.start(buf); + output.writeLong(15); output.stop(); - assertByteBufContains( buf, (short) 8, 15L ); + assertByteBufContains(buf, (short) 8, 15L); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteLongWhenCurrentChunkContainsSpace( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 34 ); + @MethodSource("testBuffers") + void shouldWriteLongWhenCurrentChunkContainsSpace(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(34); - output.start( buf ); - output.writeLong( Long.MAX_VALUE ); - output.writeLong( -1 ); - output.writeLong( -100 ); + output.start(buf); + output.writeLong(Long.MAX_VALUE); + output.writeLong(-1); + output.writeLong(-100); - output.writeLong( Long.MIN_VALUE / 2 ); + output.writeLong(Long.MIN_VALUE / 2); output.stop(); - assertByteBufContains( buf, (short) 32, Long.MAX_VALUE, -1L, -100L, Long.MIN_VALUE / 2 ); + assertByteBufContains(buf, (short) 32, Long.MAX_VALUE, -1L, -100L, Long.MIN_VALUE / 2); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteLongWhenCurrentChunkIsFull( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 38 ); - - output.start( buf ); - output.writeLong( 12 ); - output.writeLong( 8741 ); - output.writeLong( 2314 ); - output.writeLong( -85793 ); - - output.writeLong( -57999999 ); + @MethodSource("testBuffers") + void shouldWriteLongWhenCurrentChunkIsFull(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(38); + + output.start(buf); + output.writeLong(12); + output.writeLong(8741); + output.writeLong(2314); + output.writeLong(-85793); + + output.writeLong(-57999999); output.stop(); - assertByteBufContains( buf, - (short) 32, 12L, 8741L, 2314L, -85793L, // chunk 1 - (short) 8, -57999999L // chunk 2 - ); + assertByteBufContains( + buf, + (short) 32, + 12L, + 8741L, + 2314L, + -85793L, // chunk 1 + (short) 8, + -57999999L // chunk 2 + ); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteDoubleAtTheBeginningOfChunk( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 10 ); + @MethodSource("testBuffers") + void shouldWriteDoubleAtTheBeginningOfChunk(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(10); - output.start( buf ); - output.writeDouble( 12.99937 ); + output.start(buf); + output.writeDouble(12.99937); output.stop(); - assertByteBufContains( buf, (short) 8, 12.99937D ); + assertByteBufContains(buf, (short) 8, 12.99937D); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteDoubleWhenCurrentChunkContainsSpace( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 18 ); + @MethodSource("testBuffers") + void shouldWriteDoubleWhenCurrentChunkContainsSpace(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(18); - output.start( buf ); - output.writeDouble( -5 ); + output.start(buf); + output.writeDouble(-5); - output.writeDouble( 991.3333 ); + output.writeDouble(991.3333); output.stop(); - assertByteBufContains( buf, (short) 16, -5D, 991.3333D ); + assertByteBufContains(buf, (short) 16, -5D, 991.3333D); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteDoubleWhenCurrentChunkIsFull( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 20 ); + @MethodSource("testBuffers") + void shouldWriteDoubleWhenCurrentChunkIsFull(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(20); - output.start( buf ); - output.writeDouble( 1839 ); - output.writeDouble( 5710923.34873 ); + output.start(buf); + output.writeDouble(1839); + output.writeDouble(5710923.34873); - output.writeDouble( -47389.333399 ); + output.writeDouble(-47389.333399); output.stop(); - assertByteBufContains( buf, - (short) 16, 1839D, 5710923.34873D, // chunk 1 - (short) 8, -47389.333399D // chunk 2 - ); + assertByteBufContains( + buf, + (short) 16, + 1839D, + 5710923.34873D, // chunk 1 + (short) 8, + -47389.333399D // chunk 2 + ); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteBytesAtTheBeginningOfChunk( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 10 ); + @MethodSource("testBuffers") + void shouldWriteBytesAtTheBeginningOfChunk(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(10); - output.start( buf ); - output.writeBytes( new byte[]{1, 2, 3, -1, -2, -3, 127} ); + output.start(buf); + output.writeBytes(new byte[] {1, 2, 3, -1, -2, -3, 127}); output.stop(); - assertByteBufContains( buf, - (short) 7, (byte) 1, (byte) 2, (byte) 3, (byte) -1, (byte) -2, (byte) -3, (byte) 127 ); + assertByteBufContains( + buf, (short) 7, (byte) 1, (byte) 2, (byte) 3, (byte) -1, (byte) -2, (byte) -3, (byte) 127); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteBytesWhenCurrentChunkContainsSpace( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 13 ); + @MethodSource("testBuffers") + void shouldWriteBytesWhenCurrentChunkContainsSpace(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(13); - output.start( buf ); - output.writeBytes( new byte[]{9, 8, -10} ); - output.writeBytes( new byte[]{127, 126, -128, -126} ); - output.writeBytes( new byte[]{0, 99} ); + output.start(buf); + output.writeBytes(new byte[] {9, 8, -10}); + output.writeBytes(new byte[] {127, 126, -128, -126}); + output.writeBytes(new byte[] {0, 99}); - output.writeBytes( new byte[]{-42, 42} ); + output.writeBytes(new byte[] {-42, 42}); output.stop(); - assertByteBufContains( buf, (short) 11, (byte) 9, (byte) 8, (byte) -10, (byte) 127, (byte) 126, (byte) -128, - (byte) -126, (byte) 0, (byte) 99, (byte) -42, (byte) 42 ); + assertByteBufContains( + buf, + (short) 11, + (byte) 9, + (byte) 8, + (byte) -10, + (byte) 127, + (byte) 126, + (byte) -128, + (byte) -126, + (byte) 0, + (byte) 99, + (byte) -42, + (byte) 42); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteBytesWhenCurrentChunkIsFull( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 9 ); + @MethodSource("testBuffers") + void shouldWriteBytesWhenCurrentChunkIsFull(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(9); - output.start( buf ); - output.writeBytes( new byte[]{1, 2} ); - output.writeBytes( new byte[]{3, 4, 5} ); - output.writeBytes( new byte[]{10} ); + output.start(buf); + output.writeBytes(new byte[] {1, 2}); + output.writeBytes(new byte[] {3, 4, 5}); + output.writeBytes(new byte[] {10}); - output.writeBytes( new byte[]{-1, -42, -43} ); + output.writeBytes(new byte[] {-1, -42, -43}); output.stop(); - assertByteBufContains( buf, - (short) 7, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 10, (byte) -1, // chunk 1 - (short) 2, (byte) -42, (byte) -43 // chunk 2 - ); + assertByteBufContains( + buf, + (short) 7, + (byte) 1, + (byte) 2, + (byte) 3, + (byte) 4, + (byte) 5, + (byte) 10, + (byte) -1, // chunk 1 + (short) 2, + (byte) -42, + (byte) -43 // chunk 2 + ); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteBytesThatSpanMultipleChunks( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 7 ); + @MethodSource("testBuffers") + void shouldWriteBytesThatSpanMultipleChunks(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(7); - output.start( buf ); - output.writeBytes( new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18} ); + output.start(buf); + output.writeBytes(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}); output.stop(); - assertByteBufContains( buf, - (short) 5, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, // chunk 1 - (short) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, // chunk 2 - (short) 5, (byte) 11, (byte) 12, (byte) 13, (byte) 14, (byte) 15, // chunk 3 - (short) 3, (byte) 16, (byte) 17, (byte) 18 // chunk 4 - ); + assertByteBufContains( + buf, + (short) 5, + (byte) 1, + (byte) 2, + (byte) 3, + (byte) 4, + (byte) 5, // chunk 1 + (short) 5, + (byte) 6, + (byte) 7, + (byte) 8, + (byte) 9, + (byte) 10, // chunk 2 + (short) 5, + (byte) 11, + (byte) 12, + (byte) 13, + (byte) 14, + (byte) 15, // chunk 3 + (short) 3, + (byte) 16, + (byte) 17, + (byte) 18 // chunk 4 + ); } @ParameterizedTest - @MethodSource( "testBuffers" ) - void shouldWriteDataToMultipleChunks( ByteBuf buf ) - { - ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput( 13 ); - - output.start( buf ); - output.writeDouble( 12.3 ); - output.writeByte( (byte) 42 ); - output.writeInt( -10 ); - output.writeInt( 99 ); - output.writeLong( 99 ); - output.writeBytes( new byte[]{9, 8, 7, 6} ); - output.writeDouble( 0.333 ); - output.writeShort( (short) 0 ); - output.writeShort( (short) 1 ); - output.writeInt( 12345 ); - output.writeBytes( new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} ); + @MethodSource("testBuffers") + void shouldWriteDataToMultipleChunks(ByteBuf buf) { + ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(13); + + output.start(buf); + output.writeDouble(12.3); + output.writeByte((byte) 42); + output.writeInt(-10); + output.writeInt(99); + output.writeLong(99); + output.writeBytes(new byte[] {9, 8, 7, 6}); + output.writeDouble(0.333); + output.writeShort((short) 0); + output.writeShort((short) 1); + output.writeInt(12345); + output.writeBytes(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); output.stop(); - assertByteBufContains( buf, - (short) 9, 12.3D, (byte) 42, // chunk 1 - (short) 8, -10, 99, // chunk 2 - (short) 11, 99L, (byte) 9, (byte) 8, (byte) 7, // chunk 3 - (short) 11, (byte) 6, 0.333D, (short) 0, // chunk 4 - (short) 11, (short) 1, 12345, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, // chunk 5 - (short) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10 // chunk 6 - ); + assertByteBufContains( + buf, + (short) 9, + 12.3D, + (byte) 42, // chunk 1 + (short) 8, + -10, + 99, // chunk 2 + (short) 11, + 99L, + (byte) 9, + (byte) 8, + (byte) 7, // chunk 3 + (short) 11, + (byte) 6, + 0.333D, + (short) 0, // chunk 4 + (short) 11, + (short) 1, + 12345, + (byte) 1, + (byte) 2, + (byte) 3, + (byte) 4, + (byte) 5, // chunk 5 + (short) 5, + (byte) 6, + (byte) 7, + (byte) 8, + (byte) 9, + (byte) 10 // chunk 6 + ); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/outbound/OutboundMessageHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/outbound/OutboundMessageHandlerTest.java index 72d113e799..278aca1468 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/outbound/OutboundMessageHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/outbound/OutboundMessageHandlerTest.java @@ -18,16 +18,26 @@ */ package org.neo4j.driver.internal.async.outbound; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.messaging.MessageFormat.Writer; +import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; +import static org.neo4j.driver.util.TestUtil.assertByteBufContains; + import io.netty.buffer.ByteBuf; import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import java.io.IOException; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.neo4j.driver.Query; import org.neo4j.driver.Value; import org.neo4j.driver.Values; @@ -38,99 +48,84 @@ import org.neo4j.driver.internal.messaging.v3.MessageFormatV3; import org.neo4j.driver.internal.packstream.PackOutput; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.messaging.MessageFormat.Writer; -import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; -import static org.neo4j.driver.util.TestUtil.assertByteBufContains; - -class OutboundMessageHandlerTest -{ +class OutboundMessageHandlerTest { private final EmbeddedChannel channel = new EmbeddedChannel(); @BeforeEach - void setUp() - { - ChannelAttributes.setMessageDispatcher( channel, new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ) ); + void setUp() { + ChannelAttributes.setMessageDispatcher(channel, new InboundMessageDispatcher(channel, DEV_NULL_LOGGING)); } @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldOutputByteBufAsWrittenByWriterAndMessageBoundary() - { - MessageFormat messageFormat = mockMessageFormatWithWriter( 1, 2, 3, 4, 5 ); - OutboundMessageHandler handler = newHandler( messageFormat ); - channel.pipeline().addLast( handler ); + void shouldOutputByteBufAsWrittenByWriterAndMessageBoundary() { + MessageFormat messageFormat = mockMessageFormatWithWriter(1, 2, 3, 4, 5); + OutboundMessageHandler handler = newHandler(messageFormat); + channel.pipeline().addLast(handler); // do not care which message, writer will return predefined bytes anyway - assertTrue( channel.writeOutbound( PULL_ALL ) ); - assertTrue( channel.finish() ); + assertTrue(channel.writeOutbound(PULL_ALL)); + assertTrue(channel.finish()); - assertEquals( 1, channel.outboundMessages().size() ); + assertEquals(1, channel.outboundMessages().size()); ByteBuf buf = channel.readOutbound(); assertByteBufContains( buf, - (short) 5, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, // message body - (byte) 0, (byte) 0 // message boundary - ); + (short) 5, + (byte) 1, + (byte) 2, + (byte) 3, + (byte) 4, + (byte) 5, // message body + (byte) 0, + (byte) 0 // message boundary + ); } @Test - void shouldSupportByteArraysByDefault() - { - OutboundMessageHandler handler = newHandler( new MessageFormatV3() ); - channel.pipeline().addLast( handler ); + void shouldSupportByteArraysByDefault() { + OutboundMessageHandler handler = newHandler(new MessageFormatV3()); + channel.pipeline().addLast(handler); - Map params = new HashMap<>(); - params.put( "array", value( new byte[]{1, 2, 3} ) ); + Map params = new HashMap<>(); + params.put("array", value(new byte[] {1, 2, 3})); - assertTrue( channel.writeOutbound( new Query( "RETURN 1", Values.value( params ) ) ) ); - assertTrue( channel.finish() ); + assertTrue(channel.writeOutbound(new Query("RETURN 1", Values.value(params)))); + assertTrue(channel.finish()); } - private static MessageFormat mockMessageFormatWithWriter( final int... bytesToWrite ) - { - MessageFormat messageFormat = mock( MessageFormat.class ); + private static MessageFormat mockMessageFormatWithWriter(final int... bytesToWrite) { + MessageFormat messageFormat = mock(MessageFormat.class); - when( messageFormat.newWriter( any( PackOutput.class ) ) ).then( invocation -> - { - PackOutput output = invocation.getArgument( 0 ); - return mockWriter( output, bytesToWrite ); - } ); + when(messageFormat.newWriter(any(PackOutput.class))).then(invocation -> { + PackOutput output = invocation.getArgument(0); + return mockWriter(output, bytesToWrite); + }); return messageFormat; } - private static Writer mockWriter( final PackOutput output, final int... bytesToWrite ) throws IOException - { - Writer writer = mock( Writer.class ); + private static Writer mockWriter(final PackOutput output, final int... bytesToWrite) throws IOException { + Writer writer = mock(Writer.class); - doAnswer( invocation -> - { - for ( int b : bytesToWrite ) - { - output.writeByte( (byte) b ); - } - return writer; - } ).when( writer ).write( any( Message.class ) ); + doAnswer(invocation -> { + for (int b : bytesToWrite) { + output.writeByte((byte) b); + } + return writer; + }) + .when(writer) + .write(any(Message.class)); return writer; } - private static OutboundMessageHandler newHandler( MessageFormat messageFormat ) - { - return new OutboundMessageHandler( messageFormat, DEV_NULL_LOGGING ); + private static OutboundMessageHandler newHandler(MessageFormat messageFormat) { + return new OutboundMessageHandler(messageFormat, DEV_NULL_LOGGING); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java index c3caebc761..16d3397c52 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplIT.java @@ -18,15 +18,24 @@ */ package org.neo4j.driver.internal.async.pool; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.util.TestUtil.await; + import io.netty.bootstrap.Bootstrap; +import java.util.Collections; +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.Collections; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.ConnectionSettings; @@ -42,119 +51,104 @@ import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.util.TestUtil.await; - @ParallelizableIT -class ConnectionPoolImplIT -{ +class ConnectionPoolImplIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private ConnectionPoolImpl pool; @BeforeEach - void setUp() throws Exception - { + void setUp() throws Exception { pool = newPool(); } @AfterEach - void tearDown() - { + void tearDown() { pool.close(); } @Test - void shouldAcquireConnectionWhenPoolIsEmpty() - { - Connection connection = await( pool.acquire( neo4j.address() ) ); + void shouldAcquireConnectionWhenPoolIsEmpty() { + Connection connection = await(pool.acquire(neo4j.address())); - assertNotNull( connection ); + assertNotNull(connection); } @Test - void shouldAcquireIdleConnection() - { - Connection connection1 = await( pool.acquire( neo4j.address() ) ); - await( connection1.release() ); + void shouldAcquireIdleConnection() { + Connection connection1 = await(pool.acquire(neo4j.address())); + await(connection1.release()); - Connection connection2 = await( pool.acquire( neo4j.address() ) ); - assertNotNull( connection2 ); + Connection connection2 = await(pool.acquire(neo4j.address())); + assertNotNull(connection2); } @Test - void shouldBeAbleToClosePoolInIOWorkerThread() throws Throwable - { + void shouldBeAbleToClosePoolInIOWorkerThread() throws Throwable { // In the IO worker thread of a channel obtained from a pool, we shall be able to close the pool. - CompletionStage future = pool.acquire( neo4j.address() ).thenCompose( Connection::release ) + CompletionStage future = pool.acquire(neo4j.address()) + .thenCompose(Connection::release) // This shall close all pools - .whenComplete( ( ignored, error ) -> pool.retainAll( Collections.emptySet() ) ); + .whenComplete((ignored, error) -> pool.retainAll(Collections.emptySet())); // We should be able to come to this line. - await( future ); + await(future); } @Test - void shouldFailToAcquireConnectionToWrongAddress() - { - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, - () -> await( pool.acquire( new BoltServerAddress( "wrong-localhost" ) ) ) ); + void shouldFailToAcquireConnectionToWrongAddress() { + ServiceUnavailableException e = assertThrows( + ServiceUnavailableException.class, () -> await(pool.acquire(new BoltServerAddress("wrong-localhost")))); - assertThat( e.getMessage(), startsWith( "Unable to connect" ) ); + assertThat(e.getMessage(), startsWith("Unable to connect")); } @Test - void shouldFailToAcquireWhenPoolClosed() - { - Connection connection = await( pool.acquire( neo4j.address() ) ); - await( connection.release() ); - await( pool.close() ); - - IllegalStateException e = assertThrows( IllegalStateException.class, () -> pool.acquire( neo4j.address() ) ); - assertThat( e.getMessage(), startsWith( "Pool closed" ) ); + void shouldFailToAcquireWhenPoolClosed() { + Connection connection = await(pool.acquire(neo4j.address())); + await(connection.release()); + await(pool.close()); + + IllegalStateException e = assertThrows(IllegalStateException.class, () -> pool.acquire(neo4j.address())); + assertThat(e.getMessage(), startsWith("Pool closed")); } @Test - void shouldNotCloseWhenClosed() - { - assertNull( await( pool.close() ) ); - assertTrue( pool.close().toCompletableFuture().isDone() ); + void shouldNotCloseWhenClosed() { + assertNull(await(pool.close())); + assertTrue(pool.close().toCompletableFuture().isDone()); } @Test - void shouldFailToAcquireConnectionWhenPoolIsClosed() - { - await( pool.acquire( neo4j.address() ) ); - ExtendedChannelPool channelPool = this.pool.getPool( neo4j.address() ); - await( channelPool.close() ); + void shouldFailToAcquireConnectionWhenPoolIsClosed() { + await(pool.acquire(neo4j.address())); + ExtendedChannelPool channelPool = this.pool.getPool(neo4j.address()); + await(channelPool.close()); ServiceUnavailableException error = - assertThrows( ServiceUnavailableException.class, () -> await( pool.acquire( neo4j.address() ) ) ); - assertThat( error.getMessage(), containsString( "closed while acquiring a connection" ) ); - assertThat( error.getCause(), instanceOf( IllegalStateException.class ) ); - assertThat( error.getCause().getMessage(), containsString( "FixedChannelPool was closed" ) ); + assertThrows(ServiceUnavailableException.class, () -> await(pool.acquire(neo4j.address()))); + assertThat(error.getMessage(), containsString("closed while acquiring a connection")); + assertThat(error.getCause(), instanceOf(IllegalStateException.class)); + assertThat(error.getCause().getMessage(), containsString("FixedChannelPool was closed")); } - private ConnectionPoolImpl newPool() throws Exception - { + private ConnectionPoolImpl newPool() throws Exception { FakeClock clock = new FakeClock(); - ConnectionSettings connectionSettings = new ConnectionSettings( neo4j.authToken(), "test", 5000 ); - ChannelConnector connector = new ChannelConnectorImpl( connectionSettings, SecurityPlanImpl.insecure(), - DEV_NULL_LOGGING, clock, RoutingContext.EMPTY, DefaultDomainNameResolver.getInstance() ); + ConnectionSettings connectionSettings = new ConnectionSettings(neo4j.authToken(), "test", 5000); + ChannelConnector connector = new ChannelConnectorImpl( + connectionSettings, + SecurityPlanImpl.insecure(), + DEV_NULL_LOGGING, + clock, + RoutingContext.EMPTY, + DefaultDomainNameResolver.getInstance()); PoolSettings poolSettings = newSettings(); - Bootstrap bootstrap = BootstrapFactory.newBootstrap( 1 ); - return new ConnectionPoolImpl( connector, bootstrap, poolSettings, DevNullMetricsListener.INSTANCE, DEV_NULL_LOGGING, clock, true ); + Bootstrap bootstrap = BootstrapFactory.newBootstrap(1); + return new ConnectionPoolImpl( + connector, bootstrap, poolSettings, DevNullMetricsListener.INSTANCE, DEV_NULL_LOGGING, clock, true); } - private static PoolSettings newSettings() - { - return new PoolSettings( 10, 5000, -1, -1 ); + + private static PoolSettings newSettings() { + return new PoolSettings(10, 5000, -1, -1); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplTest.java index b49d6bec82..993e1d167d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImplTest.java @@ -18,18 +18,6 @@ */ package org.neo4j.driver.internal.async.pool; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import java.util.HashSet; -import java.util.concurrent.ExecutionException; - -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.metrics.DevNullMetricsListener; -import org.neo4j.driver.internal.util.FakeClock; - import static java.util.Arrays.asList; import static java.util.Collections.singleton; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -43,109 +31,116 @@ import static org.neo4j.driver.internal.async.connection.ChannelAttributes.authorizationStateListener; import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -class ConnectionPoolImplTest -{ - private static final BoltServerAddress ADDRESS_1 = new BoltServerAddress( "server:1" ); - private static final BoltServerAddress ADDRESS_2 = new BoltServerAddress( "server:2" ); - private static final BoltServerAddress ADDRESS_3 = new BoltServerAddress( "server:3" ); +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import java.util.HashSet; +import java.util.concurrent.ExecutionException; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.metrics.DevNullMetricsListener; +import org.neo4j.driver.internal.util.FakeClock; + +class ConnectionPoolImplTest { + private static final BoltServerAddress ADDRESS_1 = new BoltServerAddress("server:1"); + private static final BoltServerAddress ADDRESS_2 = new BoltServerAddress("server:2"); + private static final BoltServerAddress ADDRESS_3 = new BoltServerAddress("server:3"); @Test - void shouldDoNothingWhenRetainOnEmptyPool() - { - NettyChannelTracker nettyChannelTracker = mock( NettyChannelTracker.class ); - TestConnectionPool pool = newConnectionPool( nettyChannelTracker ); + void shouldDoNothingWhenRetainOnEmptyPool() { + NettyChannelTracker nettyChannelTracker = mock(NettyChannelTracker.class); + TestConnectionPool pool = newConnectionPool(nettyChannelTracker); - pool.retainAll( singleton( LOCAL_DEFAULT ) ); + pool.retainAll(singleton(LOCAL_DEFAULT)); - verifyNoInteractions( nettyChannelTracker ); + verifyNoInteractions(nettyChannelTracker); } @Test - void shouldRetainSpecifiedAddresses() - { - NettyChannelTracker nettyChannelTracker = mock( NettyChannelTracker.class ); - TestConnectionPool pool = newConnectionPool( nettyChannelTracker ); - - pool.acquire( ADDRESS_1 ); - pool.acquire( ADDRESS_2 ); - pool.acquire( ADDRESS_3 ); - - pool.retainAll( new HashSet<>( asList( ADDRESS_1, ADDRESS_2, ADDRESS_3 ) ) ); - for ( ExtendedChannelPool channelPool : pool.channelPoolsByAddress.values() ) - { - assertFalse( channelPool.isClosed() ); + void shouldRetainSpecifiedAddresses() { + NettyChannelTracker nettyChannelTracker = mock(NettyChannelTracker.class); + TestConnectionPool pool = newConnectionPool(nettyChannelTracker); + + pool.acquire(ADDRESS_1); + pool.acquire(ADDRESS_2); + pool.acquire(ADDRESS_3); + + pool.retainAll(new HashSet<>(asList(ADDRESS_1, ADDRESS_2, ADDRESS_3))); + for (ExtendedChannelPool channelPool : pool.channelPoolsByAddress.values()) { + assertFalse(channelPool.isClosed()); } } @Test - void shouldClosePoolsWhenRetaining() - { - NettyChannelTracker nettyChannelTracker = mock( NettyChannelTracker.class ); - TestConnectionPool pool = newConnectionPool( nettyChannelTracker ); - - pool.acquire( ADDRESS_1 ); - pool.acquire( ADDRESS_2 ); - pool.acquire( ADDRESS_3 ); - - when( nettyChannelTracker.inUseChannelCount( ADDRESS_1 ) ).thenReturn( 2 ); - when( nettyChannelTracker.inUseChannelCount( ADDRESS_2 ) ).thenReturn( 0 ); - when( nettyChannelTracker.inUseChannelCount( ADDRESS_3 ) ).thenReturn( 3 ); - - pool.retainAll( new HashSet<>( asList( ADDRESS_1, ADDRESS_3 ) ) ); - assertFalse( pool.getPool( ADDRESS_1 ).isClosed() ); - assertTrue( pool.getPool( ADDRESS_2 ).isClosed() ); - assertFalse( pool.getPool( ADDRESS_3 ).isClosed() ); + void shouldClosePoolsWhenRetaining() { + NettyChannelTracker nettyChannelTracker = mock(NettyChannelTracker.class); + TestConnectionPool pool = newConnectionPool(nettyChannelTracker); + + pool.acquire(ADDRESS_1); + pool.acquire(ADDRESS_2); + pool.acquire(ADDRESS_3); + + when(nettyChannelTracker.inUseChannelCount(ADDRESS_1)).thenReturn(2); + when(nettyChannelTracker.inUseChannelCount(ADDRESS_2)).thenReturn(0); + when(nettyChannelTracker.inUseChannelCount(ADDRESS_3)).thenReturn(3); + + pool.retainAll(new HashSet<>(asList(ADDRESS_1, ADDRESS_3))); + assertFalse(pool.getPool(ADDRESS_1).isClosed()); + assertTrue(pool.getPool(ADDRESS_2).isClosed()); + assertFalse(pool.getPool(ADDRESS_3).isClosed()); } @Test - void shouldNotClosePoolsWithActiveConnectionsWhenRetaining() - { - NettyChannelTracker nettyChannelTracker = mock( NettyChannelTracker.class ); - TestConnectionPool pool = newConnectionPool( nettyChannelTracker ); - - pool.acquire( ADDRESS_1 ); - pool.acquire( ADDRESS_2 ); - pool.acquire( ADDRESS_3 ); - - when( nettyChannelTracker.inUseChannelCount( ADDRESS_1 ) ).thenReturn( 1 ); - when( nettyChannelTracker.inUseChannelCount( ADDRESS_2 ) ).thenReturn( 42 ); - when( nettyChannelTracker.inUseChannelCount( ADDRESS_3 ) ).thenReturn( 0 ); - - pool.retainAll( singleton( ADDRESS_2 ) ); - assertFalse( pool.getPool( ADDRESS_1 ).isClosed() ); - assertFalse( pool.getPool( ADDRESS_2 ).isClosed() ); - assertTrue( pool.getPool( ADDRESS_3 ).isClosed() ); + void shouldNotClosePoolsWithActiveConnectionsWhenRetaining() { + NettyChannelTracker nettyChannelTracker = mock(NettyChannelTracker.class); + TestConnectionPool pool = newConnectionPool(nettyChannelTracker); + + pool.acquire(ADDRESS_1); + pool.acquire(ADDRESS_2); + pool.acquire(ADDRESS_3); + + when(nettyChannelTracker.inUseChannelCount(ADDRESS_1)).thenReturn(1); + when(nettyChannelTracker.inUseChannelCount(ADDRESS_2)).thenReturn(42); + when(nettyChannelTracker.inUseChannelCount(ADDRESS_3)).thenReturn(0); + + pool.retainAll(singleton(ADDRESS_2)); + assertFalse(pool.getPool(ADDRESS_1).isClosed()); + assertFalse(pool.getPool(ADDRESS_2).isClosed()); + assertTrue(pool.getPool(ADDRESS_3).isClosed()); } @Test - void shouldRegisterAuthorizationStateListenerWithChannel() throws ExecutionException, InterruptedException - { - NettyChannelTracker nettyChannelTracker = mock( NettyChannelTracker.class ); - NettyChannelHealthChecker nettyChannelHealthChecker = mock( NettyChannelHealthChecker.class ); - ArgumentCaptor channelArgumentCaptor = ArgumentCaptor.forClass( Channel.class ); - TestConnectionPool pool = newConnectionPool( nettyChannelTracker, nettyChannelHealthChecker ); - - pool.acquire( ADDRESS_1 ).toCompletableFuture().get(); - verify( nettyChannelTracker ).channelAcquired( channelArgumentCaptor.capture() ); + void shouldRegisterAuthorizationStateListenerWithChannel() throws ExecutionException, InterruptedException { + NettyChannelTracker nettyChannelTracker = mock(NettyChannelTracker.class); + NettyChannelHealthChecker nettyChannelHealthChecker = mock(NettyChannelHealthChecker.class); + ArgumentCaptor channelArgumentCaptor = ArgumentCaptor.forClass(Channel.class); + TestConnectionPool pool = newConnectionPool(nettyChannelTracker, nettyChannelHealthChecker); + + pool.acquire(ADDRESS_1).toCompletableFuture().get(); + verify(nettyChannelTracker).channelAcquired(channelArgumentCaptor.capture()); Channel channel = channelArgumentCaptor.getValue(); - assertEquals( nettyChannelHealthChecker, authorizationStateListener( channel ) ); + assertEquals(nettyChannelHealthChecker, authorizationStateListener(channel)); } - private static PoolSettings newSettings() - { - return new PoolSettings( 10, 5000, -1, -1 ); + private static PoolSettings newSettings() { + return new PoolSettings(10, 5000, -1, -1); } - private static TestConnectionPool newConnectionPool( NettyChannelTracker nettyChannelTracker ) - { - return newConnectionPool( nettyChannelTracker, mock( NettyChannelHealthChecker.class ) ); + private static TestConnectionPool newConnectionPool(NettyChannelTracker nettyChannelTracker) { + return newConnectionPool(nettyChannelTracker, mock(NettyChannelHealthChecker.class)); } - private static TestConnectionPool newConnectionPool( NettyChannelTracker nettyChannelTracker, NettyChannelHealthChecker nettyChannelHealthChecker ) - { - return new TestConnectionPool( mock( Bootstrap.class ), nettyChannelTracker, nettyChannelHealthChecker, newSettings(), DevNullMetricsListener.INSTANCE, - DEV_NULL_LOGGING, - new FakeClock(), true ); + private static TestConnectionPool newConnectionPool( + NettyChannelTracker nettyChannelTracker, NettyChannelHealthChecker nettyChannelHealthChecker) { + return new TestConnectionPool( + mock(Bootstrap.class), + nettyChannelTracker, + nettyChannelHealthChecker, + newSettings(), + DevNullMetricsListener.INSTANCE, + DEV_NULL_LOGGING, + new FakeClock(), + true); } } 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 5c56a046c4..4c1855c20b 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 @@ -18,25 +18,6 @@ */ package org.neo4j.driver.internal.async.pool; -import io.netty.channel.Channel; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.util.concurrent.Future; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import org.neo4j.driver.Value; -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; - import static org.hamcrest.Matchers.is; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -52,176 +33,192 @@ import static org.neo4j.driver.internal.util.Iterables.single; import static org.neo4j.driver.util.TestUtil.await; -class NettyChannelHealthCheckerTest -{ +import io.netty.channel.Channel; +import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.util.concurrent.Future; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +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(); - private final InboundMessageDispatcher dispatcher = new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ); + private final InboundMessageDispatcher dispatcher = new InboundMessageDispatcher(channel, DEV_NULL_LOGGING); @BeforeEach - void setUp() - { - setMessageDispatcher( channel, dispatcher ); + void setUp() { + setMessageDispatcher(channel, dispatcher); } @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldDropTooOldChannelsWhenMaxLifetimeEnabled() - { + void shouldDropTooOldChannelsWhenMaxLifetimeEnabled() { int maxLifetime = 1000; - PoolSettings settings = new PoolSettings( DEFAULT_MAX_CONNECTION_POOL_SIZE, - DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, maxLifetime, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST ); + PoolSettings settings = new PoolSettings( + DEFAULT_MAX_CONNECTION_POOL_SIZE, + DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, + maxLifetime, + DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); Clock clock = Clock.SYSTEM; - NettyChannelHealthChecker healthChecker = newHealthChecker( settings, clock ); + NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); - setCreationTimestamp( channel, clock.millis() - maxLifetime * 2 ); - Future healthy = healthChecker.isHealthy( channel ); + setCreationTimestamp(channel, clock.millis() - maxLifetime * 2); + Future healthy = healthChecker.isHealthy(channel); - assertThat( await( healthy ), is( false ) ); + assertThat(await(healthy), is(false)); } @Test - void shouldAllowVeryOldChannelsWhenMaxLifetimeDisabled() - { - PoolSettings settings = new PoolSettings( DEFAULT_MAX_CONNECTION_POOL_SIZE, - DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST ); - NettyChannelHealthChecker healthChecker = newHealthChecker( settings, Clock.SYSTEM ); - - setCreationTimestamp( channel, 0 ); - Future healthy = healthChecker.isHealthy( channel ); - - assertThat( await( healthy ), is( true ) ); + void shouldAllowVeryOldChannelsWhenMaxLifetimeDisabled() { + PoolSettings settings = new PoolSettings( + DEFAULT_MAX_CONNECTION_POOL_SIZE, + DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, + NOT_CONFIGURED, + DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); + NettyChannelHealthChecker healthChecker = newHealthChecker(settings, Clock.SYSTEM); + + setCreationTimestamp(channel, 0); + Future healthy = healthChecker.isHealthy(channel); + + assertThat(await(healthy), is(true)); } @Test - void shouldFailAllConnectionsCreatedOnOrBeforeExpirationTimestamp() - { - PoolSettings settings = new PoolSettings( DEFAULT_MAX_CONNECTION_POOL_SIZE, - DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST ); + void shouldFailAllConnectionsCreatedOnOrBeforeExpirationTimestamp() { + PoolSettings settings = new PoolSettings( + DEFAULT_MAX_CONNECTION_POOL_SIZE, + DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, + NOT_CONFIGURED, + DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); Clock clock = Clock.SYSTEM; - NettyChannelHealthChecker healthChecker = newHealthChecker( settings, clock ); + NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); long initialTimestamp = clock.millis(); - List channels = IntStream.range( 0, 100 ).mapToObj( i -> - { - Channel channel = new EmbeddedChannel(); - setCreationTimestamp( channel, initialTimestamp + i ); - return channel; - } ).collect( Collectors.toList() ); + List channels = IntStream.range(0, 100) + .mapToObj(i -> { + Channel channel = new EmbeddedChannel(); + setCreationTimestamp(channel, initialTimestamp + i); + return channel; + }) + .collect(Collectors.toList()); int authorizationExpiredChannelIndex = channels.size() / 2 - 1; - healthChecker.onExpired( new AuthorizationExpiredException( "", "" ), channels.get( authorizationExpiredChannelIndex ) ); + healthChecker.onExpired( + new AuthorizationExpiredException("", ""), channels.get(authorizationExpiredChannelIndex)); - for ( int i = 0; i < channels.size(); i++ ) - { - Channel channel = channels.get( i ); - boolean health = Objects.requireNonNull( await( healthChecker.isHealthy( channel ) ) ); + for (int i = 0; i < channels.size(); i++) { + Channel channel = channels.get(i); + boolean health = Objects.requireNonNull(await(healthChecker.isHealthy(channel))); boolean expectedHealth = i > authorizationExpiredChannelIndex; - assertEquals( expectedHealth, health, String.format( "Channel %d has failed the check", i ) ); + assertEquals(expectedHealth, health, String.format("Channel %d has failed the check", i)); } } @Test - void shouldUseGreatestExpirationTimestamp() - { - PoolSettings settings = new PoolSettings( DEFAULT_MAX_CONNECTION_POOL_SIZE, - DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST ); + void shouldUseGreatestExpirationTimestamp() { + PoolSettings settings = new PoolSettings( + DEFAULT_MAX_CONNECTION_POOL_SIZE, + DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, + NOT_CONFIGURED, + DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); Clock clock = Clock.SYSTEM; - NettyChannelHealthChecker healthChecker = newHealthChecker( settings, clock ); + NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); long initialTimestamp = clock.millis(); Channel channel1 = new EmbeddedChannel(); Channel channel2 = new EmbeddedChannel(); - setCreationTimestamp( channel1, initialTimestamp ); - setCreationTimestamp( channel2, initialTimestamp + 100 ); + setCreationTimestamp(channel1, initialTimestamp); + setCreationTimestamp(channel2, initialTimestamp + 100); - healthChecker.onExpired( new AuthorizationExpiredException( "", "" ), channel2 ); - healthChecker.onExpired( new AuthorizationExpiredException( "", "" ), channel1 ); + healthChecker.onExpired(new AuthorizationExpiredException("", ""), channel2); + healthChecker.onExpired(new AuthorizationExpiredException("", ""), channel1); - assertFalse( Objects.requireNonNull( await( healthChecker.isHealthy( channel1 ) ) ) ); - assertFalse( Objects.requireNonNull( await( healthChecker.isHealthy( channel2 ) ) ) ); + assertFalse(Objects.requireNonNull(await(healthChecker.isHealthy(channel1)))); + assertFalse(Objects.requireNonNull(await(healthChecker.isHealthy(channel2)))); } @Test - void shouldKeepIdleConnectionWhenPingSucceeds() - { - testPing( true ); + void shouldKeepIdleConnectionWhenPingSucceeds() { + testPing(true); } @Test - void shouldDropIdleConnectionWhenPingFails() - { - testPing( false ); + void shouldDropIdleConnectionWhenPingFails() { + testPing(false); } @Test - void shouldKeepActiveConnections() - { - testActiveConnectionCheck( true ); + void shouldKeepActiveConnections() { + testActiveConnectionCheck(true); } @Test - void shouldDropInactiveConnections() - { - testActiveConnectionCheck( false ); + void shouldDropInactiveConnections() { + testActiveConnectionCheck(false); } - private void testPing( boolean resetMessageSuccessful ) - { + private void testPing(boolean resetMessageSuccessful) { int idleTimeBeforeConnectionTest = 1000; - PoolSettings settings = new PoolSettings( DEFAULT_MAX_CONNECTION_POOL_SIZE, - DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, idleTimeBeforeConnectionTest ); + PoolSettings settings = new PoolSettings( + DEFAULT_MAX_CONNECTION_POOL_SIZE, + DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, + NOT_CONFIGURED, + idleTimeBeforeConnectionTest); Clock clock = Clock.SYSTEM; - NettyChannelHealthChecker healthChecker = newHealthChecker( settings, clock ); + NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); - setCreationTimestamp( channel, clock.millis() ); - setLastUsedTimestamp( channel, clock.millis() - idleTimeBeforeConnectionTest * 2 ); + setCreationTimestamp(channel, clock.millis()); + setLastUsedTimestamp(channel, clock.millis() - idleTimeBeforeConnectionTest * 2); - Future healthy = healthChecker.isHealthy( channel ); + Future healthy = healthChecker.isHealthy(channel); - assertEquals( ResetMessage.RESET, single( channel.outboundMessages() ) ); - assertFalse( healthy.isDone() ); + assertEquals(ResetMessage.RESET, single(channel.outboundMessages())); + assertFalse(healthy.isDone()); - if ( resetMessageSuccessful ) - { - dispatcher.handleSuccessMessage( Collections.emptyMap() ); - assertThat( await( healthy ), is( true ) ); - } - else - { - dispatcher.handleFailureMessage( "Neo.ClientError.General.Unknown", "Error!" ); - assertThat( await( healthy ), is( false ) ); + if (resetMessageSuccessful) { + dispatcher.handleSuccessMessage(Collections.emptyMap()); + assertThat(await(healthy), is(true)); + } else { + dispatcher.handleFailureMessage("Neo.ClientError.General.Unknown", "Error!"); + assertThat(await(healthy), is(false)); } } - private void testActiveConnectionCheck( boolean channelActive ) - { - PoolSettings settings = new PoolSettings( DEFAULT_MAX_CONNECTION_POOL_SIZE, - DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, NOT_CONFIGURED, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST ); + private void testActiveConnectionCheck(boolean channelActive) { + PoolSettings settings = new PoolSettings( + DEFAULT_MAX_CONNECTION_POOL_SIZE, + DEFAULT_CONNECTION_ACQUISITION_TIMEOUT, + NOT_CONFIGURED, + DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST); Clock clock = Clock.SYSTEM; - NettyChannelHealthChecker healthChecker = newHealthChecker( settings, clock ); + NettyChannelHealthChecker healthChecker = newHealthChecker(settings, clock); - setCreationTimestamp( channel, clock.millis() ); + setCreationTimestamp(channel, clock.millis()); - if ( channelActive ) - { - Future healthy = healthChecker.isHealthy( channel ); - assertThat( await( healthy ), is( true ) ); - } - else - { + if (channelActive) { + Future healthy = healthChecker.isHealthy(channel); + assertThat(await(healthy), is(true)); + } else { channel.close().syncUninterruptibly(); - Future healthy = healthChecker.isHealthy( channel ); - assertThat( await( healthy ), is( false ) ); + Future healthy = healthChecker.isHealthy(channel); + assertThat(await(healthy), is(false)); } } - private NettyChannelHealthChecker newHealthChecker( PoolSettings settings, Clock clock ) - { - return new NettyChannelHealthChecker( settings, clock, DEV_NULL_LOGGING ); + private NettyChannelHealthChecker newHealthChecker(PoolSettings settings, Clock clock) { + return new NettyChannelHealthChecker(settings, clock, DEV_NULL_LOGGING); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java index 63af5b70a2..ea974d06fd 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelPoolIT.java @@ -18,18 +18,28 @@ */ package org.neo4j.driver.internal.async.pool; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.util.TestUtil.await; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.pool.ChannelHealthChecker; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeoutException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeoutException; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Value; @@ -48,21 +58,8 @@ import org.neo4j.driver.util.Neo4jRunner; import org.neo4j.driver.util.ParallelizableIT; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.util.TestUtil.await; - @ParallelizableIT -class NettyChannelPoolIT -{ +class NettyChannelPoolIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @@ -71,132 +68,123 @@ class NettyChannelPoolIT private NettyChannelPool pool; @BeforeEach - void setUp() - { - bootstrap = BootstrapFactory.newBootstrap( 1 ); - poolHandler = mock( NettyChannelTracker.class ); + void setUp() { + bootstrap = BootstrapFactory.newBootstrap(1); + poolHandler = mock(NettyChannelTracker.class); } @AfterEach - void tearDown() - { - if ( pool != null ) - { + void tearDown() { + if (pool != null) { pool.close(); } - if ( bootstrap != null ) - { + if (bootstrap != null) { bootstrap.config().group().shutdownGracefully().syncUninterruptibly(); } } @Test - void shouldAcquireAndReleaseWithCorrectCredentials() throws Exception - { - pool = newPool( neo4j.authToken() ); + void shouldAcquireAndReleaseWithCorrectCredentials() throws Exception { + pool = newPool(neo4j.authToken()); - Channel channel = await( pool.acquire() ); - assertNotNull( channel ); - verify( poolHandler ).channelCreated( eq( channel ), any() ); - verify( poolHandler, never() ).channelReleased( channel ); + Channel channel = await(pool.acquire()); + assertNotNull(channel); + verify(poolHandler).channelCreated(eq(channel), any()); + verify(poolHandler, never()).channelReleased(channel); - await( pool.release( channel ) ); - verify( poolHandler ).channelReleased( channel ); + await(pool.release(channel)); + verify(poolHandler).channelReleased(channel); } @Test - void shouldFailToAcquireWithWrongCredentials() throws Exception - { - pool = newPool( AuthTokens.basic( "wrong", "wrong" ) ); + void shouldFailToAcquireWithWrongCredentials() throws Exception { + pool = newPool(AuthTokens.basic("wrong", "wrong")); - assertThrows( AuthenticationException.class, () -> await( pool.acquire() ) ); + assertThrows(AuthenticationException.class, () -> await(pool.acquire())); - verify( poolHandler, never() ).channelCreated( any() ); - verify( poolHandler, never() ).channelReleased( any() ); + verify(poolHandler, never()).channelCreated(any()); + verify(poolHandler, never()).channelReleased(any()); } @Test - void shouldAllowAcquireAfterFailures() throws Exception - { + void shouldAllowAcquireAfterFailures() throws Exception { int maxConnections = 2; - Map authTokenMap = new HashMap<>(); - authTokenMap.put( "scheme", value( "basic" ) ); - authTokenMap.put( "principal", value( "neo4j" ) ); - authTokenMap.put( "credentials", value( "wrong" ) ); - InternalAuthToken authToken = new InternalAuthToken( authTokenMap ); + Map authTokenMap = new HashMap<>(); + authTokenMap.put("scheme", value("basic")); + authTokenMap.put("principal", value("neo4j")); + authTokenMap.put("credentials", value("wrong")); + InternalAuthToken authToken = new InternalAuthToken(authTokenMap); - pool = newPool( authToken, maxConnections ); + pool = newPool(authToken, maxConnections); - for ( int i = 0; i < maxConnections; i++ ) - { - AuthenticationException e = assertThrows( AuthenticationException.class, () -> acquire( pool ) ); + for (int i = 0; i < maxConnections; i++) { + AuthenticationException e = assertThrows(AuthenticationException.class, () -> acquire(pool)); } - authTokenMap.put( "credentials", value( Neo4jRunner.PASSWORD ) ); + authTokenMap.put("credentials", value(Neo4jRunner.PASSWORD)); - assertNotNull( acquire( pool ) ); + assertNotNull(acquire(pool)); } @Test - void shouldLimitNumberOfConcurrentConnections() throws Exception - { + void shouldLimitNumberOfConcurrentConnections() throws Exception { int maxConnections = 5; - pool = newPool( neo4j.authToken(), maxConnections ); + pool = newPool(neo4j.authToken(), maxConnections); - for ( int i = 0; i < maxConnections; i++ ) - { - assertNotNull( acquire( pool ) ); + for (int i = 0; i < maxConnections; i++) { + assertNotNull(acquire(pool)); } - TimeoutException e = assertThrows( TimeoutException.class, () -> acquire( pool ) ); - assertEquals( e.getMessage(), "Acquire operation took longer then configured maximum time" ); + TimeoutException e = assertThrows(TimeoutException.class, () -> acquire(pool)); + assertEquals(e.getMessage(), "Acquire operation took longer then configured maximum time"); } @Test - void shouldTrackActiveChannels() throws Exception - { - NettyChannelTracker tracker = new NettyChannelTracker( DevNullMetricsListener.INSTANCE, new ImmediateSchedulingEventExecutor(), DEV_NULL_LOGGING ); + void shouldTrackActiveChannels() throws Exception { + NettyChannelTracker tracker = new NettyChannelTracker( + DevNullMetricsListener.INSTANCE, new ImmediateSchedulingEventExecutor(), DEV_NULL_LOGGING); poolHandler = tracker; - pool = newPool( neo4j.authToken() ); + pool = newPool(neo4j.authToken()); - Channel channel1 = acquire( pool ); - Channel channel2 = acquire( pool ); - Channel channel3 = acquire( pool ); - assertEquals( 3, tracker.inUseChannelCount( neo4j.address() ) ); + Channel channel1 = acquire(pool); + Channel channel2 = acquire(pool); + Channel channel3 = acquire(pool); + assertEquals(3, tracker.inUseChannelCount(neo4j.address())); - release( channel1 ); - release( channel2 ); - release( channel3 ); - assertEquals( 0, tracker.inUseChannelCount( neo4j.address() ) ); + release(channel1); + release(channel2); + release(channel3); + assertEquals(0, tracker.inUseChannelCount(neo4j.address())); - assertNotNull( acquire( pool ) ); - assertNotNull( acquire( pool ) ); - assertEquals( 2, tracker.inUseChannelCount( neo4j.address() ) ); + assertNotNull(acquire(pool)); + assertNotNull(acquire(pool)); + assertEquals(2, tracker.inUseChannelCount(neo4j.address())); } - private NettyChannelPool newPool( AuthToken authToken ) - { - return newPool( authToken, 100 ); + private NettyChannelPool newPool(AuthToken authToken) { + return newPool(authToken, 100); } - private NettyChannelPool newPool( AuthToken authToken, int maxConnections ) - { - ConnectionSettings settings = new ConnectionSettings( authToken, "test", 5_000 ); - ChannelConnectorImpl connector = new ChannelConnectorImpl( settings, SecurityPlanImpl.insecure(), DEV_NULL_LOGGING, - new FakeClock(), RoutingContext.EMPTY, DefaultDomainNameResolver.getInstance() ); - return new NettyChannelPool( neo4j.address(), connector, bootstrap, poolHandler, ChannelHealthChecker.ACTIVE, - 1_000, maxConnections ); + private NettyChannelPool newPool(AuthToken authToken, int maxConnections) { + ConnectionSettings settings = new ConnectionSettings(authToken, "test", 5_000); + ChannelConnectorImpl connector = new ChannelConnectorImpl( + settings, + SecurityPlanImpl.insecure(), + DEV_NULL_LOGGING, + new FakeClock(), + RoutingContext.EMPTY, + DefaultDomainNameResolver.getInstance()); + return new NettyChannelPool( + neo4j.address(), connector, bootstrap, poolHandler, ChannelHealthChecker.ACTIVE, 1_000, maxConnections); } - private static Channel acquire( NettyChannelPool pool ) throws Exception - { - return await( pool.acquire() ); + private static Channel acquire(NettyChannelPool pool) throws Exception { + return await(pool.acquire()); } - private void release( Channel channel ) throws Exception - { - await( pool.release( channel ) ); + private void release(Channel channel) throws Exception { + await(pool.release(channel)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelTrackerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelTrackerTest.java index 70612084e4..b86e56a23e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelTrackerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/NettyChannelTrackerTest.java @@ -18,18 +18,6 @@ */ package org.neo4j.driver.internal.async.pool; -import io.netty.channel.Channel; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.channel.group.ChannelGroup; -import org.bouncycastle.util.Arrays; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; -import org.neo4j.driver.internal.messaging.request.GoodbyeMessage; -import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; -import org.neo4j.driver.internal.metrics.DevNullMetricsListener; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; @@ -43,204 +31,201 @@ import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerAddress; import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -class NettyChannelTrackerTest -{ +import io.netty.channel.Channel; +import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.channel.group.ChannelGroup; +import org.bouncycastle.util.Arrays; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; +import org.neo4j.driver.internal.messaging.request.GoodbyeMessage; +import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; +import org.neo4j.driver.internal.metrics.DevNullMetricsListener; + +class NettyChannelTrackerTest { private final BoltServerAddress address = BoltServerAddress.LOCAL_DEFAULT; - private final NettyChannelTracker tracker = new NettyChannelTracker( DevNullMetricsListener.INSTANCE, mock( ChannelGroup.class ), DEV_NULL_LOGGING ); + private final NettyChannelTracker tracker = + new NettyChannelTracker(DevNullMetricsListener.INSTANCE, mock(ChannelGroup.class), DEV_NULL_LOGGING); @Test - void shouldIncrementIdleCountWhenChannelCreated() - { + void shouldIncrementIdleCountWhenChannelCreated() { Channel channel = newChannel(); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); - tracker.channelCreated( channel, null ); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 1, tracker.idleChannelCount( address ) ); + tracker.channelCreated(channel, null); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(1, tracker.idleChannelCount(address)); } @Test - void shouldIncrementInUseCountWhenChannelAcquired() - { + void shouldIncrementInUseCountWhenChannelAcquired() { Channel channel = newChannel(); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); - tracker.channelCreated( channel, null ); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 1, tracker.idleChannelCount( address ) ); + tracker.channelCreated(channel, null); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(1, tracker.idleChannelCount(address)); - tracker.channelAcquired( channel ); - assertEquals( 1, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + tracker.channelAcquired(channel); + assertEquals(1, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); } @Test - void shouldIncrementIdleCountWhenChannelReleased() - { + void shouldIncrementIdleCountWhenChannelReleased() { Channel channel = newChannel(); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); - channelCreatedAndAcquired( channel ); - assertEquals( 1, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + channelCreatedAndAcquired(channel); + assertEquals(1, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); - tracker.channelReleased( channel ); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 1, tracker.idleChannelCount( address ) ); + tracker.channelReleased(channel); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(1, tracker.idleChannelCount(address)); } @Test - void shouldIncrementIdleCountForAddress() - { + void shouldIncrementIdleCountForAddress() { Channel channel1 = newChannel(); Channel channel2 = newChannel(); Channel channel3 = newChannel(); - assertEquals( 0, tracker.idleChannelCount( address ) ); - tracker.channelCreated( channel1, null ); - assertEquals( 1, tracker.idleChannelCount( address ) ); - tracker.channelCreated( channel2, null ); - assertEquals( 2, tracker.idleChannelCount( address ) ); - tracker.channelCreated( channel3, null ); - assertEquals( 3, tracker.idleChannelCount( address ) ); - assertEquals( 0, tracker.inUseChannelCount( address ) ); + assertEquals(0, tracker.idleChannelCount(address)); + tracker.channelCreated(channel1, null); + assertEquals(1, tracker.idleChannelCount(address)); + tracker.channelCreated(channel2, null); + assertEquals(2, tracker.idleChannelCount(address)); + tracker.channelCreated(channel3, null); + assertEquals(3, tracker.idleChannelCount(address)); + assertEquals(0, tracker.inUseChannelCount(address)); } @Test - void shouldDecrementCountForAddress() - { + void shouldDecrementCountForAddress() { Channel channel1 = newChannel(); Channel channel2 = newChannel(); Channel channel3 = newChannel(); - channelCreatedAndAcquired( channel1 ); - channelCreatedAndAcquired( channel2 ); - channelCreatedAndAcquired( channel3 ); - assertEquals( 3, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); - - tracker.channelReleased( channel1 ); - assertEquals( 2, tracker.inUseChannelCount( address ) ); - assertEquals( 1, tracker.idleChannelCount( address ) ); - tracker.channelReleased( channel2 ); - assertEquals( 1, tracker.inUseChannelCount( address ) ); - assertEquals( 2, tracker.idleChannelCount( address ) ); - tracker.channelReleased( channel3 ); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 3, tracker.idleChannelCount( address ) ); + channelCreatedAndAcquired(channel1); + channelCreatedAndAcquired(channel2); + channelCreatedAndAcquired(channel3); + assertEquals(3, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); + + tracker.channelReleased(channel1); + assertEquals(2, tracker.inUseChannelCount(address)); + assertEquals(1, tracker.idleChannelCount(address)); + tracker.channelReleased(channel2); + assertEquals(1, tracker.inUseChannelCount(address)); + assertEquals(2, tracker.idleChannelCount(address)); + tracker.channelReleased(channel3); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(3, tracker.idleChannelCount(address)); } @Test - void shouldDecreaseIdleWhenClosedOutsidePool() throws Throwable - { + void shouldDecreaseIdleWhenClosedOutsidePool() throws Throwable { // Given Channel channel = newChannel(); - channelCreatedAndAcquired( channel ); - assertEquals( 1, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + channelCreatedAndAcquired(channel); + assertEquals(1, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); // When closed before session.close channel.close().sync(); // Then - assertEquals( 1, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + assertEquals(1, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); - tracker.channelReleased( channel ); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + tracker.channelReleased(channel); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); } @Test - void shouldDecreaseIdleWhenClosedInsidePool() throws Throwable - { + void shouldDecreaseIdleWhenClosedInsidePool() throws Throwable { // Given Channel channel = newChannel(); - channelCreatedAndAcquired( channel ); - assertEquals( 1, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + channelCreatedAndAcquired(channel); + assertEquals(1, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); - tracker.channelReleased( channel ); - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 1, tracker.idleChannelCount( address ) ); + tracker.channelReleased(channel); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(1, tracker.idleChannelCount(address)); // When closed before acquire channel.close().sync(); // Then - assertEquals( 0, tracker.inUseChannelCount( address ) ); - assertEquals( 0, tracker.idleChannelCount( address ) ); + assertEquals(0, tracker.inUseChannelCount(address)); + assertEquals(0, tracker.idleChannelCount(address)); } @Test - void shouldThrowWhenDecrementingForUnknownAddress() - { + void shouldThrowWhenDecrementingForUnknownAddress() { Channel channel = newChannel(); - assertThrows( IllegalStateException.class, () -> tracker.channelReleased( channel ) ); + assertThrows(IllegalStateException.class, () -> tracker.channelReleased(channel)); } @Test - void shouldReturnZeroActiveCountForUnknownAddress() - { - assertEquals( 0, tracker.inUseChannelCount( address ) ); + void shouldReturnZeroActiveCountForUnknownAddress() { + assertEquals(0, tracker.inUseChannelCount(address)); } @Test - void shouldAddChannelToGroupWhenChannelCreated() - { + void shouldAddChannelToGroupWhenChannelCreated() { Channel channel = newChannel(); Channel anotherChannel = newChannel(); - ChannelGroup group = mock( ChannelGroup.class ); - NettyChannelTracker tracker = new NettyChannelTracker( DevNullMetricsListener.INSTANCE, group, DEV_NULL_LOGGING ); + ChannelGroup group = mock(ChannelGroup.class); + NettyChannelTracker tracker = new NettyChannelTracker(DevNullMetricsListener.INSTANCE, group, DEV_NULL_LOGGING); - tracker.channelCreated( channel, null ); - tracker.channelCreated( anotherChannel, null ); + tracker.channelCreated(channel, null); + tracker.channelCreated(anotherChannel, null); - verify( group ).add( channel ); - verify( group ).add( anotherChannel ); + verify(group).add(channel); + verify(group).add(anotherChannel); } @Test - void shouldDelegateToProtocolPrepareToClose() - { + void shouldDelegateToProtocolPrepareToClose() { EmbeddedChannel channel = newChannelWithProtocolV3(); EmbeddedChannel anotherChannel = newChannelWithProtocolV3(); - ChannelGroup group = mock( ChannelGroup.class ); - when( group.iterator() ).thenReturn( new Arrays.Iterator<>( new Channel[]{channel, anotherChannel} ) ); + ChannelGroup group = mock(ChannelGroup.class); + when(group.iterator()).thenReturn(new Arrays.Iterator<>(new Channel[] {channel, anotherChannel})); - NettyChannelTracker tracker = new NettyChannelTracker( DevNullMetricsListener.INSTANCE, group, DEV_NULL_LOGGING ); + NettyChannelTracker tracker = new NettyChannelTracker(DevNullMetricsListener.INSTANCE, group, DEV_NULL_LOGGING); tracker.prepareToCloseChannels(); - assertThat( channel.outboundMessages().size(), equalTo( 1 ) ); - assertThat( channel.outboundMessages(), hasItem( GoodbyeMessage.GOODBYE ) ); + assertThat(channel.outboundMessages().size(), equalTo(1)); + assertThat(channel.outboundMessages(), hasItem(GoodbyeMessage.GOODBYE)); - assertThat( anotherChannel.outboundMessages().size(), equalTo( 1 ) ); - assertThat( anotherChannel.outboundMessages(), hasItem( GoodbyeMessage.GOODBYE ) ); + assertThat(anotherChannel.outboundMessages().size(), equalTo(1)); + assertThat(anotherChannel.outboundMessages(), hasItem(GoodbyeMessage.GOODBYE)); } - private Channel newChannel() - { + private Channel newChannel() { EmbeddedChannel channel = new EmbeddedChannel(); - setServerAddress( channel, address ); + setServerAddress(channel, address); return channel; } - private EmbeddedChannel newChannelWithProtocolV3() - { + private EmbeddedChannel newChannelWithProtocolV3() { EmbeddedChannel channel = new EmbeddedChannel(); - setServerAddress( channel, address ); - setProtocolVersion( channel, BoltProtocolV3.VERSION ); - setMessageDispatcher( channel, mock( InboundMessageDispatcher.class ) ); + setServerAddress(channel, address); + setProtocolVersion(channel, BoltProtocolV3.VERSION); + setMessageDispatcher(channel, mock(InboundMessageDispatcher.class)); return channel; } - private void channelCreatedAndAcquired( Channel channel ) - { - tracker.channelCreated( channel, null ); - tracker.channelAcquired( channel ); + private void channelCreatedAndAcquired(Channel channel) { + tracker.channelCreated(channel, null); + tracker.channelAcquired(channel); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/PoolSettingsTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/PoolSettingsTest.java index 22ab904d6f..416fa467e7 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/PoolSettingsTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/PoolSettingsTest.java @@ -18,66 +18,58 @@ */ package org.neo4j.driver.internal.async.pool; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -class PoolSettingsTest -{ +import org.junit.jupiter.api.Test; + +class PoolSettingsTest { @Test - void idleTimeBeforeConnectionTestWhenConfigured() - { - PoolSettings settings = new PoolSettings( 5, -1, 10, 42 ); - assertTrue( settings.idleTimeBeforeConnectionTestEnabled() ); - assertEquals( 42, settings.idleTimeBeforeConnectionTest() ); + void idleTimeBeforeConnectionTestWhenConfigured() { + PoolSettings settings = new PoolSettings(5, -1, 10, 42); + assertTrue(settings.idleTimeBeforeConnectionTestEnabled()); + assertEquals(42, settings.idleTimeBeforeConnectionTest()); } @Test - void idleTimeBeforeConnectionTestWhenSetToZero() - { - //Always test idle time during acquisition - PoolSettings settings = new PoolSettings( 5, -1, 10, 0 ); - assertTrue( settings.idleTimeBeforeConnectionTestEnabled() ); - assertEquals( 0, settings.idleTimeBeforeConnectionTest() ); + void idleTimeBeforeConnectionTestWhenSetToZero() { + // Always test idle time during acquisition + PoolSettings settings = new PoolSettings(5, -1, 10, 0); + assertTrue(settings.idleTimeBeforeConnectionTestEnabled()); + assertEquals(0, settings.idleTimeBeforeConnectionTest()); } @Test - void idleTimeBeforeConnectionTestWhenSetToNegativeValue() - { - //Never test idle time during acquisition - testIdleTimeBeforeConnectionTestWithIllegalValue( -1 ); - testIdleTimeBeforeConnectionTestWithIllegalValue( -42 ); - testIdleTimeBeforeConnectionTestWithIllegalValue( Integer.MIN_VALUE ); + void idleTimeBeforeConnectionTestWhenSetToNegativeValue() { + // Never test idle time during acquisition + testIdleTimeBeforeConnectionTestWithIllegalValue(-1); + testIdleTimeBeforeConnectionTestWithIllegalValue(-42); + testIdleTimeBeforeConnectionTestWithIllegalValue(Integer.MIN_VALUE); } @Test - void maxConnectionLifetimeWhenConfigured() - { - PoolSettings settings = new PoolSettings( 5, -1, 42, 10 ); - assertTrue( settings.maxConnectionLifetimeEnabled() ); - assertEquals( 42, settings.maxConnectionLifetime() ); + void maxConnectionLifetimeWhenConfigured() { + PoolSettings settings = new PoolSettings(5, -1, 42, 10); + assertTrue(settings.maxConnectionLifetimeEnabled()); + assertEquals(42, settings.maxConnectionLifetime()); } @Test - void maxConnectionLifetimeWhenSetToZeroOrNegativeValue() - { - testMaxConnectionLifetimeWithIllegalValue( 0 ); - testMaxConnectionLifetimeWithIllegalValue( -1 ); - testMaxConnectionLifetimeWithIllegalValue( -42 ); - testMaxConnectionLifetimeWithIllegalValue( Integer.MIN_VALUE ); + void maxConnectionLifetimeWhenSetToZeroOrNegativeValue() { + testMaxConnectionLifetimeWithIllegalValue(0); + testMaxConnectionLifetimeWithIllegalValue(-1); + testMaxConnectionLifetimeWithIllegalValue(-42); + testMaxConnectionLifetimeWithIllegalValue(Integer.MIN_VALUE); } - private static void testIdleTimeBeforeConnectionTestWithIllegalValue( int value ) - { - PoolSettings settings = new PoolSettings( 5, -1, 10, value ); - assertFalse( settings.idleTimeBeforeConnectionTestEnabled() ); + private static void testIdleTimeBeforeConnectionTestWithIllegalValue(int value) { + PoolSettings settings = new PoolSettings(5, -1, 10, value); + assertFalse(settings.idleTimeBeforeConnectionTestEnabled()); } - private static void testMaxConnectionLifetimeWithIllegalValue( int value ) - { - PoolSettings settings = new PoolSettings( 5, -1, value, 10 ); - assertFalse( settings.maxConnectionLifetimeEnabled() ); + private static void testMaxConnectionLifetimeWithIllegalValue(int value) { + PoolSettings settings = new PoolSettings(5, -1, value, 10); + assertFalse(settings.maxConnectionLifetimeEnabled()); } } 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 d317231aa0..03ab4c022b 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 @@ -18,15 +18,20 @@ */ package org.neo4j.driver.internal.async.pool; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setPoolId; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerAddress; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; + import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.embedded.EmbeddedChannel; - import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicBoolean; - import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.connection.ChannelConnector; @@ -35,89 +40,86 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.Clock; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setPoolId; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setServerAddress; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; - -public class TestConnectionPool extends ConnectionPoolImpl -{ - final Map channelPoolsByAddress = new HashMap<>(); +public class TestConnectionPool extends ConnectionPoolImpl { + final Map channelPoolsByAddress = new HashMap<>(); private final NettyChannelTracker nettyChannelTracker; - public TestConnectionPool( Bootstrap bootstrap, NettyChannelTracker nettyChannelTracker, NettyChannelHealthChecker nettyChannelHealthChecker, - PoolSettings settings, - MetricsListener metricsListener, Logging logging, Clock clock, boolean ownsEventLoopGroup ) - { - super( mock( ChannelConnector.class ), bootstrap, nettyChannelTracker, nettyChannelHealthChecker, settings, metricsListener, logging, clock, - ownsEventLoopGroup, - newConnectionFactory() ); + public TestConnectionPool( + Bootstrap bootstrap, + NettyChannelTracker nettyChannelTracker, + NettyChannelHealthChecker nettyChannelHealthChecker, + PoolSettings settings, + MetricsListener metricsListener, + Logging logging, + Clock clock, + boolean ownsEventLoopGroup) { + super( + mock(ChannelConnector.class), + bootstrap, + nettyChannelTracker, + nettyChannelHealthChecker, + settings, + metricsListener, + logging, + clock, + ownsEventLoopGroup, + newConnectionFactory()); this.nettyChannelTracker = nettyChannelTracker; } - ExtendedChannelPool getPool( BoltServerAddress address ) - { - return channelPoolsByAddress.get( address ); + ExtendedChannelPool getPool(BoltServerAddress address) { + return channelPoolsByAddress.get(address); } @Override - ExtendedChannelPool newPool( BoltServerAddress address ) - { - ExtendedChannelPool channelPool = new ExtendedChannelPool() - { - private final AtomicBoolean isClosed = new AtomicBoolean( false ); + ExtendedChannelPool newPool(BoltServerAddress address) { + ExtendedChannelPool channelPool = new ExtendedChannelPool() { + private final AtomicBoolean isClosed = new AtomicBoolean(false); + @Override - public CompletionStage acquire() - { + public CompletionStage acquire() { EmbeddedChannel channel = new EmbeddedChannel(); - setServerAddress( channel, address ); - setPoolId( channel, id() ); + setServerAddress(channel, address); + setPoolId(channel, id()); - ListenerEvent event = nettyChannelTracker.channelCreating( id() ); - nettyChannelTracker.channelCreated( channel, event ); - nettyChannelTracker.channelAcquired( channel ); + ListenerEvent event = nettyChannelTracker.channelCreating(id()); + nettyChannelTracker.channelCreated(channel, event); + nettyChannelTracker.channelAcquired(channel); - return completedFuture( channel ); + return completedFuture(channel); } @Override - public CompletionStage release( Channel channel ) - { - nettyChannelTracker.channelReleased( channel ); - nettyChannelTracker.channelClosed( channel ); + public CompletionStage release(Channel channel) { + nettyChannelTracker.channelReleased(channel); + nettyChannelTracker.channelClosed(channel); return completedWithNull(); } @Override - public boolean isClosed() - { + public boolean isClosed() { return isClosed.get(); } @Override - public String id() - { + public String id() { return "Pool-" + this.hashCode(); } @Override - public CompletionStage close() - { - isClosed.set( true ); + public CompletionStage close() { + isClosed.set(true); return completedWithNull(); } }; - channelPoolsByAddress.put( address, channelPool ); + channelPoolsByAddress.put(address, channelPool); return channelPool; } - private static ConnectionFactory newConnectionFactory() - { - return ( channel, pool ) -> { - Connection conn = mock( Connection.class ); - when( conn.release() ).thenAnswer( invocation -> pool.release( channel ) ); + private static ConnectionFactory newConnectionFactory() { + return (channel, pool) -> { + Connection conn = mock(Connection.class); + when(conn.release()).thenAnswer(invocation -> pool.release(channel)); return conn; }; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/AbstractRoutingProcedureRunnerTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/AbstractRoutingProcedureRunnerTest.java index 0fe12d5165..b5274b5b31 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/AbstractRoutingProcedureRunnerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/AbstractRoutingProcedureRunnerTest.java @@ -18,15 +18,6 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.concurrent.CompletionStage; - -import org.neo4j.driver.Record; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.internal.spi.Connection; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -40,68 +31,73 @@ import static org.neo4j.driver.internal.util.Futures.failedFuture; import static org.neo4j.driver.util.TestUtil.await; -abstract class AbstractRoutingProcedureRunnerTest -{ +import java.util.List; +import java.util.concurrent.CompletionStage; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Record; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.internal.spi.Connection; + +abstract class AbstractRoutingProcedureRunnerTest { @Test - void shouldReturnFailedResponseOnClientException() - { - ClientException error = new ClientException( "Hi" ); - SingleDatabaseRoutingProcedureRunner runner = singleDatabaseRoutingProcedureRunner( RoutingContext.EMPTY, failedFuture( error ) ); + void shouldReturnFailedResponseOnClientException() { + ClientException error = new ClientException("Hi"); + SingleDatabaseRoutingProcedureRunner runner = + singleDatabaseRoutingProcedureRunner(RoutingContext.EMPTY, failedFuture(error)); - RoutingProcedureResponse response = await( runner.run( connection(), defaultDatabase(), empty(), null ) ); + RoutingProcedureResponse response = await(runner.run(connection(), defaultDatabase(), empty(), null)); - assertFalse( response.isSuccess() ); - assertEquals( error, response.error() ); + assertFalse(response.isSuccess()); + assertEquals(error, response.error()); } @Test - void shouldReturnFailedStageOnError() - { - Exception error = new Exception( "Hi" ); - SingleDatabaseRoutingProcedureRunner runner = singleDatabaseRoutingProcedureRunner( RoutingContext.EMPTY, failedFuture( error ) ); - - Exception e = assertThrows( Exception.class, () -> await( runner.run( connection(), defaultDatabase(), empty(), null ) ) ); - assertEquals( error, e ); + void shouldReturnFailedStageOnError() { + Exception error = new Exception("Hi"); + SingleDatabaseRoutingProcedureRunner runner = + singleDatabaseRoutingProcedureRunner(RoutingContext.EMPTY, failedFuture(error)); + + Exception e = + assertThrows(Exception.class, () -> await(runner.run(connection(), defaultDatabase(), empty(), null))); + assertEquals(error, e); } @Test - void shouldReleaseConnectionOnSuccess() - { - SingleDatabaseRoutingProcedureRunner runner = singleDatabaseRoutingProcedureRunner( RoutingContext.EMPTY ); + void shouldReleaseConnectionOnSuccess() { + SingleDatabaseRoutingProcedureRunner runner = singleDatabaseRoutingProcedureRunner(RoutingContext.EMPTY); Connection connection = connection(); - RoutingProcedureResponse response = await( runner.run( connection, defaultDatabase(), empty(), null ) ); + RoutingProcedureResponse response = await(runner.run(connection, defaultDatabase(), empty(), null)); - assertTrue( response.isSuccess() ); - verify( connection ).release(); + assertTrue(response.isSuccess()); + verify(connection).release(); } @Test - void shouldPropagateReleaseError() - { - SingleDatabaseRoutingProcedureRunner runner = singleDatabaseRoutingProcedureRunner( RoutingContext.EMPTY ); + void shouldPropagateReleaseError() { + SingleDatabaseRoutingProcedureRunner runner = singleDatabaseRoutingProcedureRunner(RoutingContext.EMPTY); - RuntimeException releaseError = new RuntimeException( "Release failed" ); - Connection connection = connection( failedFuture( releaseError ) ); + RuntimeException releaseError = new RuntimeException("Release failed"); + Connection connection = connection(failedFuture(releaseError)); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( runner.run( connection, defaultDatabase(), empty(), null ) ) ); - assertEquals( releaseError, e ); - verify( connection ).release(); + RuntimeException e = assertThrows( + RuntimeException.class, () -> await(runner.run(connection, defaultDatabase(), empty(), null))); + assertEquals(releaseError, e); + verify(connection).release(); } - abstract SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( RoutingContext context ); + abstract SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner(RoutingContext context); - abstract SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( RoutingContext context, CompletionStage> runProcedureResult ); + abstract SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( + RoutingContext context, CompletionStage> runProcedureResult); - static Connection connection() - { - return connection( completedWithNull() ); + static Connection connection() { + return connection(completedWithNull()); } - static Connection connection( CompletionStage releaseStage ) - { - Connection connection = mock( Connection.class ); - when( connection.release() ).thenReturn( releaseStage ); + static Connection connection(CompletionStage releaseStage) { + Connection connection = mock(Connection.class); + when(connection.release()).thenReturn(releaseStage); return connection; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterCompositionTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterCompositionTest.java index 7fe9dc13b9..5c2d849738 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterCompositionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterCompositionTest.java @@ -18,20 +18,6 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.neo4j.driver.Record; -import org.neo4j.driver.Value; -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.InternalRecord; - import static java.util.Arrays.asList; import static org.hamcrest.Matchers.contains; import static org.hamcrest.junit.MatcherAssert.assertThat; @@ -46,200 +32,186 @@ import static org.neo4j.driver.internal.util.ClusterCompositionUtil.E; import static org.neo4j.driver.internal.util.ClusterCompositionUtil.F; -class ClusterCompositionTest -{ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Record; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.InternalRecord; + +class ClusterCompositionTest { @Test - void hasWritersReturnsFalseWhenNoWriters() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses(), addresses( C, D ) ); + void hasWritersReturnsFalseWhenNoWriters() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(), addresses(C, D)); - assertFalse( composition.hasWriters() ); + assertFalse(composition.hasWriters()); } @Test - void hasWritersReturnsTrueWhenSomeWriters() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) ); + void hasWritersReturnsTrueWhenSomeWriters() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(C, D), addresses(E, F)); - assertTrue( composition.hasWriters() ); + assertTrue(composition.hasWriters()); } @Test - void hasRoutersAndReadersReturnsFalseWhenNoRouters() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses() ); + void hasRoutersAndReadersReturnsFalseWhenNoRouters() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(C, D), addresses()); - assertFalse( composition.hasRoutersAndReaders() ); + assertFalse(composition.hasRoutersAndReaders()); } @Test - void hasRoutersAndReadersReturnsFalseWhenNoReaders() - { - ClusterComposition composition = newComposition( 1, addresses(), addresses( A, B ), addresses( C, D ) ); + void hasRoutersAndReadersReturnsFalseWhenNoReaders() { + ClusterComposition composition = newComposition(1, addresses(), addresses(A, B), addresses(C, D)); - assertFalse( composition.hasRoutersAndReaders() ); + assertFalse(composition.hasRoutersAndReaders()); } @Test - void hasRoutersAndReadersWhenSomeReadersAndRouters() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) ); + void hasRoutersAndReadersWhenSomeReadersAndRouters() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(C, D), addresses(E, F)); - assertTrue( composition.hasRoutersAndReaders() ); + assertTrue(composition.hasRoutersAndReaders()); } @Test - void readersWhenEmpty() - { - ClusterComposition composition = newComposition( 1, addresses(), addresses( A, B ), addresses( C, D ) ); + void readersWhenEmpty() { + ClusterComposition composition = newComposition(1, addresses(), addresses(A, B), addresses(C, D)); - assertEquals( 0, composition.readers().size() ); + assertEquals(0, composition.readers().size()); } @Test - void writersWhenEmpty() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses(), addresses( C, D ) ); + void writersWhenEmpty() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(), addresses(C, D)); - assertEquals( 0, composition.writers().size() ); + assertEquals(0, composition.writers().size()); } @Test - void routersWhenEmpty() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses() ); + void routersWhenEmpty() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(C, D), addresses()); - assertEquals( 0, composition.routers().size() ); + assertEquals(0, composition.routers().size()); } @Test - void readersWhenNonEmpty() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) ); + void readersWhenNonEmpty() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(C, D), addresses(E, F)); - assertEquals( addresses( A, B ), composition.readers() ); + assertEquals(addresses(A, B), composition.readers()); } @Test - void writersWhenNonEmpty() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) ); + void writersWhenNonEmpty() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(C, D), addresses(E, F)); - assertEquals( addresses( C, D ), composition.writers() ); + assertEquals(addresses(C, D), composition.writers()); } @Test - void routersWhenNonEmpty() - { - ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) ); + void routersWhenNonEmpty() { + ClusterComposition composition = newComposition(1, addresses(A, B), addresses(C, D), addresses(E, F)); - assertEquals( addresses( E, F ), composition.routers() ); + assertEquals(addresses(E, F), composition.routers()); } @Test - void expirationTimestamp() - { - ClusterComposition composition = newComposition( 42, addresses( A, B ), addresses( C, D ), addresses( E, F ) ); + void expirationTimestamp() { + ClusterComposition composition = newComposition(42, addresses(A, B), addresses(C, D), addresses(E, F)); - assertEquals( 42, composition.expirationTimestamp() ); + assertEquals(42, composition.expirationTimestamp()); } @Test - void parseCorrectRecord() - { + void parseCorrectRecord() { Value[] values = { - value( 42L ), - value( asList( serversEntry( "READ", A, B ), - serversEntry( "WRITE", C, D ), - serversEntry( "ROUTE", E, F ) ) ) + value(42L), + value(asList(serversEntry("READ", A, B), serversEntry("WRITE", C, D), serversEntry("ROUTE", E, F))) }; - Record record = new InternalRecord( asList( "ttl", "servers" ), values ); + Record record = new InternalRecord(asList("ttl", "servers"), values); - ClusterComposition composition = ClusterComposition.parse( record, 0 ); + ClusterComposition composition = ClusterComposition.parse(record, 0); // TTL is received in seconds and is converted to millis - assertEquals( 42_000, composition.expirationTimestamp() ); + assertEquals(42_000, composition.expirationTimestamp()); - assertEquals( addresses( A, B ), composition.readers() ); - assertEquals( addresses( C, D ), composition.writers() ); - assertEquals( addresses( E, F ), composition.routers() ); + assertEquals(addresses(A, B), composition.readers()); + assertEquals(addresses(C, D), composition.writers()); + assertEquals(addresses(E, F), composition.routers()); } @Test - void parsePreservesOrderOfReaders() - { + void parsePreservesOrderOfReaders() { Value[] values = { - value( 42L ), - value( asList( serversEntry( "READ", A, C, E, B, F, D ), - serversEntry( "WRITE" ), - serversEntry( "ROUTE" ) ) ) + value(42L), + value(asList(serversEntry("READ", A, C, E, B, F, D), serversEntry("WRITE"), serversEntry("ROUTE"))) }; - Record record = new InternalRecord( asList( "ttl", "servers" ), values ); + Record record = new InternalRecord(asList("ttl", "servers"), values); - ClusterComposition composition = ClusterComposition.parse( record, 0 ); + ClusterComposition composition = ClusterComposition.parse(record, 0); - assertThat( composition.readers(), contains( A, C, E, B, F, D ) ); - assertEquals( 0, composition.writers().size() ); - assertEquals( 0, composition.routers().size() ); + assertThat(composition.readers(), contains(A, C, E, B, F, D)); + assertEquals(0, composition.writers().size()); + assertEquals(0, composition.routers().size()); } @Test - void parsePreservesOrderOfWriters() - { + void parsePreservesOrderOfWriters() { Value[] values = { - value( 42L ), - value( asList( serversEntry( "READ" ), - serversEntry( "WRITE", C, F, D, A, B, E ), - serversEntry( "ROUTE" ) ) ) + value(42L), + value(asList(serversEntry("READ"), serversEntry("WRITE", C, F, D, A, B, E), serversEntry("ROUTE"))) }; - Record record = new InternalRecord( asList( "ttl", "servers" ), values ); + Record record = new InternalRecord(asList("ttl", "servers"), values); - ClusterComposition composition = ClusterComposition.parse( record, 0 ); + ClusterComposition composition = ClusterComposition.parse(record, 0); - assertEquals( 0, composition.readers().size() ); - assertThat( composition.writers(), contains( C, F, D, A, B, E ) ); - assertEquals( 0, composition.routers().size() ); + assertEquals(0, composition.readers().size()); + assertThat(composition.writers(), contains(C, F, D, A, B, E)); + assertEquals(0, composition.routers().size()); } @Test - void parsePreservesOrderOfRouters() - { + void parsePreservesOrderOfRouters() { Value[] values = { - value( 42L ), - value( asList( serversEntry( "READ" ), - serversEntry( "WRITE" ), - serversEntry( "ROUTE", F, D, A, B, C, E ) ) ) + value(42L), + value(asList(serversEntry("READ"), serversEntry("WRITE"), serversEntry("ROUTE", F, D, A, B, C, E))) }; - Record record = new InternalRecord( asList( "ttl", "servers" ), values ); + Record record = new InternalRecord(asList("ttl", "servers"), values); - ClusterComposition composition = ClusterComposition.parse( record, 0 ); + ClusterComposition composition = ClusterComposition.parse(record, 0); - assertEquals( 0, composition.readers().size() ); - assertEquals( 0, composition.writers().size() ); - assertThat( composition.routers(), contains( F, D, A, B, C, E ) ); + assertEquals(0, composition.readers().size()); + assertEquals(0, composition.writers().size()); + assertThat(composition.routers(), contains(F, D, A, B, C, E)); } - private static ClusterComposition newComposition( long expirationTimestamp, Set readers, - Set writers, Set routers ) - { - return new ClusterComposition( expirationTimestamp, readers, writers, routers, null ); + private static ClusterComposition newComposition( + long expirationTimestamp, + Set readers, + Set writers, + Set routers) { + return new ClusterComposition(expirationTimestamp, readers, writers, routers, null); } - private static Set addresses( BoltServerAddress... elements ) - { - return new LinkedHashSet<>( asList( elements ) ); + private static Set addresses(BoltServerAddress... elements) { + return new LinkedHashSet<>(asList(elements)); } - private static Map serversEntry( String role, BoltServerAddress... addresses ) - { - Map map = new HashMap<>(); - map.put( "role", role ); + private static Map serversEntry(String role, BoltServerAddress... addresses) { + Map map = new HashMap<>(); + map.put("role", role); List addressStrings = new ArrayList<>(); - for ( BoltServerAddress address : addresses ) - { - addressStrings.add( address.toString() ); + for (BoltServerAddress address : addresses) { + addressStrings.add(address.toString()); } - map.put( "addresses", addressStrings ); + map.put("addresses", addressStrings); return map; } } 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 1ddbe7a130..3ef5dd8e9b 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 @@ -18,17 +18,6 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import java.time.Duration; -import java.util.List; - -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.util.Clock; -import org.neo4j.driver.internal.util.FakeClock; - import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.assertArrayEquals; @@ -48,240 +37,233 @@ import static org.neo4j.driver.internal.util.ClusterCompositionUtil.F; import static org.neo4j.driver.internal.util.ClusterCompositionUtil.createClusterComposition; -class ClusterRoutingTableTest -{ +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 { @Test - void shouldReturnStaleIfTtlExpired() - { + void shouldReturnStaleIfTtlExpired() { // Given FakeClock clock = new FakeClock(); - RoutingTable routingTable = newRoutingTable( clock ); + RoutingTable routingTable = newRoutingTable(clock); // When - routingTable.update( createClusterComposition( 1000, - asList( A, B ), asList( C ), asList( D, E ) ) ); - clock.progress( 1234 ); + routingTable.update(createClusterComposition(1000, asList(A, B), asList(C), asList(D, E))); + clock.progress(1234); // Then - assertTrue( routingTable.isStaleFor( READ ) ); - assertTrue( routingTable.isStaleFor( WRITE ) ); + assertTrue(routingTable.isStaleFor(READ)); + assertTrue(routingTable.isStaleFor(WRITE)); } @Test - void shouldReturnStaleIfNoRouter() - { + void shouldReturnStaleIfNoRouter() { // Given RoutingTable routingTable = newRoutingTable(); // When - routingTable.update( createClusterComposition( EMPTY, asList( C ), asList( D, E ) ) ); + routingTable.update(createClusterComposition(EMPTY, asList(C), asList(D, E))); // Then - assertTrue( routingTable.isStaleFor( READ ) ); - assertTrue( routingTable.isStaleFor( WRITE ) ); + assertTrue(routingTable.isStaleFor(READ)); + assertTrue(routingTable.isStaleFor(WRITE)); } @Test - void shouldBeStaleForReadsButNotWritesWhenNoReaders() - { + void shouldBeStaleForReadsButNotWritesWhenNoReaders() { // Given RoutingTable routingTable = newRoutingTable(); // When - routingTable.update( createClusterComposition( asList( A, B ), asList( C ), EMPTY ) ); + routingTable.update(createClusterComposition(asList(A, B), asList(C), EMPTY)); // Then - assertTrue( routingTable.isStaleFor( READ ) ); - assertFalse( routingTable.isStaleFor( WRITE ) ); + assertTrue(routingTable.isStaleFor(READ)); + assertFalse(routingTable.isStaleFor(WRITE)); } @Test - void shouldBeStaleForWritesButNotReadsWhenNoWriters() - { + void shouldBeStaleForWritesButNotReadsWhenNoWriters() { // Given RoutingTable routingTable = newRoutingTable(); // When - routingTable.update( createClusterComposition( asList( A, B ), EMPTY, asList( D, E ) ) ); + routingTable.update(createClusterComposition(asList(A, B), EMPTY, asList(D, E))); // Then - assertFalse( routingTable.isStaleFor( READ ) ); - assertTrue( routingTable.isStaleFor( WRITE ) ); + assertFalse(routingTable.isStaleFor(READ)); + assertTrue(routingTable.isStaleFor(WRITE)); } @Test - void shouldBeNotStaleWithReadersWritersAndRouters() - { + void shouldBeNotStaleWithReadersWritersAndRouters() { // Given RoutingTable routingTable = newRoutingTable(); // When - routingTable.update( createClusterComposition( asList( A, B ), asList( C ), asList( D, E ) ) ); + routingTable.update(createClusterComposition(asList(A, B), asList(C), asList(D, E))); // Then - assertFalse( routingTable.isStaleFor( READ ) ); - assertFalse( routingTable.isStaleFor( WRITE ) ); + assertFalse(routingTable.isStaleFor(READ)); + assertFalse(routingTable.isStaleFor(WRITE)); } @Test - void shouldBeStaleForReadsAndWritesAfterCreation() - { + void shouldBeStaleForReadsAndWritesAfterCreation() { // Given FakeClock clock = new FakeClock(); // When - RoutingTable routingTable = new ClusterRoutingTable( defaultDatabase(), clock, A ); + RoutingTable routingTable = new ClusterRoutingTable(defaultDatabase(), clock, A); // Then - assertTrue( routingTable.isStaleFor( READ ) ); - assertTrue( routingTable.isStaleFor( WRITE ) ); + assertTrue(routingTable.isStaleFor(READ)); + assertTrue(routingTable.isStaleFor(WRITE)); } @ParameterizedTest - @ValueSource( strings = {"Molly", "", "I AM A NAME"} ) - void shouldReturnDatabaseNameCorrectly( String db ) - { + @ValueSource(strings = {"Molly", "", "I AM A NAME"}) + void shouldReturnDatabaseNameCorrectly(String db) { // Given FakeClock clock = new FakeClock(); // When - RoutingTable routingTable = new ClusterRoutingTable( database( db ), clock, A ); + RoutingTable routingTable = new ClusterRoutingTable(database(db), clock, A); // Then - assertEquals( db, routingTable.database().description() ); + assertEquals(db, routingTable.database().description()); } @Test - void shouldContainInitialRouters() - { + void shouldContainInitialRouters() { // Given FakeClock clock = new FakeClock(); // When - RoutingTable routingTable = new ClusterRoutingTable( defaultDatabase(), clock, A, B, C ); + RoutingTable routingTable = new ClusterRoutingTable(defaultDatabase(), clock, A, B, C); // Then - assertArrayEquals( new BoltServerAddress[]{A, B, C}, routingTable.routers().toArray() ); - assertArrayEquals( new BoltServerAddress[0], routingTable.readers().toArray() ); - assertArrayEquals( new BoltServerAddress[0], routingTable.writers().toArray() ); + assertArrayEquals( + new BoltServerAddress[] {A, B, C}, routingTable.routers().toArray()); + assertArrayEquals(new BoltServerAddress[0], routingTable.readers().toArray()); + assertArrayEquals(new BoltServerAddress[0], routingTable.writers().toArray()); } @Test - void shouldPreserveOrderingOfRouters() - { + void shouldPreserveOrderingOfRouters() { ClusterRoutingTable routingTable = newRoutingTable(); - List routers = asList( A, C, D, F, B, E ); + List routers = asList(A, C, D, F, B, E); - routingTable.update( createClusterComposition( routers, EMPTY, EMPTY ) ); + routingTable.update(createClusterComposition(routers, EMPTY, EMPTY)); - assertArrayEquals( new BoltServerAddress[]{A, C, D, F, B, E}, routingTable.routers().toArray() ); + assertArrayEquals( + new BoltServerAddress[] {A, C, D, F, B, E}, + routingTable.routers().toArray()); } @Test - void shouldPreserveOrderingOfWriters() - { + void shouldPreserveOrderingOfWriters() { ClusterRoutingTable routingTable = newRoutingTable(); - List writers = asList( D, F, A, C, E ); + List writers = asList(D, F, A, C, E); - routingTable.update( createClusterComposition( EMPTY, writers, EMPTY ) ); + routingTable.update(createClusterComposition(EMPTY, writers, EMPTY)); - assertArrayEquals( new BoltServerAddress[]{D, F, A, C, E}, routingTable.writers().toArray() ); + assertArrayEquals( + new BoltServerAddress[] {D, F, A, C, E}, routingTable.writers().toArray()); } @Test - void shouldPreserveOrderingOfReaders() - { + void shouldPreserveOrderingOfReaders() { ClusterRoutingTable routingTable = newRoutingTable(); - List readers = asList( B, A, F, C, D ); + List readers = asList(B, A, F, C, D); - routingTable.update( createClusterComposition( EMPTY, EMPTY, readers ) ); + routingTable.update(createClusterComposition(EMPTY, EMPTY, readers)); - assertArrayEquals( new BoltServerAddress[]{B, A, F, C, D}, routingTable.readers().toArray() ); + assertArrayEquals( + new BoltServerAddress[] {B, A, F, C, D}, routingTable.readers().toArray()); } @Test - void shouldTreatOneRouterAsValid() - { + void shouldTreatOneRouterAsValid() { ClusterRoutingTable routingTable = newRoutingTable(); - List routers = singletonList( A ); - List writers = asList( B, C ); - List readers = asList( D, E ); + List routers = singletonList(A); + List writers = asList(B, C); + List readers = asList(D, E); - routingTable.update( createClusterComposition( routers, writers, readers ) ); + routingTable.update(createClusterComposition(routers, writers, readers)); - assertFalse( routingTable.isStaleFor( READ ) ); - assertFalse( routingTable.isStaleFor( WRITE ) ); + assertFalse(routingTable.isStaleFor(READ)); + assertFalse(routingTable.isStaleFor(WRITE)); } @Test - void shouldHaveBeStaleForExpiredTime() throws Throwable - { - ClusterRoutingTable routingTable = newRoutingTable( Clock.SYSTEM ); - assertTrue( routingTable.hasBeenStaleFor( 0 ) ); + void shouldHaveBeStaleForExpiredTime() throws Throwable { + ClusterRoutingTable routingTable = newRoutingTable(Clock.SYSTEM); + assertTrue(routingTable.hasBeenStaleFor(0)); } @Test - void shouldNotHaveBeStaleForUnexpiredTime() throws Throwable - { - ClusterRoutingTable routingTable = newRoutingTable( Clock.SYSTEM ); - assertFalse( routingTable.hasBeenStaleFor( Duration.ofSeconds( 30 ).toMillis() ) ); + void shouldNotHaveBeStaleForUnexpiredTime() throws Throwable { + ClusterRoutingTable routingTable = newRoutingTable(Clock.SYSTEM); + assertFalse(routingTable.hasBeenStaleFor(Duration.ofSeconds(30).toMillis())); } @Test - void shouldDefaultToPreferInitialRouter() throws Throwable - { + void shouldDefaultToPreferInitialRouter() throws Throwable { ClusterRoutingTable routingTable = newRoutingTable(); - assertTrue( routingTable.preferInitialRouter() ); + assertTrue(routingTable.preferInitialRouter()); } @Test - void shouldPreferInitialRouterIfNoWriter() throws Throwable - { + void shouldPreferInitialRouterIfNoWriter() throws Throwable { ClusterRoutingTable routingTable = newRoutingTable(); - routingTable.update( createClusterComposition( EMPTY, EMPTY, EMPTY ) ); - assertTrue( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(EMPTY, EMPTY, EMPTY)); + assertTrue(routingTable.preferInitialRouter()); - routingTable.update( createClusterComposition( singletonList( A ), EMPTY, singletonList( A ) ) ); - assertTrue( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(singletonList(A), EMPTY, singletonList(A))); + assertTrue(routingTable.preferInitialRouter()); - routingTable.update( createClusterComposition( asList( A, B ), EMPTY, asList( A, B ) ) ); - assertTrue( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(asList(A, B), EMPTY, asList(A, B))); + assertTrue(routingTable.preferInitialRouter()); - routingTable.update( createClusterComposition( EMPTY, EMPTY, singletonList( A ) ) ); - assertTrue( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(EMPTY, EMPTY, singletonList(A))); + assertTrue(routingTable.preferInitialRouter()); - routingTable.update( createClusterComposition( singletonList( A ), EMPTY, EMPTY ) ); - assertTrue( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(singletonList(A), EMPTY, EMPTY)); + assertTrue(routingTable.preferInitialRouter()); } @Test - void shouldNotPreferInitialRouterIfHasWriter() throws Throwable - { + void shouldNotPreferInitialRouterIfHasWriter() throws Throwable { ClusterRoutingTable routingTable = newRoutingTable(); - routingTable.update( createClusterComposition( EMPTY, singletonList( A ), EMPTY ) ); - assertFalse( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(EMPTY, singletonList(A), EMPTY)); + assertFalse(routingTable.preferInitialRouter()); - routingTable.update( createClusterComposition( singletonList( A ), singletonList( A ), singletonList( A ) ) ); - assertFalse( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(singletonList(A), singletonList(A), singletonList(A))); + assertFalse(routingTable.preferInitialRouter()); - routingTable.update( createClusterComposition( asList( A, B ), singletonList( A ), asList( A, B ) ) ); - assertFalse( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(asList(A, B), singletonList(A), asList(A, B))); + assertFalse(routingTable.preferInitialRouter()); - routingTable.update( createClusterComposition( EMPTY, singletonList( A ), singletonList( A ) ) ); - assertFalse( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(EMPTY, singletonList(A), singletonList(A))); + assertFalse(routingTable.preferInitialRouter()); - routingTable.update( createClusterComposition( singletonList( A ), singletonList( A ), EMPTY ) ); - assertFalse( routingTable.preferInitialRouter() ); + routingTable.update(createClusterComposition(singletonList(A), singletonList(A), EMPTY)); + assertFalse(routingTable.preferInitialRouter()); } - private ClusterRoutingTable newRoutingTable() - { - return new ClusterRoutingTable( defaultDatabase(), new FakeClock() ); + private ClusterRoutingTable newRoutingTable() { + return new ClusterRoutingTable(defaultDatabase(), new FakeClock()); } - private ClusterRoutingTable newRoutingTable( Clock clock ) - { - return new ClusterRoutingTable( defaultDatabase(), clock ); + private ClusterRoutingTable newRoutingTable(Clock clock) { + return new ClusterRoutingTable(defaultDatabase(), clock); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/IdentityResolverTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/IdentityResolverTest.java index 8bd322808e..78a24f7d64 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/IdentityResolverTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/IdentityResolverTest.java @@ -18,28 +18,24 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; - -import java.util.Set; - -import org.neo4j.driver.net.ServerAddress; - import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.mockito.Mockito.mock; import static org.neo4j.driver.internal.cluster.IdentityResolver.IDENTITY_RESOLVER; -class IdentityResolverTest -{ +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.net.ServerAddress; + +class IdentityResolverTest { @Test - void shouldReturnGivenAddress() - { - ServerAddress address = mock( ServerAddress.class ); + void shouldReturnGivenAddress() { + ServerAddress address = mock(ServerAddress.class); - Set resolved = IDENTITY_RESOLVER.resolve( address ); + Set resolved = IDENTITY_RESOLVER.resolve(address); - assertThat( resolved.size(), equalTo( 1 ) ); - assertThat( resolved.iterator().next(), is( address ) ); + assertThat(resolved.size(), equalTo(1)); + assertThat(resolved.iterator().next(), is(address)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/MultiDatabasesRoutingProcedureRunnerTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/MultiDatabasesRoutingProcedureRunnerTest.java index 7abbe76252..787e3b73da 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/MultiDatabasesRoutingProcedureRunnerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/MultiDatabasesRoutingProcedureRunnerTest.java @@ -18,22 +18,6 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; - -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Query; -import org.neo4j.driver.Record; -import org.neo4j.driver.Value; -import org.neo4j.driver.internal.BookmarkHolder; -import org.neo4j.driver.internal.ReadOnlyBookmarkHolder; -import org.neo4j.driver.internal.spi.Connection; - import static java.util.Collections.EMPTY_MAP; import static java.util.Collections.singletonList; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -53,87 +37,93 @@ import static org.neo4j.driver.internal.cluster.SingleDatabaseRoutingProcedureRunner.ROUTING_CONTEXT; import static org.neo4j.driver.util.TestUtil.await; -class MultiDatabasesRoutingProcedureRunnerTest extends AbstractRoutingProcedureRunnerTest -{ +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.BookmarkHolder; +import org.neo4j.driver.internal.ReadOnlyBookmarkHolder; +import org.neo4j.driver.internal.spi.Connection; + +class MultiDatabasesRoutingProcedureRunnerTest extends AbstractRoutingProcedureRunnerTest { @ParameterizedTest - @ValueSource( strings = {"", SYSTEM_DATABASE_NAME, " this is a db name "} ) - void shouldCallGetRoutingTableWithEmptyMapOnSystemDatabaseForDatabase( String db ) - { - TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner( RoutingContext.EMPTY ); - RoutingProcedureResponse response = await( runner.run( connection(), database( db ), empty(), null ) ); + @ValueSource(strings = {"", SYSTEM_DATABASE_NAME, " this is a db name "}) + void shouldCallGetRoutingTableWithEmptyMapOnSystemDatabaseForDatabase(String db) { + TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner(RoutingContext.EMPTY); + RoutingProcedureResponse response = await(runner.run(connection(), database(db), empty(), null)); - assertTrue( response.isSuccess() ); - assertEquals( 1, response.records().size() ); + assertTrue(response.isSuccess()); + assertEquals(1, response.records().size()); - assertThat( runner.bookmarkHolder, instanceOf( ReadOnlyBookmarkHolder.class ) ); - assertThat( runner.connection.databaseName(), equalTo( systemDatabase() ) ); - assertThat( runner.connection.mode(), equalTo( AccessMode.READ ) ); + assertThat(runner.bookmarkHolder, instanceOf(ReadOnlyBookmarkHolder.class)); + assertThat(runner.connection.databaseName(), equalTo(systemDatabase())); + assertThat(runner.connection.mode(), equalTo(AccessMode.READ)); - Query query = generateMultiDatabaseRoutingQuery( EMPTY_MAP, db ); - assertThat( runner.procedure, equalTo(query) ); + Query query = generateMultiDatabaseRoutingQuery(EMPTY_MAP, db); + assertThat(runner.procedure, equalTo(query)); } @ParameterizedTest - @ValueSource( strings = {"", SYSTEM_DATABASE_NAME, " this is a db name "} ) - void shouldCallGetRoutingTableWithParamOnSystemDatabaseForDatabase( String db ) - { - URI uri = URI.create( "neo4j://localhost/?key1=value1&key2=value2" ); - RoutingContext context = new RoutingContext( uri ); + @ValueSource(strings = {"", SYSTEM_DATABASE_NAME, " this is a db name "}) + void shouldCallGetRoutingTableWithParamOnSystemDatabaseForDatabase(String db) { + URI uri = URI.create("neo4j://localhost/?key1=value1&key2=value2"); + RoutingContext context = new RoutingContext(uri); - TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner( context ); - RoutingProcedureResponse response = await( runner.run( connection(), database( db ), empty(), null ) ); + TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner(context); + RoutingProcedureResponse response = await(runner.run(connection(), database(db), empty(), null)); - assertTrue( response.isSuccess() ); - assertEquals( 1, response.records().size() ); + assertTrue(response.isSuccess()); + assertEquals(1, response.records().size()); - assertThat( runner.bookmarkHolder, instanceOf( ReadOnlyBookmarkHolder.class ) ); - assertThat( runner.connection.databaseName(), equalTo( systemDatabase() ) ); - assertThat( runner.connection.mode(), equalTo( AccessMode.READ ) ); + assertThat(runner.bookmarkHolder, instanceOf(ReadOnlyBookmarkHolder.class)); + assertThat(runner.connection.databaseName(), equalTo(systemDatabase())); + assertThat(runner.connection.mode(), equalTo(AccessMode.READ)); - Query query = generateMultiDatabaseRoutingQuery( context.toMap(), db ); - assertThat( response.procedure(), equalTo(query) ); - assertThat( runner.procedure, equalTo(query) ); + Query query = generateMultiDatabaseRoutingQuery(context.toMap(), db); + assertThat(response.procedure(), equalTo(query)); + assertThat(runner.procedure, equalTo(query)); } @Override - SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( RoutingContext context ) - { - return new TestRoutingProcedureRunner( context ); + SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner(RoutingContext context) { + return new TestRoutingProcedureRunner(context); } @Override - SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( RoutingContext context, CompletionStage> runProcedureResult ) - { - return new TestRoutingProcedureRunner( context, runProcedureResult ); + SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( + RoutingContext context, CompletionStage> runProcedureResult) { + return new TestRoutingProcedureRunner(context, runProcedureResult); } - private static Query generateMultiDatabaseRoutingQuery(Map context, String db ) - { - Value parameters = parameters( ROUTING_CONTEXT, context, DATABASE_NAME, db ); - return new Query( MULTI_DB_GET_ROUTING_TABLE, parameters ); + private static Query generateMultiDatabaseRoutingQuery(Map context, String db) { + Value parameters = parameters(ROUTING_CONTEXT, context, DATABASE_NAME, db); + return new Query(MULTI_DB_GET_ROUTING_TABLE, parameters); } - private static class TestRoutingProcedureRunner extends MultiDatabasesRoutingProcedureRunner - { + private static class TestRoutingProcedureRunner extends MultiDatabasesRoutingProcedureRunner { final CompletionStage> runProcedureResult; private Connection connection; private Query procedure; private BookmarkHolder bookmarkHolder; - TestRoutingProcedureRunner( RoutingContext context ) - { - this( context, completedFuture( singletonList( mock( Record.class ) ) ) ); + TestRoutingProcedureRunner(RoutingContext context) { + this(context, completedFuture(singletonList(mock(Record.class)))); } - TestRoutingProcedureRunner( RoutingContext context, CompletionStage> runProcedureResult ) - { - super( context ); + TestRoutingProcedureRunner(RoutingContext context, CompletionStage> runProcedureResult) { + super(context); this.runProcedureResult = runProcedureResult; } @Override - CompletionStage> runProcedure(Connection connection, Query procedure, BookmarkHolder bookmarkHolder ) - { + CompletionStage> runProcedure( + Connection connection, Query procedure, BookmarkHolder bookmarkHolder) { this.connection = connection; this.procedure = procedure; this.bookmarkHolder = bookmarkHolder; diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java index cad1046464..ce57b73bf2 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryTest.java @@ -18,40 +18,6 @@ */ package org.neo4j.driver.internal.cluster; -import io.netty.util.concurrent.GlobalEventExecutor; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import org.mockito.ArgumentCaptor; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.neo4j.driver.Logger; -import org.neo4j.driver.Logging; -import org.neo4j.driver.exceptions.AuthenticationException; -import org.neo4j.driver.exceptions.AuthorizationExpiredException; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.exceptions.DiscoveryException; -import org.neo4j.driver.exceptions.ProtocolException; -import org.neo4j.driver.exceptions.ServiceUnavailableException; -import org.neo4j.driver.exceptions.SessionExpiredException; -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.DatabaseName; -import org.neo4j.driver.internal.DefaultDomainNameResolver; -import org.neo4j.driver.internal.DomainNameResolver; -import org.neo4j.driver.internal.InternalBookmark; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.FakeClock; -import org.neo4j.driver.internal.util.ImmediateSchedulingEventExecutor; -import org.neo4j.driver.net.ServerAddressResolver; - import static java.util.Arrays.asList; import static java.util.Collections.emptySet; import static java.util.Collections.singletonMap; @@ -81,511 +47,556 @@ import static org.neo4j.driver.util.TestUtil.asOrderedSet; import static org.neo4j.driver.util.TestUtil.await; -class RediscoveryTest -{ +import io.netty.util.concurrent.GlobalEventExecutor; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.ArgumentCaptor; +import org.neo4j.driver.Logger; +import org.neo4j.driver.Logging; +import org.neo4j.driver.exceptions.AuthenticationException; +import org.neo4j.driver.exceptions.AuthorizationExpiredException; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.exceptions.DiscoveryException; +import org.neo4j.driver.exceptions.ProtocolException; +import org.neo4j.driver.exceptions.ServiceUnavailableException; +import org.neo4j.driver.exceptions.SessionExpiredException; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.DatabaseName; +import org.neo4j.driver.internal.DefaultDomainNameResolver; +import org.neo4j.driver.internal.DomainNameResolver; +import org.neo4j.driver.internal.InternalBookmark; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionPool; +import org.neo4j.driver.internal.util.FakeClock; +import org.neo4j.driver.internal.util.ImmediateSchedulingEventExecutor; +import org.neo4j.driver.net.ServerAddressResolver; + +class RediscoveryTest { private final ConnectionPool pool = asyncConnectionPoolMock(); @Test - void shouldUseFirstRouterInTable() - { + void shouldUseFirstRouterInTable() { ClusterComposition expectedComposition = - new ClusterComposition( 42, asOrderedSet( B, C ), asOrderedSet( C, D ), asOrderedSet( B ), null ); + new ClusterComposition(42, asOrderedSet(B, C), asOrderedSet(C, D), asOrderedSet(B), null); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( B, expectedComposition ); // first -> valid cluster composition + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(B, expectedComposition); // first -> valid cluster composition - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, mock( ServerAddressResolver.class ) ); - RoutingTable table = routingTableMock( B ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, mock(ServerAddressResolver.class)); + RoutingTable table = routingTableMock(B); - ClusterComposition actualComposition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); + ClusterComposition actualComposition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); - assertEquals( expectedComposition, actualComposition ); - verify( table, never() ).forget( B ); + assertEquals(expectedComposition, actualComposition); + verify(table, never()).forget(B); } @Test - void shouldSkipFailingRouters() - { + void shouldSkipFailingRouters() { ClusterComposition expectedComposition = - new ClusterComposition( 42, asOrderedSet( A, B, C ), asOrderedSet( B, C, D ), asOrderedSet( A, B ), null ); + new ClusterComposition(42, asOrderedSet(A, B, C), asOrderedSet(B, C, D), asOrderedSet(A, B), null); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( A, new RuntimeException( "Hi!" ) ); // first -> non-fatal failure - responsesByAddress.put( B, new ServiceUnavailableException( "Hi!" ) ); // second -> non-fatal failure - responsesByAddress.put( C, expectedComposition ); // third -> valid cluster composition + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(A, new RuntimeException("Hi!")); // first -> non-fatal failure + responsesByAddress.put(B, new ServiceUnavailableException("Hi!")); // second -> non-fatal failure + responsesByAddress.put(C, expectedComposition); // third -> valid cluster composition - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, mock( ServerAddressResolver.class ) ); - RoutingTable table = routingTableMock( A, B, C ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, mock(ServerAddressResolver.class)); + RoutingTable table = routingTableMock(A, B, C); - ClusterComposition actualComposition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); + ClusterComposition actualComposition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); - assertEquals( expectedComposition, actualComposition ); - verify( table ).forget( A ); - verify( table ).forget( B ); - verify( table, never() ).forget( C ); + assertEquals(expectedComposition, actualComposition); + verify(table).forget(A); + verify(table).forget(B); + verify(table, never()).forget(C); } @Test - void shouldFailImmediatelyOnAuthError() - { - AuthenticationException authError = new AuthenticationException( "Neo.ClientError.Security.Unauthorized", - "Wrong password" ); - - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( A, new RuntimeException( "Hi!" ) ); // first router -> non-fatal failure - responsesByAddress.put( B, authError ); // second router -> fatal auth error - - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, mock( ServerAddressResolver.class ) ); - RoutingTable table = routingTableMock( A, B, C ); - - AuthenticationException error = assertThrows( AuthenticationException.class, - () -> await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ) ); - assertEquals( authError, error ); - verify( table ).forget( A ); + void shouldFailImmediatelyOnAuthError() { + AuthenticationException authError = + new AuthenticationException("Neo.ClientError.Security.Unauthorized", "Wrong password"); + + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(A, new RuntimeException("Hi!")); // first router -> non-fatal failure + responsesByAddress.put(B, authError); // second router -> fatal auth error + + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, mock(ServerAddressResolver.class)); + RoutingTable table = routingTableMock(A, B, C); + + AuthenticationException error = assertThrows( + AuthenticationException.class, + () -> await(rediscovery.lookupClusterComposition(table, pool, empty(), null))); + assertEquals(authError, error); + verify(table).forget(A); } @Test - void shouldUseAnotherRouterOnAuthorizationExpiredException() - { + void shouldUseAnotherRouterOnAuthorizationExpiredException() { ClusterComposition expectedComposition = - new ClusterComposition( 42, asOrderedSet( A, B, C ), asOrderedSet( B, C, D ), asOrderedSet( A, B ), null ); + new ClusterComposition(42, asOrderedSet(A, B, C), asOrderedSet(B, C, D), asOrderedSet(A, B), null); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( A, new AuthorizationExpiredException( "Neo.ClientError.Security.AuthorizationExpired", "message" ) ); - responsesByAddress.put( B, expectedComposition ); + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put( + A, new AuthorizationExpiredException("Neo.ClientError.Security.AuthorizationExpired", "message")); + responsesByAddress.put(B, expectedComposition); - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, mock( ServerAddressResolver.class ) ); - RoutingTable table = routingTableMock( A, B, C ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, mock(ServerAddressResolver.class)); + RoutingTable table = routingTableMock(A, B, C); - ClusterComposition actualComposition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); + ClusterComposition actualComposition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); - assertEquals( expectedComposition, actualComposition ); - verify( table ).forget( A ); - verify( table, never() ).forget( B ); - verify( table, never() ).forget( C ); + assertEquals(expectedComposition, actualComposition); + verify(table).forget(A); + verify(table, never()).forget(B); + verify(table, never()).forget(C); } @ParameterizedTest - @ValueSource( strings = {"Neo.ClientError.Transaction.InvalidBookmark", "Neo.ClientError.Transaction.InvalidBookmarkMixture"} ) - void shouldFailImmediatelyOnBookmarkErrors( String code ) - { - ClientException error = new ClientException( code, "Invalid" ); - - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( A, new RuntimeException( "Hi!" ) ); - responsesByAddress.put( B, error ); - - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, mock( ServerAddressResolver.class ) ); - RoutingTable table = routingTableMock( A, B, C ); - - ClientException actualError = assertThrows( ClientException.class, - () -> await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ) ); - assertEquals( error, actualError ); - verify( table ).forget( A ); + @ValueSource( + strings = { + "Neo.ClientError.Transaction.InvalidBookmark", + "Neo.ClientError.Transaction.InvalidBookmarkMixture" + }) + void shouldFailImmediatelyOnBookmarkErrors(String code) { + ClientException error = new ClientException(code, "Invalid"); + + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(A, new RuntimeException("Hi!")); + responsesByAddress.put(B, error); + + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, mock(ServerAddressResolver.class)); + RoutingTable table = routingTableMock(A, B, C); + + ClientException actualError = assertThrows( + ClientException.class, () -> await(rediscovery.lookupClusterComposition(table, pool, empty(), null))); + assertEquals(error, actualError); + verify(table).forget(A); } @Test - void shouldFailImmediatelyOnClosedPoolError() - { - IllegalStateException error = new IllegalStateException( ConnectionPool.CONNECTION_POOL_CLOSED_ERROR_MESSAGE ); - - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( A, new RuntimeException( "Hi!" ) ); - responsesByAddress.put( B, error ); - - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, mock( ServerAddressResolver.class ) ); - RoutingTable table = routingTableMock( A, B, C ); - - IllegalStateException actualError = assertThrows( IllegalStateException.class, - () -> await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ) ); - assertEquals( error, actualError ); - verify( table ).forget( A ); + void shouldFailImmediatelyOnClosedPoolError() { + IllegalStateException error = new IllegalStateException(ConnectionPool.CONNECTION_POOL_CLOSED_ERROR_MESSAGE); + + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(A, new RuntimeException("Hi!")); + responsesByAddress.put(B, error); + + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, mock(ServerAddressResolver.class)); + RoutingTable table = routingTableMock(A, B, C); + + IllegalStateException actualError = assertThrows( + IllegalStateException.class, + () -> await(rediscovery.lookupClusterComposition(table, pool, empty(), null))); + assertEquals(error, actualError); + verify(table).forget(A); } @Test - void shouldFallbackToInitialRouterWhenKnownRoutersFail() - { + void shouldFallbackToInitialRouterWhenKnownRoutersFail() { BoltServerAddress initialRouter = A; ClusterComposition expectedComposition = - new ClusterComposition( 42, asOrderedSet( C, B, A ), asOrderedSet( A, B ), asOrderedSet( D, E ), null ); + new ClusterComposition(42, asOrderedSet(C, B, A), asOrderedSet(A, B), asOrderedSet(D, E), null); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( B, new ServiceUnavailableException( "Hi!" ) ); // first -> non-fatal failure - responsesByAddress.put( C, new ServiceUnavailableException( "Hi!" ) ); // second -> non-fatal failure - responsesByAddress.put( initialRouter, expectedComposition ); // initial -> valid response + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(B, new ServiceUnavailableException("Hi!")); // first -> non-fatal failure + responsesByAddress.put(C, new ServiceUnavailableException("Hi!")); // second -> non-fatal failure + responsesByAddress.put(initialRouter, expectedComposition); // initial -> valid response - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - ServerAddressResolver resolver = resolverMock( initialRouter, initialRouter ); - Rediscovery rediscovery = newRediscovery( initialRouter, compositionProvider, resolver ); - RoutingTable table = routingTableMock( B, C ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + ServerAddressResolver resolver = resolverMock(initialRouter, initialRouter); + Rediscovery rediscovery = newRediscovery(initialRouter, compositionProvider, resolver); + RoutingTable table = routingTableMock(B, C); - ClusterComposition actualComposition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); + ClusterComposition actualComposition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); - assertEquals( expectedComposition, actualComposition ); - verify( table ).forget( B ); - verify( table ).forget( C ); + assertEquals(expectedComposition, actualComposition); + verify(table).forget(B); + verify(table).forget(C); } @Test - void shouldFailImmediatelyWhenClusterCompositionProviderReturnsFailure() - { + void shouldFailImmediatelyWhenClusterCompositionProviderReturnsFailure() { ClusterComposition validComposition = - new ClusterComposition( 42, asOrderedSet( A ), asOrderedSet( B ), asOrderedSet( C ), null ); - ProtocolException protocolError = new ProtocolException( "Wrong record!" ); + new ClusterComposition(42, asOrderedSet(A), asOrderedSet(B), asOrderedSet(C), null); + ProtocolException protocolError = new ProtocolException("Wrong record!"); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( B, protocolError ); // first -> fatal failure - responsesByAddress.put( C, validComposition ); // second -> valid cluster composition + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(B, protocolError); // first -> fatal failure + responsesByAddress.put(C, validComposition); // second -> valid cluster composition - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, mock( ServerAddressResolver.class ), logging ); - RoutingTable table = routingTableMock( B, C ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, mock(ServerAddressResolver.class), logging); + RoutingTable table = routingTableMock(B, C); // When - ClusterComposition composition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); - assertEquals( validComposition, composition ); - - ArgumentCaptor warningMessageCaptor = ArgumentCaptor.forClass( String.class ); - ArgumentCaptor debugMessageCaptor = ArgumentCaptor.forClass( String.class ); - ArgumentCaptor debugThrowableCaptor = ArgumentCaptor.forClass( DiscoveryException.class ); - verify( logging ).getLog( RediscoveryImpl.class ); - verify( logger ).warn( warningMessageCaptor.capture() ); - verify( logger ).debug( debugMessageCaptor.capture(), debugThrowableCaptor.capture() ); - assertNotNull( warningMessageCaptor.getValue() ); - assertEquals( warningMessageCaptor.getValue(), debugMessageCaptor.getValue() ); - assertThat( debugThrowableCaptor.getValue().getCause(), equalTo( protocolError ) ); + ClusterComposition composition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); + assertEquals(validComposition, composition); + + ArgumentCaptor warningMessageCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor debugMessageCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor debugThrowableCaptor = ArgumentCaptor.forClass(DiscoveryException.class); + verify(logging).getLog(RediscoveryImpl.class); + verify(logger).warn(warningMessageCaptor.capture()); + verify(logger).debug(debugMessageCaptor.capture(), debugThrowableCaptor.capture()); + assertNotNull(warningMessageCaptor.getValue()); + assertEquals(warningMessageCaptor.getValue(), debugMessageCaptor.getValue()); + assertThat(debugThrowableCaptor.getValue().getCause(), equalTo(protocolError)); } @Test - void shouldResolveInitialRouterAddress() - { + void shouldResolveInitialRouterAddress() { BoltServerAddress initialRouter = A; ClusterComposition expectedComposition = - new ClusterComposition( 42, asOrderedSet( A, B ), asOrderedSet( A, B ), asOrderedSet( A, B ), null ); + new ClusterComposition(42, asOrderedSet(A, B), asOrderedSet(A, B), asOrderedSet(A, B), null); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( B, new ServiceUnavailableException( "Hi!" ) ); // first -> non-fatal failure - responsesByAddress.put( C, new ServiceUnavailableException( "Hi!" ) ); // second -> non-fatal failure - responsesByAddress.put( D, new IOException( "Hi!" ) ); // resolved first -> non-fatal failure - responsesByAddress.put( E, expectedComposition ); // resolved second -> valid response + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(B, new ServiceUnavailableException("Hi!")); // first -> non-fatal failure + responsesByAddress.put(C, new ServiceUnavailableException("Hi!")); // second -> non-fatal failure + responsesByAddress.put(D, new IOException("Hi!")); // resolved first -> non-fatal failure + responsesByAddress.put(E, expectedComposition); // resolved second -> valid response - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); // initial router resolved to two other addresses - ServerAddressResolver resolver = resolverMock( initialRouter, D, E ); - Rediscovery rediscovery = newRediscovery( initialRouter, compositionProvider, resolver ); - RoutingTable table = routingTableMock( B, C ); + ServerAddressResolver resolver = resolverMock(initialRouter, D, E); + Rediscovery rediscovery = newRediscovery(initialRouter, compositionProvider, resolver); + RoutingTable table = routingTableMock(B, C); - ClusterComposition actualComposition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); + ClusterComposition actualComposition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); - assertEquals( expectedComposition, actualComposition ); - verify( table ).forget( B ); - verify( table ).forget( C ); - verify( table ).forget( D ); + assertEquals(expectedComposition, actualComposition); + verify(table).forget(B); + verify(table).forget(C); + verify(table).forget(D); } @Test - void shouldResolveInitialRouterAddressUsingCustomResolver() - { + void shouldResolveInitialRouterAddressUsingCustomResolver() { ClusterComposition expectedComposition = - new ClusterComposition( 42, asOrderedSet( A, B, C ), asOrderedSet( A, B, C ), asOrderedSet( B, E ), null ); + new ClusterComposition(42, asOrderedSet(A, B, C), asOrderedSet(A, B, C), asOrderedSet(B, E), null); - ServerAddressResolver resolver = address -> - { - assertEquals( A, address ); - return asOrderedSet( B, C, E ); + ServerAddressResolver resolver = address -> { + assertEquals(A, address); + return asOrderedSet(B, C, E); }; - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( B, new ServiceUnavailableException( "Hi!" ) ); // first -> non-fatal failure - responsesByAddress.put( C, new ServiceUnavailableException( "Hi!" ) ); // second -> non-fatal failure - responsesByAddress.put( E, expectedComposition ); // resolved second -> valid response + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(B, new ServiceUnavailableException("Hi!")); // first -> non-fatal failure + responsesByAddress.put(C, new ServiceUnavailableException("Hi!")); // second -> non-fatal failure + responsesByAddress.put(E, expectedComposition); // resolved second -> valid response - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, resolver ); - RoutingTable table = routingTableMock( B, C ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, resolver); + RoutingTable table = routingTableMock(B, C); - ClusterComposition actualComposition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); + ClusterComposition actualComposition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); - assertEquals( expectedComposition, actualComposition ); - verify( table ).forget( B ); - verify( table ).forget( C ); + assertEquals(expectedComposition, actualComposition); + verify(table).forget(B); + verify(table).forget(C); } @Test - void shouldPropagateFailureWhenResolverFails() - { + void shouldPropagateFailureWhenResolverFails() { ClusterComposition expectedComposition = - new ClusterComposition( 42, asOrderedSet( A, B ), asOrderedSet( A, B ), asOrderedSet( A, B ), null ); + new ClusterComposition(42, asOrderedSet(A, B), asOrderedSet(A, B), asOrderedSet(A, B), null); - Map responsesByAddress = singletonMap( A, expectedComposition ); - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); + Map responsesByAddress = singletonMap(A, expectedComposition); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); // failing server address resolver - ServerAddressResolver resolver = mock( ServerAddressResolver.class ); - when( resolver.resolve( A ) ).thenThrow( new RuntimeException( "Resolver fails!" ) ); + ServerAddressResolver resolver = mock(ServerAddressResolver.class); + when(resolver.resolve(A)).thenThrow(new RuntimeException("Resolver fails!")); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, resolver ); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, resolver); RoutingTable table = routingTableMock(); - RuntimeException error = assertThrows( RuntimeException.class, () -> await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ) ); - assertEquals( "Resolver fails!", error.getMessage() ); + RuntimeException error = assertThrows( + RuntimeException.class, () -> await(rediscovery.lookupClusterComposition(table, pool, empty(), null))); + assertEquals("Resolver fails!", error.getMessage()); - verify( resolver ).resolve( A ); - verify( table, never() ).forget( any() ); + verify(resolver).resolve(A); + verify(table, never()).forget(any()); } @Test - void shouldRecordAllErrorsWhenNoRouterRespond() - { - Map responsesByAddress = new HashMap<>(); - ServiceUnavailableException first = new ServiceUnavailableException( "Hi!" ); - responsesByAddress.put( A, first ); // first -> non-fatal failure - SessionExpiredException second = new SessionExpiredException( "Hi!" ); - responsesByAddress.put( B, second ); // second -> non-fatal failure - IOException third = new IOException( "Hi!" ); - responsesByAddress.put( C, third ); // third -> non-fatal failure - - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - Rediscovery rediscovery = newRediscovery( A, compositionProvider, mock( ServerAddressResolver.class ) ); - RoutingTable table = routingTableMock( A, B, C ); - - ServiceUnavailableException e = - assertThrows( ServiceUnavailableException.class, () -> await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ) ); - assertThat( e.getMessage(), containsString( "Could not perform discovery" ) ); - assertThat( e.getSuppressed().length, equalTo( 3 ) ); - assertThat( e.getSuppressed()[0].getCause(), equalTo( first ) ); - assertThat( e.getSuppressed()[1].getCause(), equalTo( second ) ); - assertThat( e.getSuppressed()[2].getCause(), equalTo( third ) ); + void shouldRecordAllErrorsWhenNoRouterRespond() { + Map responsesByAddress = new HashMap<>(); + ServiceUnavailableException first = new ServiceUnavailableException("Hi!"); + responsesByAddress.put(A, first); // first -> non-fatal failure + SessionExpiredException second = new SessionExpiredException("Hi!"); + responsesByAddress.put(B, second); // second -> non-fatal failure + IOException third = new IOException("Hi!"); + responsesByAddress.put(C, third); // third -> non-fatal failure + + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + Rediscovery rediscovery = newRediscovery(A, compositionProvider, mock(ServerAddressResolver.class)); + RoutingTable table = routingTableMock(A, B, C); + + ServiceUnavailableException e = assertThrows( + ServiceUnavailableException.class, + () -> await(rediscovery.lookupClusterComposition(table, pool, empty(), null))); + assertThat(e.getMessage(), containsString("Could not perform discovery")); + assertThat(e.getSuppressed().length, equalTo(3)); + assertThat(e.getSuppressed()[0].getCause(), equalTo(first)); + assertThat(e.getSuppressed()[1].getCause(), equalTo(second)); + assertThat(e.getSuppressed()[2].getCause(), equalTo(third)); } @Test - void shouldUseInitialRouterAfterDiscoveryReturnsNoWriters() - { + void shouldUseInitialRouterAfterDiscoveryReturnsNoWriters() { BoltServerAddress initialRouter = A; ClusterComposition noWritersComposition = - new ClusterComposition( 42, asOrderedSet( D, E ), emptySet(), asOrderedSet( D, E ), null ); + new ClusterComposition(42, asOrderedSet(D, E), emptySet(), asOrderedSet(D, E), null); ClusterComposition validComposition = - new ClusterComposition( 42, asOrderedSet( B, A ), asOrderedSet( B, A ), asOrderedSet( B, A ), null ); + new ClusterComposition(42, asOrderedSet(B, A), asOrderedSet(B, A), asOrderedSet(B, A), null); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( initialRouter, validComposition ); // initial -> valid composition + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(initialRouter, validComposition); // initial -> valid composition - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - ServerAddressResolver resolver = resolverMock( initialRouter, initialRouter ); - Rediscovery rediscovery = newRediscovery( initialRouter, compositionProvider, resolver ); - RoutingTable table = new ClusterRoutingTable( defaultDatabase(), new FakeClock() ); - table.update( noWritersComposition ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + ServerAddressResolver resolver = resolverMock(initialRouter, initialRouter); + Rediscovery rediscovery = newRediscovery(initialRouter, compositionProvider, resolver); + RoutingTable table = new ClusterRoutingTable(defaultDatabase(), new FakeClock()); + table.update(noWritersComposition); - ClusterComposition composition2 = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); - assertEquals( validComposition, composition2 ); + ClusterComposition composition2 = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); + assertEquals(validComposition, composition2); } @Test - void shouldUseInitialRouterToStartWith() - { + void shouldUseInitialRouterToStartWith() { BoltServerAddress initialRouter = A; ClusterComposition validComposition = - new ClusterComposition( 42, asOrderedSet( A ), asOrderedSet( A ), asOrderedSet( A ), null ); + new ClusterComposition(42, asOrderedSet(A), asOrderedSet(A), asOrderedSet(A), null); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( initialRouter, validComposition ); // initial -> valid composition + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(initialRouter, validComposition); // initial -> valid composition - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - ServerAddressResolver resolver = resolverMock( initialRouter, initialRouter ); - Rediscovery rediscovery = newRediscovery( initialRouter, compositionProvider, resolver ); - RoutingTable table = routingTableMock( true, B, C, D ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + ServerAddressResolver resolver = resolverMock(initialRouter, initialRouter); + Rediscovery rediscovery = newRediscovery(initialRouter, compositionProvider, resolver); + RoutingTable table = routingTableMock(true, B, C, D); - ClusterComposition composition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); - assertEquals( validComposition, composition ); + ClusterComposition composition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); + assertEquals(validComposition, composition); } @Test - void shouldUseKnownRoutersWhenInitialRouterFails() - { + void shouldUseKnownRoutersWhenInitialRouterFails() { BoltServerAddress initialRouter = A; ClusterComposition validComposition = - new ClusterComposition( 42, asOrderedSet( D, E ), asOrderedSet( E, D ), asOrderedSet( A, B ), null ); - - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( initialRouter, new ServiceUnavailableException( "Hi" ) ); // initial -> non-fatal error - responsesByAddress.put( D, new IOException( "Hi" ) ); // first known -> non-fatal failure - responsesByAddress.put( E, validComposition ); // second known -> valid composition - - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - ServerAddressResolver resolver = resolverMock( initialRouter, initialRouter ); - Rediscovery rediscovery = newRediscovery( initialRouter, compositionProvider, resolver ); - RoutingTable table = routingTableMock( true, D, E ); - - ClusterComposition composition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); - assertEquals( validComposition, composition ); - verify( table ).forget( initialRouter ); - verify( table ).forget( D ); + new ClusterComposition(42, asOrderedSet(D, E), asOrderedSet(E, D), asOrderedSet(A, B), null); + + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(initialRouter, new ServiceUnavailableException("Hi")); // initial -> non-fatal error + responsesByAddress.put(D, new IOException("Hi")); // first known -> non-fatal failure + responsesByAddress.put(E, validComposition); // second known -> valid composition + + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + ServerAddressResolver resolver = resolverMock(initialRouter, initialRouter); + Rediscovery rediscovery = newRediscovery(initialRouter, compositionProvider, resolver); + RoutingTable table = routingTableMock(true, D, E); + + ClusterComposition composition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); + assertEquals(validComposition, composition); + verify(table).forget(initialRouter); + verify(table).forget(D); } @Test - void shouldRetryConfiguredNumberOfTimesWithDelay() - { + void shouldRetryConfiguredNumberOfTimesWithDelay() { int maxRoutingFailures = 3; long retryTimeoutDelay = 15; ClusterComposition expectedComposition = - new ClusterComposition( 42, asOrderedSet( A, C ), asOrderedSet( B, D ), asOrderedSet( A, E ), null ); + new ClusterComposition(42, asOrderedSet(A, C), asOrderedSet(B, D), asOrderedSet(A, E), null); - Map responsesByAddress = new HashMap<>(); - responsesByAddress.put( A, new ServiceUnavailableException( "Hi!" ) ); - responsesByAddress.put( B, new ServiceUnavailableException( "Hi!" ) ); - responsesByAddress.put( E, expectedComposition ); + Map responsesByAddress = new HashMap<>(); + responsesByAddress.put(A, new ServiceUnavailableException("Hi!")); + responsesByAddress.put(B, new ServiceUnavailableException("Hi!")); + responsesByAddress.put(E, expectedComposition); - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - ServerAddressResolver resolver = mock( ServerAddressResolver.class ); - when( resolver.resolve( A ) ).thenReturn( asOrderedSet( A ) ) - .thenReturn( asOrderedSet( A ) ) - .thenReturn( asOrderedSet( E ) ); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + ServerAddressResolver resolver = mock(ServerAddressResolver.class); + when(resolver.resolve(A)) + .thenReturn(asOrderedSet(A)) + .thenReturn(asOrderedSet(A)) + .thenReturn(asOrderedSet(E)); ImmediateSchedulingEventExecutor eventExecutor = new ImmediateSchedulingEventExecutor(); - RoutingSettings settings = new RoutingSettings( maxRoutingFailures, retryTimeoutDelay, 0 ); - Rediscovery rediscovery = - new RediscoveryImpl( A, settings, compositionProvider, eventExecutor, resolver, DEV_NULL_LOGGING, - DefaultDomainNameResolver.getInstance() ); - RoutingTable table = routingTableMock( A, B ); - - ClusterComposition actualComposition = await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ).getClusterComposition(); - - assertEquals( expectedComposition, actualComposition ); - verify( table, times( maxRoutingFailures ) ).forget( A ); - verify( table, times( maxRoutingFailures ) ).forget( B ); - assertEquals( asList( retryTimeoutDelay, retryTimeoutDelay * 2 ), eventExecutor.scheduleDelays() ); + RoutingSettings settings = new RoutingSettings(maxRoutingFailures, retryTimeoutDelay, 0); + Rediscovery rediscovery = new RediscoveryImpl( + A, + settings, + compositionProvider, + eventExecutor, + resolver, + DEV_NULL_LOGGING, + DefaultDomainNameResolver.getInstance()); + RoutingTable table = routingTableMock(A, B); + + ClusterComposition actualComposition = await(rediscovery.lookupClusterComposition(table, pool, empty(), null)) + .getClusterComposition(); + + assertEquals(expectedComposition, actualComposition); + verify(table, times(maxRoutingFailures)).forget(A); + verify(table, times(maxRoutingFailures)).forget(B); + assertEquals(asList(retryTimeoutDelay, retryTimeoutDelay * 2), eventExecutor.scheduleDelays()); } @Test - void shouldNotLogWhenSingleRetryAttemptFails() - { + void shouldNotLogWhenSingleRetryAttemptFails() { int maxRoutingFailures = 1; long retryTimeoutDelay = 10; - Map responsesByAddress = singletonMap( A, new ServiceUnavailableException( "Hi!" ) ); - ClusterCompositionProvider compositionProvider = compositionProviderMock( responsesByAddress ); - ServerAddressResolver resolver = resolverMock( A, A ); + Map responsesByAddress = singletonMap(A, new ServiceUnavailableException("Hi!")); + ClusterCompositionProvider compositionProvider = compositionProviderMock(responsesByAddress); + ServerAddressResolver resolver = resolverMock(A, A); ImmediateSchedulingEventExecutor eventExecutor = new ImmediateSchedulingEventExecutor(); - RoutingSettings settings = new RoutingSettings( maxRoutingFailures, retryTimeoutDelay, 0 ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - Rediscovery rediscovery = - new RediscoveryImpl( A, settings, compositionProvider, eventExecutor, resolver, logging, DefaultDomainNameResolver.getInstance() ); - RoutingTable table = routingTableMock( A ); - - ServiceUnavailableException e = - assertThrows( ServiceUnavailableException.class, () -> await( rediscovery.lookupClusterComposition( table, pool, empty(), null ) ) ); - assertThat( e.getMessage(), containsString( "Could not perform discovery" ) ); + RoutingSettings settings = new RoutingSettings(maxRoutingFailures, retryTimeoutDelay, 0); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + Rediscovery rediscovery = new RediscoveryImpl( + A, + settings, + compositionProvider, + eventExecutor, + resolver, + logging, + DefaultDomainNameResolver.getInstance()); + RoutingTable table = routingTableMock(A); + + ServiceUnavailableException e = assertThrows( + ServiceUnavailableException.class, + () -> await(rediscovery.lookupClusterComposition(table, pool, empty(), null))); + assertThat(e.getMessage(), containsString("Could not perform discovery")); // rediscovery should not log about retries and should not schedule any retries - verify( logging ).getLog( RediscoveryImpl.class ); - verify( logger, never() ).info( startsWith( "Unable to fetch new routing table, will try again in " ) ); - assertEquals( 0, eventExecutor.scheduleDelays().size() ); + verify(logging).getLog(RediscoveryImpl.class); + verify(logger, never()).info(startsWith("Unable to fetch new routing table, will try again in ")); + assertEquals(0, eventExecutor.scheduleDelays().size()); } @Test - void shouldResolveToIP() throws UnknownHostException - { - ServerAddressResolver resolver = resolverMock( A, A ); - DomainNameResolver domainNameResolver = mock( DomainNameResolver.class ); + void shouldResolveToIP() throws UnknownHostException { + ServerAddressResolver resolver = resolverMock(A, A); + DomainNameResolver domainNameResolver = mock(DomainNameResolver.class); InetAddress localhost = InetAddress.getLocalHost(); - when( domainNameResolver.resolve( A.host() ) ).thenReturn( new InetAddress[]{localhost} ); - Rediscovery rediscovery = new RediscoveryImpl( A, null, null, null, resolver, DEV_NULL_LOGGING, domainNameResolver ); + when(domainNameResolver.resolve(A.host())).thenReturn(new InetAddress[] {localhost}); + Rediscovery rediscovery = + new RediscoveryImpl(A, null, null, null, resolver, DEV_NULL_LOGGING, domainNameResolver); List addresses = rediscovery.resolve(); - verify( resolver, times( 1 ) ).resolve( A ); - verify( domainNameResolver, times( 1 ) ).resolve( A.host() ); - assertEquals( 1, addresses.size() ); - assertEquals( new BoltServerAddress( A.host(), localhost.getHostAddress(), A.port() ), addresses.get( 0 ) ); + verify(resolver, times(1)).resolve(A); + verify(domainNameResolver, times(1)).resolve(A.host()); + assertEquals(1, addresses.size()); + assertEquals(new BoltServerAddress(A.host(), localhost.getHostAddress(), A.port()), addresses.get(0)); } - private Rediscovery newRediscovery( BoltServerAddress initialRouter, ClusterCompositionProvider compositionProvider, - ServerAddressResolver resolver ) - { - return newRediscovery( initialRouter, compositionProvider, resolver, DEV_NULL_LOGGING ); + private Rediscovery newRediscovery( + BoltServerAddress initialRouter, + ClusterCompositionProvider compositionProvider, + ServerAddressResolver resolver) { + return newRediscovery(initialRouter, compositionProvider, resolver, DEV_NULL_LOGGING); } - private Rediscovery newRediscovery( BoltServerAddress initialRouter, ClusterCompositionProvider compositionProvider, - ServerAddressResolver resolver, Logging logging ) - { - RoutingSettings settings = new RoutingSettings( 1, 0, 0 ); - return new RediscoveryImpl( initialRouter, settings, compositionProvider, GlobalEventExecutor.INSTANCE, resolver, logging, - DefaultDomainNameResolver.getInstance() ); + private Rediscovery newRediscovery( + BoltServerAddress initialRouter, + ClusterCompositionProvider compositionProvider, + ServerAddressResolver resolver, + Logging logging) { + RoutingSettings settings = new RoutingSettings(1, 0, 0); + return new RediscoveryImpl( + initialRouter, + settings, + compositionProvider, + GlobalEventExecutor.INSTANCE, + resolver, + logging, + DefaultDomainNameResolver.getInstance()); } - @SuppressWarnings( "unchecked" ) + @SuppressWarnings("unchecked") private static ClusterCompositionProvider compositionProviderMock( - Map responsesByAddress ) - { - ClusterCompositionProvider provider = mock( ClusterCompositionProvider.class ); - when( provider.getClusterComposition( any( Connection.class ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .then( invocation -> - { - Connection connection = invocation.getArgument( 0 ); - BoltServerAddress address = connection.serverAddress(); - Object response = responsesByAddress.get( address ); - assertNotNull( response ); - if ( response instanceof Throwable ) - { - return failedFuture( (Throwable) response ); - } - else - { - return completedFuture( response ); - } - } ); + Map responsesByAddress) { + ClusterCompositionProvider provider = mock(ClusterCompositionProvider.class); + when(provider.getClusterComposition( + any(Connection.class), any(DatabaseName.class), any(InternalBookmark.class), any())) + .then(invocation -> { + Connection connection = invocation.getArgument(0); + BoltServerAddress address = connection.serverAddress(); + Object response = responsesByAddress.get(address); + assertNotNull(response); + if (response instanceof Throwable) { + return failedFuture((Throwable) response); + } else { + return completedFuture(response); + } + }); return provider; } - private static ServerAddressResolver resolverMock( BoltServerAddress address, BoltServerAddress... resolved ) - { - ServerAddressResolver resolver = mock( ServerAddressResolver.class ); - when( resolver.resolve( address ) ).thenReturn( asOrderedSet( resolved ) ); + private static ServerAddressResolver resolverMock(BoltServerAddress address, BoltServerAddress... resolved) { + ServerAddressResolver resolver = mock(ServerAddressResolver.class); + when(resolver.resolve(address)).thenReturn(asOrderedSet(resolved)); return resolver; } - private static ConnectionPool asyncConnectionPoolMock() - { - ConnectionPool pool = mock( ConnectionPool.class ); - when( pool.acquire( any() ) ).then( invocation -> - { - BoltServerAddress address = invocation.getArgument( 0 ); - return completedFuture( asyncConnectionMock( address ) ); - } ); + private static ConnectionPool asyncConnectionPoolMock() { + ConnectionPool pool = mock(ConnectionPool.class); + when(pool.acquire(any())).then(invocation -> { + BoltServerAddress address = invocation.getArgument(0); + return completedFuture(asyncConnectionMock(address)); + }); return pool; } - private static Connection asyncConnectionMock( BoltServerAddress address ) - { - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( address ); + private static Connection asyncConnectionMock(BoltServerAddress address) { + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(address); return connection; } - private static RoutingTable routingTableMock( BoltServerAddress... routers ) - { - return routingTableMock( false, routers ); + private static RoutingTable routingTableMock(BoltServerAddress... routers) { + return routingTableMock(false, routers); } - private static RoutingTable routingTableMock( boolean preferInitialRouter, BoltServerAddress... routers ) - { - RoutingTable routingTable = mock( RoutingTable.class ); - when( routingTable.routers() ).thenReturn( Arrays.asList( routers ) ); - when( routingTable.database() ).thenReturn( defaultDatabase() ); - when( routingTable.preferInitialRouter() ).thenReturn( preferInitialRouter ); + private static RoutingTable routingTableMock(boolean preferInitialRouter, BoltServerAddress... routers) { + RoutingTable routingTable = mock(RoutingTable.class); + when(routingTable.routers()).thenReturn(Arrays.asList(routers)); + when(routingTable.database()).thenReturn(defaultDatabase()); + when(routingTable.preferInitialRouter()).thenReturn(preferInitialRouter); return routingTable; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryUtil.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryUtil.java index 06454c5126..c3db1262e2 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryUtil.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RediscoveryUtil.java @@ -18,23 +18,20 @@ */ package org.neo4j.driver.internal.cluster; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.internal.InternalBookmark; import org.neo4j.driver.internal.async.ConnectionContext; import org.neo4j.driver.internal.async.ImmutableConnectionContext; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; - -public class RediscoveryUtil -{ - public static ConnectionContext contextWithDatabase( String databaseName ) - { - return new ImmutableConnectionContext( database( databaseName ), InternalBookmark.empty(), AccessMode.WRITE ); +public class RediscoveryUtil { + public static ConnectionContext contextWithDatabase(String databaseName) { + return new ImmutableConnectionContext(database(databaseName), InternalBookmark.empty(), AccessMode.WRITE); } - public static ConnectionContext contextWithMode( AccessMode mode ) - { - return new ImmutableConnectionContext( defaultDatabase(), InternalBookmark.empty(), mode ); + public static ConnectionContext contextWithMode(AccessMode mode) { + return new ImmutableConnectionContext(defaultDatabase(), InternalBookmark.empty(), mode); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunnerTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunnerTest.java index 484394e615..1994db9250 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunnerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunnerTest.java @@ -18,10 +18,15 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import java.net.URI; import java.util.ArrayList; @@ -31,7 +36,10 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -43,115 +51,108 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.util.TestUtil; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -class RouteMessageRoutingProcedureRunnerTest -{ +class RouteMessageRoutingProcedureRunnerTest { - private static Stream shouldRequestRoutingTableForAllValidInputScenarios() - { + private static Stream shouldRequestRoutingTableForAllValidInputScenarios() { return Stream.of( - Arguments.arguments( RoutingContext.EMPTY, DatabaseNameUtil.defaultDatabase() ), - Arguments.arguments( RoutingContext.EMPTY, DatabaseNameUtil.systemDatabase() ), - Arguments.arguments( RoutingContext.EMPTY, DatabaseNameUtil.database( "neo4j" ) ), - Arguments.arguments( new RoutingContext( URI.create( "localhost:17601" ) ), DatabaseNameUtil.defaultDatabase() ), - Arguments.arguments( new RoutingContext( URI.create( "localhost:17602" ) ), DatabaseNameUtil.systemDatabase() ), - Arguments.arguments( new RoutingContext( URI.create( "localhost:17603" ) ), DatabaseNameUtil.database( "neo4j" ) ) - ); + Arguments.arguments(RoutingContext.EMPTY, DatabaseNameUtil.defaultDatabase()), + Arguments.arguments(RoutingContext.EMPTY, DatabaseNameUtil.systemDatabase()), + Arguments.arguments(RoutingContext.EMPTY, DatabaseNameUtil.database("neo4j")), + Arguments.arguments( + new RoutingContext(URI.create("localhost:17601")), DatabaseNameUtil.defaultDatabase()), + Arguments.arguments( + new RoutingContext(URI.create("localhost:17602")), DatabaseNameUtil.systemDatabase()), + Arguments.arguments( + new RoutingContext(URI.create("localhost:17603")), DatabaseNameUtil.database("neo4j"))); } @ParameterizedTest @MethodSource - void shouldRequestRoutingTableForAllValidInputScenarios( RoutingContext routingContext, DatabaseName databaseName ) - { - Map routingTable = getRoutingTable(); - CompletableFuture> completableFuture = CompletableFuture.completedFuture( routingTable ); - RouteMessageRoutingProcedureRunner runner = new RouteMessageRoutingProcedureRunner( routingContext, () -> completableFuture ); - Connection connection = mock( Connection.class ); - CompletableFuture releaseConnectionFuture = CompletableFuture.completedFuture( null ); - doReturn( releaseConnectionFuture ).when( connection ).release(); - - RoutingProcedureResponse response = TestUtil.await( runner.run( connection, databaseName, null, null ) ); - - assertNotNull( response ); - assertTrue( response.isSuccess() ); - assertNotNull( response.procedure() ); - assertEquals( 1, response.records().size() ); - assertNotNull( response.records().get( 0 ) ); - - Record record = response.records().get( 0 ); - assertEquals( routingTable.get( "ttl" ), record.get( "ttl" ) ); - assertEquals( routingTable.get( "servers" ), record.get( "servers" ) ); - - verifyMessageWasWrittenAndFlushed( connection, completableFuture, routingContext, null, databaseName ); - verify( connection ).release(); + void shouldRequestRoutingTableForAllValidInputScenarios(RoutingContext routingContext, DatabaseName databaseName) { + Map routingTable = getRoutingTable(); + CompletableFuture> completableFuture = CompletableFuture.completedFuture(routingTable); + RouteMessageRoutingProcedureRunner runner = + new RouteMessageRoutingProcedureRunner(routingContext, () -> completableFuture); + Connection connection = mock(Connection.class); + CompletableFuture releaseConnectionFuture = CompletableFuture.completedFuture(null); + doReturn(releaseConnectionFuture).when(connection).release(); + + RoutingProcedureResponse response = TestUtil.await(runner.run(connection, databaseName, null, null)); + + assertNotNull(response); + assertTrue(response.isSuccess()); + assertNotNull(response.procedure()); + assertEquals(1, response.records().size()); + assertNotNull(response.records().get(0)); + + Record record = response.records().get(0); + assertEquals(routingTable.get("ttl"), record.get("ttl")); + assertEquals(routingTable.get("servers"), record.get("servers")); + + verifyMessageWasWrittenAndFlushed(connection, completableFuture, routingContext, null, databaseName); + verify(connection).release(); } @Test - void shouldReturnFailureWhenSomethingHappensGettingTheRoutingTable() - { - Throwable reason = new RuntimeException( "Some error" ); - CompletableFuture> completableFuture = new CompletableFuture<>(); - completableFuture.completeExceptionally( reason ); - RouteMessageRoutingProcedureRunner runner = new RouteMessageRoutingProcedureRunner( RoutingContext.EMPTY, () -> completableFuture ); - Connection connection = mock( Connection.class ); - CompletableFuture releaseConnectionFuture = CompletableFuture.completedFuture( null ); - doReturn( releaseConnectionFuture ).when( connection ).release(); - - RoutingProcedureResponse response = TestUtil.await( runner.run( connection, DatabaseNameUtil.defaultDatabase(), null, null ) ); - - assertNotNull( response ); - assertFalse( response.isSuccess() ); - assertNotNull( response.procedure() ); - assertEquals( reason, response.error() ); - assertThrows( IllegalStateException.class, () -> response.records().size() ); - - verifyMessageWasWrittenAndFlushed( connection, completableFuture, RoutingContext.EMPTY, null, DatabaseNameUtil.defaultDatabase() ); - verify( connection ).release(); + void shouldReturnFailureWhenSomethingHappensGettingTheRoutingTable() { + Throwable reason = new RuntimeException("Some error"); + CompletableFuture> completableFuture = new CompletableFuture<>(); + completableFuture.completeExceptionally(reason); + RouteMessageRoutingProcedureRunner runner = + new RouteMessageRoutingProcedureRunner(RoutingContext.EMPTY, () -> completableFuture); + Connection connection = mock(Connection.class); + CompletableFuture releaseConnectionFuture = CompletableFuture.completedFuture(null); + doReturn(releaseConnectionFuture).when(connection).release(); + + RoutingProcedureResponse response = + TestUtil.await(runner.run(connection, DatabaseNameUtil.defaultDatabase(), null, null)); + + assertNotNull(response); + assertFalse(response.isSuccess()); + assertNotNull(response.procedure()); + assertEquals(reason, response.error()); + assertThrows(IllegalStateException.class, () -> response.records().size()); + + verifyMessageWasWrittenAndFlushed( + connection, completableFuture, RoutingContext.EMPTY, null, DatabaseNameUtil.defaultDatabase()); + verify(connection).release(); } - private void verifyMessageWasWrittenAndFlushed( Connection connection, CompletableFuture> completableFuture, - RoutingContext routingContext, Bookmark bookmark, DatabaseName databaseName ) - { - Map context = routingContext.toMap() - .entrySet() - .stream() - .collect( Collectors.toMap( Map.Entry::getKey, entry -> Values.value( entry.getValue() ) ) ); - - verify( connection ).writeAndFlush( eq( new RouteMessage( context, bookmark, databaseName.databaseName().orElse( null ), null ) ), - eq( new RouteMessageResponseHandler( completableFuture ) ) ); + private void verifyMessageWasWrittenAndFlushed( + Connection connection, + CompletableFuture> completableFuture, + RoutingContext routingContext, + Bookmark bookmark, + DatabaseName databaseName) { + Map context = routingContext.toMap().entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, entry -> Values.value(entry.getValue()))); + + verify(connection) + .writeAndFlush( + eq(new RouteMessage( + context, bookmark, databaseName.databaseName().orElse(null), null)), + eq(new RouteMessageResponseHandler(completableFuture))); } - private Map getRoutingTable() - { - Map routingTable = new HashMap<>(); - routingTable.put( "ttl", Values.value( 300 ) ); - routingTable.put( "servers", Values.value( getServers() ) ); + private Map getRoutingTable() { + Map routingTable = new HashMap<>(); + routingTable.put("ttl", Values.value(300)); + routingTable.put("servers", Values.value(getServers())); return routingTable; } - private List> getServers() - { - List> servers = new ArrayList<>(); - servers.add( getServer( "WRITE", "localhost:17601" ) ); - servers.add( getServer( "READ", "localhost:17601", "localhost:17602", "localhost:17603" ) ); - servers.add( getServer( "ROUTE", "localhost:17601", "localhost:17602", "localhost:17603" ) ); + private List> getServers() { + List> servers = new ArrayList<>(); + servers.add(getServer("WRITE", "localhost:17601")); + servers.add(getServer("READ", "localhost:17601", "localhost:17602", "localhost:17603")); + servers.add(getServer("ROUTE", "localhost:17601", "localhost:17602", "localhost:17603")); return servers; } - private Map getServer( String role, String... addresses ) - { - Map server = new HashMap<>(); - server.put( "role", Values.value( role ) ); - server.put( "addresses", Values.value( addresses ) ); + private Map getServer(String role, String... addresses) { + Map server = new HashMap<>(); + server.put("role", Values.value(role)); + server.put("addresses", Values.value(addresses)); return server; } -} \ No newline at end of file +} diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingContextTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingContextTest.java index f75d95dbeb..946a5994c3 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingContextTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingContextTest.java @@ -18,149 +18,131 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -class RoutingContextTest -{ +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class RoutingContextTest { @Test - void emptyContextIsNotDefined() - { - assertFalse( RoutingContext.EMPTY.isDefined() ); + void emptyContextIsNotDefined() { + assertFalse(RoutingContext.EMPTY.isDefined()); } @Test - void emptyContextInEmptyMap() - { - assertTrue( RoutingContext.EMPTY.toMap().isEmpty() ); + void emptyContextInEmptyMap() { + assertTrue(RoutingContext.EMPTY.toMap().isEmpty()); } @Test - void uriWithoutQueryIsParsedToEmptyContext() - { - testEmptyRoutingContext( URI.create( "neo4j://localhost:7687/" ) ); + void uriWithoutQueryIsParsedToEmptyContext() { + testEmptyRoutingContext(URI.create("neo4j://localhost:7687/")); } @Test - void uriWithEmptyQueryIsParsedToEmptyContext() - { - testEmptyRoutingContext( URI.create( "neo4j://localhost:7687?" ) ); - testEmptyRoutingContext( URI.create( "neo4j://localhost:7687/?" ) ); + void uriWithEmptyQueryIsParsedToEmptyContext() { + testEmptyRoutingContext(URI.create("neo4j://localhost:7687?")); + testEmptyRoutingContext(URI.create("neo4j://localhost:7687/?")); } @Test - void uriWithQueryIsParsed() - { - URI uri = URI.create( "neo4j://localhost:7687/?key1=value1&key2=value2&key3=value3" ); - RoutingContext context = new RoutingContext( uri ); + void uriWithQueryIsParsed() { + URI uri = URI.create("neo4j://localhost:7687/?key1=value1&key2=value2&key3=value3"); + RoutingContext context = new RoutingContext(uri); - assertTrue( context.isDefined() ); - Map expectedMap = new HashMap<>(); - expectedMap.put( "key1", "value1" ); - expectedMap.put( "key2", "value2" ); - expectedMap.put( "key3", "value3" ); - expectedMap.put( "address", "localhost:7687" ); - assertEquals( expectedMap, context.toMap() ); + assertTrue(context.isDefined()); + Map expectedMap = new HashMap<>(); + expectedMap.put("key1", "value1"); + expectedMap.put("key2", "value2"); + expectedMap.put("key3", "value3"); + expectedMap.put("address", "localhost:7687"); + assertEquals(expectedMap, context.toMap()); } @Test - void boltUriDisablesServerSideRouting() - { - URI uri = URI.create( "bolt://localhost:7687/?key1=value1&key2=value2&key3=value3" ); - RoutingContext context = new RoutingContext( uri ); + void boltUriDisablesServerSideRouting() { + URI uri = URI.create("bolt://localhost:7687/?key1=value1&key2=value2&key3=value3"); + RoutingContext context = new RoutingContext(uri); - assertEquals( false, context.isServerRoutingEnabled() ); + assertEquals(false, context.isServerRoutingEnabled()); } @Test - void neo4jUriEnablesServerSideRouting() - { - URI uri = URI.create( "neo4j://localhost:7687/?key1=value1&key2=value2&key3=value3" ); - RoutingContext context = new RoutingContext( uri ); + void neo4jUriEnablesServerSideRouting() { + URI uri = URI.create("neo4j://localhost:7687/?key1=value1&key2=value2&key3=value3"); + RoutingContext context = new RoutingContext(uri); - assertEquals( true, context.isServerRoutingEnabled() ); + assertEquals(true, context.isServerRoutingEnabled()); } @Test - void throwsForInvalidUriQuery() - { - testIllegalUri( URI.create( "neo4j://localhost:7687/?justKey" ) ); + void throwsForInvalidUriQuery() { + testIllegalUri(URI.create("neo4j://localhost:7687/?justKey")); } @Test - void throwsForInvalidUriQueryKey() - { - testIllegalUri( URI.create( "neo4j://localhost:7687/?=value1&key2=value2" ) ); + void throwsForInvalidUriQueryKey() { + testIllegalUri(URI.create("neo4j://localhost:7687/?=value1&key2=value2")); } @Test - void throwsForInvalidUriQueryValue() - { - testIllegalUri( URI.create( "neo4j://localhost:7687/key1?=value1&key2=" ) ); + void throwsForInvalidUriQueryValue() { + testIllegalUri(URI.create("neo4j://localhost:7687/key1?=value1&key2=")); } @Test - void throwsForDuplicatedUriQueryParameters() - { - testIllegalUri( URI.create( "neo4j://localhost:7687/?key1=value1&key2=value2&key1=value2" ) ); + void throwsForDuplicatedUriQueryParameters() { + testIllegalUri(URI.create("neo4j://localhost:7687/?key1=value1&key2=value2&key1=value2")); } @Test - void mapRepresentationIsUnmodifiable() - { - URI uri = URI.create( "neo4j://localhost:7687/?key1=value1" ); - RoutingContext context = new RoutingContext( uri ); + void mapRepresentationIsUnmodifiable() { + URI uri = URI.create("neo4j://localhost:7687/?key1=value1"); + RoutingContext context = new RoutingContext(uri); - Map expectedMap = new HashMap<>(); - expectedMap.put( "key1", "value1" ); - expectedMap.put( "address", "localhost:7687" ); + Map expectedMap = new HashMap<>(); + expectedMap.put("key1", "value1"); + expectedMap.put("address", "localhost:7687"); - assertEquals( expectedMap, context.toMap() ); + assertEquals(expectedMap, context.toMap()); - assertThrows( UnsupportedOperationException.class, () -> context.toMap().put( "key2", "value2" ) ); - assertEquals( expectedMap, context.toMap() ); + assertThrows(UnsupportedOperationException.class, () -> context.toMap().put("key2", "value2")); + assertEquals(expectedMap, context.toMap()); } @Test - void populateAddressWithDefaultPort() - { - URI uri = URI.create( "neo4j://localhost/" ); - RoutingContext context = new RoutingContext( uri ); + void populateAddressWithDefaultPort() { + URI uri = URI.create("neo4j://localhost/"); + RoutingContext context = new RoutingContext(uri); - assertEquals( singletonMap( "address", "localhost:7687" ), context.toMap() ); + assertEquals(singletonMap("address", "localhost:7687"), context.toMap()); } @Test - void throwsExceptionIfAddressIsUsedInContext() - { - URI uri = URI.create( "neo4j://localhost:7687/?key1=value1&address=someaddress:9010" ); + void throwsExceptionIfAddressIsUsedInContext() { + URI uri = URI.create("neo4j://localhost:7687/?key1=value1&address=someaddress:9010"); - IllegalArgumentException e = assertThrows( IllegalArgumentException.class, () -> new RoutingContext( uri ) ); - assertEquals( "The key 'address' is reserved for routing context.", e.getMessage() ); + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> new RoutingContext(uri)); + assertEquals("The key 'address' is reserved for routing context.", e.getMessage()); } - private static void testIllegalUri( URI uri ) - { - assertThrows( IllegalArgumentException.class, () -> new RoutingContext( uri ) ); + private static void testIllegalUri(URI uri) { + assertThrows(IllegalArgumentException.class, () -> new RoutingContext(uri)); } - private static void testEmptyRoutingContext( URI uri ) - { - RoutingContext context = new RoutingContext( uri ); + private static void testEmptyRoutingContext(URI uri) { + RoutingContext context = new RoutingContext(uri); - Map expectedMap = new HashMap<>(); - expectedMap.put( "address", "localhost:7687" ); + Map expectedMap = new HashMap<>(); + expectedMap.put("address", "localhost:7687"); - assertFalse( context.isDefined() ); - assertEquals( singletonMap( "address", "localhost:7687" ), context.toMap() ); + assertFalse(context.isDefined()); + assertEquals(singletonMap("address", "localhost:7687"), context.toMap()); } } 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 d2cc5b3750..7a68b1d035 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 @@ -18,13 +18,29 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.InternalBookmark.empty; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; +import static org.neo4j.driver.internal.util.Futures.failedFuture; +import static org.neo4j.driver.util.TestUtil.await; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -42,411 +58,369 @@ import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.internal.value.StringValue; -import static java.util.Arrays.asList; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.InternalBookmark.empty; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import static org.neo4j.driver.internal.util.Futures.failedFuture; -import static org.neo4j.driver.util.TestUtil.await; - -class RoutingProcedureClusterCompositionProviderTest -{ +class RoutingProcedureClusterCompositionProviderTest { @Test - void shouldProtocolErrorWhenNoRecord() - { + void shouldProtocolErrorWhenNoRecord() { // Given SingleDatabaseRoutingProcedureRunner mockedRunner = newProcedureRunnerMock(); - Connection connection = mock( Connection.class ); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection ); + Connection connection = mock(Connection.class); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection); RoutingProcedureResponse noRecordsResponse = newRoutingResponse(); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( noRecordsResponse ) ); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(noRecordsResponse)); // When & Then - ProtocolException error = assertThrows( ProtocolException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertThat( error.getMessage(), containsString( "records received '0' is too few or too many." ) ); + ProtocolException error = assertThrows( + ProtocolException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertThat(error.getMessage(), containsString("records received '0' is too few or too many.")); } @Test - void shouldProtocolErrorWhenMoreThanOneRecord() - { + void shouldProtocolErrorWhenMoreThanOneRecord() { // Given SingleDatabaseRoutingProcedureRunner mockedRunner = newProcedureRunnerMock(); - Connection connection = mock( Connection.class ); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection ); + Connection connection = mock(Connection.class); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection); - Record aRecord = new InternalRecord( asList( "key1", "key2" ), new Value[]{new StringValue( "a value" )} ); - RoutingProcedureResponse routingResponse = newRoutingResponse( aRecord, aRecord ); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( routingResponse ) ); + Record aRecord = new InternalRecord(asList("key1", "key2"), new Value[] {new StringValue("a value")}); + RoutingProcedureResponse routingResponse = newRoutingResponse(aRecord, aRecord); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(routingResponse)); // When - ProtocolException error = assertThrows( ProtocolException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertThat( error.getMessage(), containsString( "records received '2' is too few or too many." ) ); + ProtocolException error = assertThrows( + ProtocolException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertThat(error.getMessage(), containsString("records received '2' is too few or too many.")); } @Test - void shouldProtocolErrorWhenUnparsableRecord() - { + void shouldProtocolErrorWhenUnparsableRecord() { // Given SingleDatabaseRoutingProcedureRunner mockedRunner = newProcedureRunnerMock(); - Connection connection = mock( Connection.class ); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection ); + Connection connection = mock(Connection.class); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection); - Record aRecord = new InternalRecord( asList( "key1", "key2" ), new Value[]{new StringValue( "a value" )} ); - RoutingProcedureResponse routingResponse = newRoutingResponse( aRecord ); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( routingResponse ) ); + Record aRecord = new InternalRecord(asList("key1", "key2"), new Value[] {new StringValue("a value")}); + RoutingProcedureResponse routingResponse = newRoutingResponse(aRecord); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(routingResponse)); // When - ProtocolException error = assertThrows( ProtocolException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertThat( error.getMessage(), containsString( "unparsable record received." ) ); + ProtocolException error = assertThrows( + ProtocolException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertThat(error.getMessage(), containsString("unparsable record received.")); } @Test - void shouldProtocolErrorWhenNoRouters() - { + void shouldProtocolErrorWhenNoRouters() { // Given MultiDatabasesRoutingProcedureRunner mockedRunner = newMultiDBProcedureRunnerMock(); - Connection connection = mock( Connection.class ); - Clock mockedClock = mock( Clock.class ); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection, mockedClock ); - - Record record = new InternalRecord( asList( "ttl", "servers" ), new Value[]{ - value( 100 ), value( asList( - serverInfo( "READ", "one:1337", "two:1337" ), - serverInfo( "WRITE", "one:1337" ) ) ) - } ); - RoutingProcedureResponse routingResponse = newRoutingResponse( record ); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( routingResponse ) ); - when( mockedClock.millis() ).thenReturn( 12345L ); + Connection connection = mock(Connection.class); + Clock mockedClock = mock(Clock.class); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection, mockedClock); + + Record record = new InternalRecord(asList("ttl", "servers"), new Value[] { + value(100), value(asList(serverInfo("READ", "one:1337", "two:1337"), serverInfo("WRITE", "one:1337"))) + }); + RoutingProcedureResponse routingResponse = newRoutingResponse(record); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(routingResponse)); + when(mockedClock.millis()).thenReturn(12345L); // When - ProtocolException error = assertThrows( ProtocolException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertThat( error.getMessage(), containsString( "no router or reader found in response." ) ); + ProtocolException error = assertThrows( + ProtocolException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertThat(error.getMessage(), containsString("no router or reader found in response.")); } @Test - void routeMessageRoutingProcedureShouldProtocolErrorWhenNoRouters() - { + void routeMessageRoutingProcedureShouldProtocolErrorWhenNoRouters() { // Given RouteMessageRoutingProcedureRunner mockedRunner = newRouteMessageRoutingProcedureRunnerMock(); - Connection connection = mock( Connection.class ); - Clock mockedClock = mock( Clock.class ); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection, mockedClock ); - - Record record = new InternalRecord( asList( "ttl", "servers" ), new Value[]{ - value( 100 ), value( asList( - serverInfo( "READ", "one:1337", "two:1337" ), - serverInfo( "WRITE", "one:1337" ) ) ) - } ); - RoutingProcedureResponse routingResponse = newRoutingResponse( record ); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( routingResponse ) ); - when( mockedClock.millis() ).thenReturn( 12345L ); + Connection connection = mock(Connection.class); + Clock mockedClock = mock(Clock.class); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection, mockedClock); + + Record record = new InternalRecord(asList("ttl", "servers"), new Value[] { + value(100), value(asList(serverInfo("READ", "one:1337", "two:1337"), serverInfo("WRITE", "one:1337"))) + }); + RoutingProcedureResponse routingResponse = newRoutingResponse(record); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(routingResponse)); + when(mockedClock.millis()).thenReturn(12345L); // When - ProtocolException error = assertThrows( ProtocolException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertThat( error.getMessage(), containsString( "no router or reader found in response." ) ); + ProtocolException error = assertThrows( + ProtocolException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertThat(error.getMessage(), containsString("no router or reader found in response.")); } @Test - void shouldProtocolErrorWhenNoReaders() - { + void shouldProtocolErrorWhenNoReaders() { // Given MultiDatabasesRoutingProcedureRunner mockedRunner = newMultiDBProcedureRunnerMock(); - Connection connection = mock( Connection.class ); - Clock mockedClock = mock( Clock.class ); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection, mockedClock ); - - Record record = new InternalRecord( asList( "ttl", "servers" ), new Value[]{ - value( 100 ), value( asList( - serverInfo( "WRITE", "one:1337" ), - serverInfo( "ROUTE", "one:1337", "two:1337" ) ) ) - } ); - RoutingProcedureResponse routingResponse = newRoutingResponse( record ); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( routingResponse ) ); - when( mockedClock.millis() ).thenReturn( 12345L ); + Connection connection = mock(Connection.class); + Clock mockedClock = mock(Clock.class); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection, mockedClock); + + Record record = new InternalRecord(asList("ttl", "servers"), new Value[] { + value(100), value(asList(serverInfo("WRITE", "one:1337"), serverInfo("ROUTE", "one:1337", "two:1337"))) + }); + RoutingProcedureResponse routingResponse = newRoutingResponse(record); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(routingResponse)); + when(mockedClock.millis()).thenReturn(12345L); // When - ProtocolException error = assertThrows( ProtocolException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertThat( error.getMessage(), containsString( "no router or reader found in response." ) ); + ProtocolException error = assertThrows( + ProtocolException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertThat(error.getMessage(), containsString("no router or reader found in response.")); } @Test - void routeMessageRoutingProcedureShouldProtocolErrorWhenNoReaders() - { + void routeMessageRoutingProcedureShouldProtocolErrorWhenNoReaders() { // Given RouteMessageRoutingProcedureRunner mockedRunner = newRouteMessageRoutingProcedureRunnerMock(); - Connection connection = mock( Connection.class ); - Clock mockedClock = mock( Clock.class ); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection, mockedClock ); - - Record record = new InternalRecord( asList( "ttl", "servers" ), new Value[]{ - value( 100 ), value( asList( - serverInfo( "WRITE", "one:1337" ), - serverInfo( "ROUTE", "one:1337", "two:1337" ) ) ) - } ); - RoutingProcedureResponse routingResponse = newRoutingResponse( record ); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( routingResponse ) ); - when( mockedClock.millis() ).thenReturn( 12345L ); + Connection connection = mock(Connection.class); + Clock mockedClock = mock(Clock.class); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection, mockedClock); + + Record record = new InternalRecord(asList("ttl", "servers"), new Value[] { + value(100), value(asList(serverInfo("WRITE", "one:1337"), serverInfo("ROUTE", "one:1337", "two:1337"))) + }); + RoutingProcedureResponse routingResponse = newRoutingResponse(record); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(routingResponse)); + when(mockedClock.millis()).thenReturn(12345L); // When - ProtocolException error = assertThrows( ProtocolException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertThat( error.getMessage(), containsString( "no router or reader found in response." ) ); + ProtocolException error = assertThrows( + ProtocolException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertThat(error.getMessage(), containsString("no router or reader found in response.")); } @Test - void shouldPropagateConnectionFailureExceptions() - { + void shouldPropagateConnectionFailureExceptions() { // Given SingleDatabaseRoutingProcedureRunner mockedRunner = newProcedureRunnerMock(); - Connection connection = mock( Connection.class ); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection ); + Connection connection = mock(Connection.class); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( failedFuture( new ServiceUnavailableException( "Connection breaks during cypher execution" ) ) ); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(failedFuture(new ServiceUnavailableException("Connection breaks during cypher execution"))); // When & Then - ServiceUnavailableException e = assertThrows( ServiceUnavailableException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertThat( e.getMessage(), containsString( "Connection breaks during cypher execution" ) ); + ServiceUnavailableException e = assertThrows( + ServiceUnavailableException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertThat(e.getMessage(), containsString("Connection breaks during cypher execution")); } @Test - void shouldReturnSuccessResultWhenNoError() - { + void shouldReturnSuccessResultWhenNoError() { // Given - Clock mockedClock = mock( Clock.class ); - Connection connection = mock( Connection.class ); + Clock mockedClock = mock(Clock.class); + Connection connection = mock(Connection.class); MultiDatabasesRoutingProcedureRunner mockedRunner = newMultiDBProcedureRunnerMock(); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection, mockedClock ); - - Record record = new InternalRecord( asList( "ttl", "servers" ), new Value[]{ - value( 100 ), value( asList( - serverInfo( "READ", "one:1337", "two:1337" ), - serverInfo( "WRITE", "one:1337" ), - serverInfo( "ROUTE", "one:1337", "two:1337" ) ) ) - } ); - RoutingProcedureResponse routingResponse = newRoutingResponse( record ); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( routingResponse ) ); - when( mockedClock.millis() ).thenReturn( 12345L ); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection, mockedClock); + + Record record = new InternalRecord(asList("ttl", "servers"), new Value[] { + value(100), + value(asList( + serverInfo("READ", "one:1337", "two:1337"), + serverInfo("WRITE", "one:1337"), + serverInfo("ROUTE", "one:1337", "two:1337"))) + }); + RoutingProcedureResponse routingResponse = newRoutingResponse(record); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(routingResponse)); + when(mockedClock.millis()).thenReturn(12345L); // When - ClusterComposition cluster = await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ); + ClusterComposition cluster = + await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null)); // Then - assertEquals( 12345 + 100_000, cluster.expirationTimestamp() ); - assertEquals( serverSet( "one:1337", "two:1337" ), cluster.readers() ); - assertEquals( serverSet( "one:1337" ), cluster.writers() ); - assertEquals( serverSet( "one:1337", "two:1337" ), cluster.routers() ); + assertEquals(12345 + 100_000, cluster.expirationTimestamp()); + assertEquals(serverSet("one:1337", "two:1337"), cluster.readers()); + assertEquals(serverSet("one:1337"), cluster.writers()); + assertEquals(serverSet("one:1337", "two:1337"), cluster.routers()); } @Test - void routeMessageRoutingProcedureShouldReturnSuccessResultWhenNoError() - { + void routeMessageRoutingProcedureShouldReturnSuccessResultWhenNoError() { // Given - Clock mockedClock = mock( Clock.class ); - Connection connection = mock( Connection.class ); + Clock mockedClock = mock(Clock.class); + Connection connection = mock(Connection.class); RouteMessageRoutingProcedureRunner mockedRunner = newRouteMessageRoutingProcedureRunnerMock(); - ClusterCompositionProvider provider = - newClusterCompositionProvider( mockedRunner, connection, mockedClock ); - - Record record = new InternalRecord( asList( "ttl", "servers" ), new Value[]{ - value( 100 ), value( asList( - serverInfo( "READ", "one:1337", "two:1337" ), - serverInfo( "WRITE", "one:1337" ), - serverInfo( "ROUTE", "one:1337", "two:1337" ) ) ) - } ); - RoutingProcedureResponse routingResponse = newRoutingResponse( record ); - when( mockedRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( routingResponse ) ); - when( mockedClock.millis() ).thenReturn( 12345L ); + ClusterCompositionProvider provider = newClusterCompositionProvider(mockedRunner, connection, mockedClock); + + Record record = new InternalRecord(asList("ttl", "servers"), new Value[] { + value(100), + value(asList( + serverInfo("READ", "one:1337", "two:1337"), + serverInfo("WRITE", "one:1337"), + serverInfo("ROUTE", "one:1337", "two:1337"))) + }); + RoutingProcedureResponse routingResponse = newRoutingResponse(record); + when(mockedRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(routingResponse)); + when(mockedClock.millis()).thenReturn(12345L); // When - ClusterComposition cluster = await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ); + ClusterComposition cluster = + await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null)); // Then - assertEquals( 12345 + 100_000, cluster.expirationTimestamp() ); - assertEquals( serverSet( "one:1337", "two:1337" ), cluster.readers() ); - assertEquals( serverSet( "one:1337" ), cluster.writers() ); - assertEquals( serverSet( "one:1337", "two:1337" ), cluster.routers() ); + assertEquals(12345 + 100_000, cluster.expirationTimestamp()); + assertEquals(serverSet("one:1337", "two:1337"), cluster.readers()); + assertEquals(serverSet("one:1337"), cluster.writers()); + assertEquals(serverSet("one:1337", "two:1337"), cluster.routers()); } @Test - void shouldReturnFailureWhenProcedureRunnerFails() - { + void shouldReturnFailureWhenProcedureRunnerFails() { SingleDatabaseRoutingProcedureRunner procedureRunner = newProcedureRunnerMock(); - Connection connection = mock( Connection.class ); + Connection connection = mock(Connection.class); - RuntimeException error = new RuntimeException( "hi" ); - when( procedureRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( newRoutingResponse( error ) ) ); + RuntimeException error = new RuntimeException("hi"); + when(procedureRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(newRoutingResponse(error))); RoutingProcedureClusterCompositionProvider provider = - newClusterCompositionProvider( procedureRunner, connection ); + newClusterCompositionProvider(procedureRunner, connection); - RuntimeException e = assertThrows( RuntimeException.class, - () -> await( provider.getClusterComposition( connection, defaultDatabase(), empty(), null ) ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows( + RuntimeException.class, + () -> await(provider.getClusterComposition(connection, defaultDatabase(), empty(), null))); + assertEquals(error, e); } @Test - void shouldUseMultiDBProcedureRunnerWhenConnectingWith40Server() throws Throwable - { + void shouldUseMultiDBProcedureRunnerWhenConnectingWith40Server() throws Throwable { MultiDatabasesRoutingProcedureRunner procedureRunner = newMultiDBProcedureRunnerMock(); - Connection connection = mock( Connection.class ); + Connection connection = mock(Connection.class); RoutingProcedureClusterCompositionProvider provider = - newClusterCompositionProvider( procedureRunner, connection ); + newClusterCompositionProvider(procedureRunner, connection); - when( procedureRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ).thenReturn( completedWithNull() ); - provider.getClusterComposition( connection, defaultDatabase(), empty(), null ); + when(procedureRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedWithNull()); + provider.getClusterComposition(connection, defaultDatabase(), empty(), null); - verify( procedureRunner ).run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ); + verify(procedureRunner).run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any()); } @Test - void shouldUseProcedureRunnerWhenConnectingWith35AndPreviousServers() throws Throwable - { + void shouldUseProcedureRunnerWhenConnectingWith35AndPreviousServers() throws Throwable { SingleDatabaseRoutingProcedureRunner procedureRunner = newProcedureRunnerMock(); - Connection connection = mock( Connection.class ); + Connection connection = mock(Connection.class); RoutingProcedureClusterCompositionProvider provider = - newClusterCompositionProvider( procedureRunner, connection ); + newClusterCompositionProvider(procedureRunner, connection); - when( procedureRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ).thenReturn( completedWithNull() ); - provider.getClusterComposition( connection, defaultDatabase(), empty(), null ); + when(procedureRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedWithNull()); + provider.getClusterComposition(connection, defaultDatabase(), empty(), null); - verify( procedureRunner ).run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ); + verify(procedureRunner).run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any()); } @Test - void shouldUseRouteMessageProcedureRunnerWhenConnectingWithProtocol43() throws Throwable - { + void shouldUseRouteMessageProcedureRunnerWhenConnectingWithProtocol43() throws Throwable { RouteMessageRoutingProcedureRunner procedureRunner = newRouteMessageRoutingProcedureRunnerMock(); - Connection connection = mock( Connection.class ); + Connection connection = mock(Connection.class); RoutingProcedureClusterCompositionProvider provider = - newClusterCompositionProvider( procedureRunner, connection ); + newClusterCompositionProvider(procedureRunner, connection); - when( procedureRunner.run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ) ).thenReturn( completedWithNull() ); - provider.getClusterComposition( connection, defaultDatabase(), empty(), null ); + when(procedureRunner.run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any())) + .thenReturn(completedWithNull()); + provider.getClusterComposition(connection, defaultDatabase(), empty(), null); - verify( procedureRunner ).run( eq( connection ), any( DatabaseName.class ), any( InternalBookmark.class ), any() ); + verify(procedureRunner).run(eq(connection), any(DatabaseName.class), any(InternalBookmark.class), any()); } - private static Map serverInfo( String role, String... addresses ) - { - Map map = new HashMap<>(); - map.put( "role", role ); - map.put( "addresses", asList( addresses ) ); + private static Map serverInfo(String role, String... addresses) { + Map map = new HashMap<>(); + map.put("role", role); + map.put("addresses", asList(addresses)); return map; } - private static Set serverSet( String... addresses ) - { + private static Set serverSet(String... addresses) { Set result = new HashSet<>(); - for ( String address : addresses ) - { - result.add( new BoltServerAddress( address ) ); + for (String address : addresses) { + result.add(new BoltServerAddress(address)); } return result; } - private static SingleDatabaseRoutingProcedureRunner newProcedureRunnerMock() - { - return mock( SingleDatabaseRoutingProcedureRunner.class ); + private static SingleDatabaseRoutingProcedureRunner newProcedureRunnerMock() { + return mock(SingleDatabaseRoutingProcedureRunner.class); } - private static MultiDatabasesRoutingProcedureRunner newMultiDBProcedureRunnerMock() - { - return mock( MultiDatabasesRoutingProcedureRunner.class ); + private static MultiDatabasesRoutingProcedureRunner newMultiDBProcedureRunnerMock() { + return mock(MultiDatabasesRoutingProcedureRunner.class); } - private static RouteMessageRoutingProcedureRunner newRouteMessageRoutingProcedureRunnerMock() - { - return mock( RouteMessageRoutingProcedureRunner.class ); + private static RouteMessageRoutingProcedureRunner newRouteMessageRoutingProcedureRunnerMock() { + return mock(RouteMessageRoutingProcedureRunner.class); } - private static RoutingProcedureResponse newRoutingResponse( Record... records ) - { - return new RoutingProcedureResponse( new Query( "procedure" ), asList( records ) ); + private static RoutingProcedureResponse newRoutingResponse(Record... records) { + return new RoutingProcedureResponse(new Query("procedure"), asList(records)); } - private static RoutingProcedureResponse newRoutingResponse( Throwable error ) - { - return new RoutingProcedureResponse( new Query( "procedure" ), error ); + private static RoutingProcedureResponse newRoutingResponse(Throwable error) { + return new RoutingProcedureResponse(new Query("procedure"), error); } - private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( SingleDatabaseRoutingProcedureRunner runner, - Connection connection ) - { - when( connection.serverVersion() ).thenReturn( ServerVersion.v3_5_0 ); - when( connection.protocol() ).thenReturn( BoltProtocolV3.INSTANCE ); - return new RoutingProcedureClusterCompositionProvider( mock( Clock.class ), runner, newMultiDBProcedureRunnerMock(), - newRouteMessageRoutingProcedureRunnerMock() ); + private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( + SingleDatabaseRoutingProcedureRunner runner, Connection connection) { + when(connection.serverVersion()).thenReturn(ServerVersion.v3_5_0); + when(connection.protocol()).thenReturn(BoltProtocolV3.INSTANCE); + return new RoutingProcedureClusterCompositionProvider( + mock(Clock.class), + runner, + newMultiDBProcedureRunnerMock(), + newRouteMessageRoutingProcedureRunnerMock()); } - private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( MultiDatabasesRoutingProcedureRunner runner, - Connection connection ) - { - when( connection.serverVersion() ).thenReturn( ServerVersion.v4_0_0 ); - when( connection.protocol() ).thenReturn( BoltProtocolV4.INSTANCE ); - return new RoutingProcedureClusterCompositionProvider( mock( Clock.class ), newProcedureRunnerMock(), runner, - newRouteMessageRoutingProcedureRunnerMock() ); + private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( + MultiDatabasesRoutingProcedureRunner runner, Connection connection) { + when(connection.serverVersion()).thenReturn(ServerVersion.v4_0_0); + when(connection.protocol()).thenReturn(BoltProtocolV4.INSTANCE); + return new RoutingProcedureClusterCompositionProvider( + mock(Clock.class), newProcedureRunnerMock(), runner, newRouteMessageRoutingProcedureRunnerMock()); } - private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( MultiDatabasesRoutingProcedureRunner runner, Connection connection, - Clock clock ) - { - when( connection.serverVersion() ).thenReturn( ServerVersion.v4_0_0 ); - when( connection.protocol() ).thenReturn( BoltProtocolV4.INSTANCE ); - return new RoutingProcedureClusterCompositionProvider( clock, newProcedureRunnerMock(), runner, newRouteMessageRoutingProcedureRunnerMock() ); + private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( + MultiDatabasesRoutingProcedureRunner runner, Connection connection, Clock clock) { + when(connection.serverVersion()).thenReturn(ServerVersion.v4_0_0); + when(connection.protocol()).thenReturn(BoltProtocolV4.INSTANCE); + return new RoutingProcedureClusterCompositionProvider( + clock, newProcedureRunnerMock(), runner, newRouteMessageRoutingProcedureRunnerMock()); } - private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( RouteMessageRoutingProcedureRunner runner, Connection connection ) - { + private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( + RouteMessageRoutingProcedureRunner runner, Connection connection) { - return newClusterCompositionProvider( runner, connection, mock( Clock.class ) ); + return newClusterCompositionProvider(runner, connection, mock(Clock.class)); } - private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( RouteMessageRoutingProcedureRunner runner, - Connection connection, Clock clock ) - { - when( connection.protocol() ).thenReturn( BoltProtocolV43.INSTANCE ); - return new RoutingProcedureClusterCompositionProvider( clock, newProcedureRunnerMock(), newMultiDBProcedureRunnerMock(), runner ); + private static RoutingProcedureClusterCompositionProvider newClusterCompositionProvider( + RouteMessageRoutingProcedureRunner runner, Connection connection, Clock clock) { + when(connection.protocol()).thenReturn(BoltProtocolV43.INSTANCE); + return new RoutingProcedureClusterCompositionProvider( + clock, newProcedureRunnerMock(), newMultiDBProcedureRunnerMock(), runner); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureResponseTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureResponseTest.java index aaae4b4003..4fcc2c5bab 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureResponseTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureResponseTest.java @@ -18,80 +18,71 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.InternalRecord; -import org.neo4j.driver.internal.value.StringValue; -import org.neo4j.driver.Record; -import org.neo4j.driver.Query; -import org.neo4j.driver.Value; - import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -class RoutingProcedureResponseTest -{ - private static final Query PROCEDURE = new Query( "procedure" ); +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.InternalRecord; +import org.neo4j.driver.internal.value.StringValue; + +class RoutingProcedureResponseTest { + private static final Query PROCEDURE = new Query("procedure"); - private static final Record RECORD_1 = new InternalRecord( asList( "a", "b" ), - new Value[]{new StringValue( "a" ), new StringValue( "b" )} ); - private static final Record RECORD_2 = new InternalRecord( asList( "a", "b" ), - new Value[]{new StringValue( "aa" ), new StringValue( "bb" )} ); + private static final Record RECORD_1 = + new InternalRecord(asList("a", "b"), new Value[] {new StringValue("a"), new StringValue("b")}); + private static final Record RECORD_2 = + new InternalRecord(asList("a", "b"), new Value[] {new StringValue("aa"), new StringValue("bb")}); @Test - void shouldBeSuccessfulWithRecords() - { - RoutingProcedureResponse response = new RoutingProcedureResponse( PROCEDURE, asList( RECORD_1, RECORD_2 ) ); - assertTrue( response.isSuccess() ); + void shouldBeSuccessfulWithRecords() { + RoutingProcedureResponse response = new RoutingProcedureResponse(PROCEDURE, asList(RECORD_1, RECORD_2)); + assertTrue(response.isSuccess()); } @Test - void shouldNotBeSuccessfulWithError() - { - RoutingProcedureResponse response = new RoutingProcedureResponse( PROCEDURE, new RuntimeException() ); - assertFalse( response.isSuccess() ); + void shouldNotBeSuccessfulWithError() { + RoutingProcedureResponse response = new RoutingProcedureResponse(PROCEDURE, new RuntimeException()); + assertFalse(response.isSuccess()); } @Test - void shouldThrowWhenFailedAndAskedForRecords() - { + void shouldThrowWhenFailedAndAskedForRecords() { RuntimeException error = new RuntimeException(); - RoutingProcedureResponse response = new RoutingProcedureResponse( PROCEDURE, error ); + RoutingProcedureResponse response = new RoutingProcedureResponse(PROCEDURE, error); - IllegalStateException e = assertThrows( IllegalStateException.class, response::records ); - assertEquals( e.getCause(), error ); + IllegalStateException e = assertThrows(IllegalStateException.class, response::records); + assertEquals(e.getCause(), error); } @Test - void shouldThrowWhenSuccessfulAndAskedForError() - { - RoutingProcedureResponse response = new RoutingProcedureResponse( PROCEDURE, asList( RECORD_1, RECORD_2 ) ); + void shouldThrowWhenSuccessfulAndAskedForError() { + RoutingProcedureResponse response = new RoutingProcedureResponse(PROCEDURE, asList(RECORD_1, RECORD_2)); - assertThrows( IllegalStateException.class, response::error ); + assertThrows(IllegalStateException.class, response::error); } @Test - void shouldHaveErrorWhenFailed() - { - RuntimeException error = new RuntimeException( "Hi!" ); - RoutingProcedureResponse response = new RoutingProcedureResponse( PROCEDURE, error ); - assertEquals( error, response.error() ); + void shouldHaveErrorWhenFailed() { + RuntimeException error = new RuntimeException("Hi!"); + RoutingProcedureResponse response = new RoutingProcedureResponse(PROCEDURE, error); + assertEquals(error, response.error()); } @Test - void shouldHaveRecordsWhenSuccessful() - { - RoutingProcedureResponse response = new RoutingProcedureResponse( PROCEDURE, asList( RECORD_1, RECORD_2 ) ); - assertEquals( asList( RECORD_1, RECORD_2 ), response.records() ); + void shouldHaveRecordsWhenSuccessful() { + RoutingProcedureResponse response = new RoutingProcedureResponse(PROCEDURE, asList(RECORD_1, RECORD_2)); + assertEquals(asList(RECORD_1, RECORD_2), response.records()); } @Test - void shouldHaveProcedure() - { - RoutingProcedureResponse response = new RoutingProcedureResponse( PROCEDURE, asList( RECORD_1, RECORD_2 ) ); - assertEquals( PROCEDURE, response.procedure() ); + void shouldHaveProcedure() { + RoutingProcedureResponse response = new RoutingProcedureResponse(PROCEDURE, asList(RECORD_1, RECORD_2)); + assertEquals(PROCEDURE, response.procedure()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerTest.java index e732068e40..52591a8fb0 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerTest.java @@ -18,27 +18,6 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletionStage; - -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.exceptions.ServiceUnavailableException; -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.DatabaseName; -import org.neo4j.driver.internal.InternalBookmark; -import org.neo4j.driver.internal.async.ConnectionContext; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.FakeClock; -import org.neo4j.driver.internal.util.Futures; - import static java.util.Arrays.asList; import static java.util.Collections.emptySet; import static java.util.Collections.singletonList; @@ -70,252 +49,262 @@ import static org.neo4j.driver.util.TestUtil.asOrderedSet; import static org.neo4j.driver.util.TestUtil.await; -class RoutingTableHandlerTest -{ - @Test - void shouldRemoveAddressFromRoutingTableOnConnectionFailure() - { - RoutingTable routingTable = new ClusterRoutingTable( defaultDatabase(), new FakeClock() ); - routingTable.update( new ClusterComposition( - 42, asOrderedSet( A, B, C ), asOrderedSet( A, C, E ), asOrderedSet( B, D, F ), null ) ); +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CompletionStage; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.exceptions.ServiceUnavailableException; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.DatabaseName; +import org.neo4j.driver.internal.InternalBookmark; +import org.neo4j.driver.internal.async.ConnectionContext; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionPool; +import org.neo4j.driver.internal.util.FakeClock; +import org.neo4j.driver.internal.util.Futures; - RoutingTableHandler handler = newRoutingTableHandler( routingTable, newRediscoveryMock(), newConnectionPoolMock() ); +class RoutingTableHandlerTest { + @Test + void shouldRemoveAddressFromRoutingTableOnConnectionFailure() { + RoutingTable routingTable = new ClusterRoutingTable(defaultDatabase(), new FakeClock()); + routingTable.update( + new ClusterComposition(42, asOrderedSet(A, B, C), asOrderedSet(A, C, E), asOrderedSet(B, D, F), null)); + RoutingTableHandler handler = + newRoutingTableHandler(routingTable, newRediscoveryMock(), newConnectionPoolMock()); - handler.onConnectionFailure( B ); + handler.onConnectionFailure(B); - assertArrayEquals( new BoltServerAddress[]{A, C}, routingTable.readers().toArray() ); - assertArrayEquals( new BoltServerAddress[]{A, C, E}, routingTable.writers().toArray() ); - assertArrayEquals( new BoltServerAddress[]{D, F}, routingTable.routers().toArray() ); + assertArrayEquals(new BoltServerAddress[] {A, C}, routingTable.readers().toArray()); + assertArrayEquals( + new BoltServerAddress[] {A, C, E}, routingTable.writers().toArray()); + assertArrayEquals(new BoltServerAddress[] {D, F}, routingTable.routers().toArray()); - handler.onConnectionFailure( A ); + handler.onConnectionFailure(A); - assertArrayEquals( new BoltServerAddress[]{C}, routingTable.readers().toArray() ); - assertArrayEquals( new BoltServerAddress[]{C, E}, routingTable.writers().toArray() ); - assertArrayEquals( new BoltServerAddress[]{D, F}, routingTable.routers().toArray() ); + assertArrayEquals(new BoltServerAddress[] {C}, routingTable.readers().toArray()); + assertArrayEquals(new BoltServerAddress[] {C, E}, routingTable.writers().toArray()); + assertArrayEquals(new BoltServerAddress[] {D, F}, routingTable.routers().toArray()); } @Test - void acquireShouldUpdateRoutingTableWhenKnownRoutingTableIsStale() - { - BoltServerAddress initialRouter = new BoltServerAddress( "initialRouter", 1 ); - BoltServerAddress reader1 = new BoltServerAddress( "reader-1", 2 ); - BoltServerAddress reader2 = new BoltServerAddress( "reader-1", 3 ); - BoltServerAddress writer1 = new BoltServerAddress( "writer-1", 4 ); - BoltServerAddress router1 = new BoltServerAddress( "router-1", 5 ); + void acquireShouldUpdateRoutingTableWhenKnownRoutingTableIsStale() { + BoltServerAddress initialRouter = new BoltServerAddress("initialRouter", 1); + BoltServerAddress reader1 = new BoltServerAddress("reader-1", 2); + BoltServerAddress reader2 = new BoltServerAddress("reader-1", 3); + BoltServerAddress writer1 = new BoltServerAddress("writer-1", 4); + BoltServerAddress router1 = new BoltServerAddress("router-1", 5); ConnectionPool connectionPool = newConnectionPoolMock(); - ClusterRoutingTable routingTable = new ClusterRoutingTable( defaultDatabase(), new FakeClock(), initialRouter ); - - Set readers = new LinkedHashSet<>( asList( reader1, reader2 ) ); - Set writers = new LinkedHashSet<>( singletonList( writer1 ) ); - Set routers = new LinkedHashSet<>( singletonList( router1 ) ); - ClusterComposition clusterComposition = new ClusterComposition( 42, readers, writers, routers, null ); - Rediscovery rediscovery = mock( RediscoveryImpl.class ); - when( rediscovery.lookupClusterComposition( eq( routingTable ), eq( connectionPool ), any(), any() ) ) - .thenReturn( completedFuture( new ClusterCompositionLookupResult( clusterComposition ) ) ); - - RoutingTableHandler handler = newRoutingTableHandler( routingTable, rediscovery, connectionPool ); - - assertNotNull( await( handler.ensureRoutingTable( simple( false ) ) ) ); - - verify( rediscovery ).lookupClusterComposition( eq( routingTable ), eq( connectionPool ), any(), any() ); - assertArrayEquals( new BoltServerAddress[]{reader1, reader2}, routingTable.readers().toArray() ); - assertArrayEquals( new BoltServerAddress[]{writer1}, routingTable.writers().toArray() ); - assertArrayEquals( new BoltServerAddress[]{router1}, routingTable.routers().toArray() ); + ClusterRoutingTable routingTable = new ClusterRoutingTable(defaultDatabase(), new FakeClock(), initialRouter); + + Set readers = new LinkedHashSet<>(asList(reader1, reader2)); + Set writers = new LinkedHashSet<>(singletonList(writer1)); + Set routers = new LinkedHashSet<>(singletonList(router1)); + ClusterComposition clusterComposition = new ClusterComposition(42, readers, writers, routers, null); + Rediscovery rediscovery = mock(RediscoveryImpl.class); + when(rediscovery.lookupClusterComposition(eq(routingTable), eq(connectionPool), any(), any())) + .thenReturn(completedFuture(new ClusterCompositionLookupResult(clusterComposition))); + + RoutingTableHandler handler = newRoutingTableHandler(routingTable, rediscovery, connectionPool); + + assertNotNull(await(handler.ensureRoutingTable(simple(false)))); + + verify(rediscovery).lookupClusterComposition(eq(routingTable), eq(connectionPool), any(), any()); + assertArrayEquals( + new BoltServerAddress[] {reader1, reader2}, + routingTable.readers().toArray()); + assertArrayEquals( + new BoltServerAddress[] {writer1}, routingTable.writers().toArray()); + assertArrayEquals( + new BoltServerAddress[] {router1}, routingTable.routers().toArray()); } @Test - void shouldRediscoverOnReadWhenRoutingTableIsStaleForReads() - { - testRediscoveryWhenStale( READ ); + void shouldRediscoverOnReadWhenRoutingTableIsStaleForReads() { + testRediscoveryWhenStale(READ); } @Test - void shouldRediscoverOnWriteWhenRoutingTableIsStaleForWrites() - { - testRediscoveryWhenStale( WRITE ); + void shouldRediscoverOnWriteWhenRoutingTableIsStaleForWrites() { + testRediscoveryWhenStale(WRITE); } @Test - void shouldNotRediscoverOnReadWhenRoutingTableIsStaleForWritesButNotReads() - { - testNoRediscoveryWhenNotStale( WRITE, READ ); + void shouldNotRediscoverOnReadWhenRoutingTableIsStaleForWritesButNotReads() { + testNoRediscoveryWhenNotStale(WRITE, READ); } @Test - void shouldNotRediscoverOnWriteWhenRoutingTableIsStaleForReadsButNotWrites() - { - testNoRediscoveryWhenNotStale( READ, WRITE ); + void shouldNotRediscoverOnWriteWhenRoutingTableIsStaleForReadsButNotWrites() { + testNoRediscoveryWhenNotStale(READ, WRITE); } @Test - void shouldRetainAllFetchedAddressesInConnectionPoolAfterFetchingOfRoutingTable() - { - RoutingTable routingTable = new ClusterRoutingTable( defaultDatabase(), new FakeClock() ); - routingTable.update( new ClusterComposition( - 42, asOrderedSet(), asOrderedSet( B, C ), asOrderedSet( D, E ), null ) ); + void shouldRetainAllFetchedAddressesInConnectionPoolAfterFetchingOfRoutingTable() { + RoutingTable routingTable = new ClusterRoutingTable(defaultDatabase(), new FakeClock()); + routingTable.update(new ClusterComposition(42, asOrderedSet(), asOrderedSet(B, C), asOrderedSet(D, E), null)); ConnectionPool connectionPool = newConnectionPoolMock(); Rediscovery rediscovery = newRediscoveryMock(); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ).thenReturn( completedFuture( - new ClusterCompositionLookupResult( new ClusterComposition( 42, asOrderedSet( A, B ), asOrderedSet( B, C ), asOrderedSet( A, C ), null ) ) ) ); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())) + .thenReturn(completedFuture(new ClusterCompositionLookupResult( + new ClusterComposition(42, asOrderedSet(A, B), asOrderedSet(B, C), asOrderedSet(A, C), null)))); - RoutingTableRegistry registry = new RoutingTableRegistry() - { + RoutingTableRegistry registry = new RoutingTableRegistry() { @Override - public CompletionStage ensureRoutingTable( ConnectionContext context ) - { + public CompletionStage ensureRoutingTable(ConnectionContext context) { throw new UnsupportedOperationException(); } @Override - public Set allServers() - { + public Set allServers() { return routingTable.servers(); } @Override - public void remove( DatabaseName databaseName ) - { + public void remove(DatabaseName databaseName) { throw new UnsupportedOperationException(); } @Override - public void removeAged() - { - } + public void removeAged() {} @Override - public Optional getRoutingTableHandler( DatabaseName databaseName ) - { + public Optional getRoutingTableHandler(DatabaseName databaseName) { return Optional.empty(); } }; - RoutingTableHandler handler = newRoutingTableHandler( routingTable, rediscovery, connectionPool, registry ); + RoutingTableHandler handler = newRoutingTableHandler(routingTable, rediscovery, connectionPool, registry); - RoutingTable actual = await( handler.ensureRoutingTable( simple( false ) ) ); - assertEquals( routingTable, actual ); + RoutingTable actual = await(handler.ensureRoutingTable(simple(false))); + assertEquals(routingTable, actual); - verify( connectionPool ).retainAll( new HashSet<>( asList( A, B, C ) ) ); + verify(connectionPool).retainAll(new HashSet<>(asList(A, B, C))); } @Test - void shouldRemoveRoutingTableHandlerIfFailedToLookup() throws Throwable - { + void shouldRemoveRoutingTableHandlerIfFailedToLookup() throws Throwable { // Given - RoutingTable routingTable = new ClusterRoutingTable( defaultDatabase(), new FakeClock() ); + RoutingTable routingTable = new ClusterRoutingTable(defaultDatabase(), new FakeClock()); Rediscovery rediscovery = newRediscoveryMock(); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ).thenReturn( Futures.failedFuture( new RuntimeException( "Bang!" ) ) ); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())) + .thenReturn(Futures.failedFuture(new RuntimeException("Bang!"))); ConnectionPool connectionPool = newConnectionPoolMock(); RoutingTableRegistry registry = newRoutingTableRegistryMock(); // When - RoutingTableHandler handler = newRoutingTableHandler( routingTable, rediscovery, connectionPool, registry ); - assertThrows( RuntimeException.class, () -> await( handler.ensureRoutingTable( simple( false ) ) ) ); + RoutingTableHandler handler = newRoutingTableHandler(routingTable, rediscovery, connectionPool, registry); + assertThrows(RuntimeException.class, () -> await(handler.ensureRoutingTable(simple(false)))); // Then - verify( registry ).remove( defaultDatabase() ); + verify(registry).remove(defaultDatabase()); } - private void testRediscoveryWhenStale( AccessMode mode ) - { - ConnectionPool connectionPool = mock( ConnectionPool.class ); - when( connectionPool.acquire( LOCAL_DEFAULT ) ) - .thenReturn( completedFuture( mock( Connection.class ) ) ); + private void testRediscoveryWhenStale(AccessMode mode) { + ConnectionPool connectionPool = mock(ConnectionPool.class); + when(connectionPool.acquire(LOCAL_DEFAULT)).thenReturn(completedFuture(mock(Connection.class))); - RoutingTable routingTable = newStaleRoutingTableMock( mode ); + RoutingTable routingTable = newStaleRoutingTableMock(mode); Rediscovery rediscovery = newRediscoveryMock(); - RoutingTableHandler handler = newRoutingTableHandler( routingTable, rediscovery, connectionPool ); - RoutingTable actual = await( handler.ensureRoutingTable( contextWithMode( mode ) ) ); - assertEquals( routingTable, actual ); + RoutingTableHandler handler = newRoutingTableHandler(routingTable, rediscovery, connectionPool); + RoutingTable actual = await(handler.ensureRoutingTable(contextWithMode(mode))); + assertEquals(routingTable, actual); - verify( routingTable ).isStaleFor( mode ); - verify( rediscovery ).lookupClusterComposition( eq( routingTable ), eq( connectionPool ), any(), any() ); + verify(routingTable).isStaleFor(mode); + verify(rediscovery).lookupClusterComposition(eq(routingTable), eq(connectionPool), any(), any()); } - private void testNoRediscoveryWhenNotStale( AccessMode staleMode, AccessMode notStaleMode ) - { - ConnectionPool connectionPool = mock( ConnectionPool.class ); - when( connectionPool.acquire( LOCAL_DEFAULT ) ) - .thenReturn( completedFuture( mock( Connection.class ) ) ); + private void testNoRediscoveryWhenNotStale(AccessMode staleMode, AccessMode notStaleMode) { + ConnectionPool connectionPool = mock(ConnectionPool.class); + when(connectionPool.acquire(LOCAL_DEFAULT)).thenReturn(completedFuture(mock(Connection.class))); - RoutingTable routingTable = newStaleRoutingTableMock( staleMode ); + RoutingTable routingTable = newStaleRoutingTableMock(staleMode); Rediscovery rediscovery = newRediscoveryMock(); - RoutingTableHandler handler = newRoutingTableHandler( routingTable, rediscovery, connectionPool ); + RoutingTableHandler handler = newRoutingTableHandler(routingTable, rediscovery, connectionPool); - assertNotNull( await( handler.ensureRoutingTable( contextWithMode( notStaleMode ) ) ) ); - verify( routingTable ).isStaleFor( notStaleMode ); - verify( rediscovery, never() ).lookupClusterComposition( eq( routingTable ), eq( connectionPool ), any(), any() ); + assertNotNull(await(handler.ensureRoutingTable(contextWithMode(notStaleMode)))); + verify(routingTable).isStaleFor(notStaleMode); + verify(rediscovery, never()).lookupClusterComposition(eq(routingTable), eq(connectionPool), any(), any()); } - private static RoutingTable newStaleRoutingTableMock( AccessMode mode ) - { - RoutingTable routingTable = mock( RoutingTable.class ); - when( routingTable.isStaleFor( mode ) ).thenReturn( true ); + private static RoutingTable newStaleRoutingTableMock(AccessMode mode) { + RoutingTable routingTable = mock(RoutingTable.class); + when(routingTable.isStaleFor(mode)).thenReturn(true); - List addresses = singletonList( LOCAL_DEFAULT ); - when( routingTable.readers() ).thenReturn( addresses ); - when( routingTable.writers() ).thenReturn( addresses ); - when( routingTable.database() ).thenReturn( defaultDatabase() ); + List addresses = singletonList(LOCAL_DEFAULT); + when(routingTable.readers()).thenReturn(addresses); + when(routingTable.writers()).thenReturn(addresses); + when(routingTable.database()).thenReturn(defaultDatabase()); return routingTable; } - private static RoutingTableRegistry newRoutingTableRegistryMock() - { - return mock( RoutingTableRegistry.class ); + private static RoutingTableRegistry newRoutingTableRegistryMock() { + return mock(RoutingTableRegistry.class); } - private static Rediscovery newRediscoveryMock() - { - Rediscovery rediscovery = mock( RediscoveryImpl.class ); + private static Rediscovery newRediscoveryMock() { + Rediscovery rediscovery = mock(RediscoveryImpl.class); Set noServers = Collections.emptySet(); - ClusterComposition clusterComposition = new ClusterComposition( 1, noServers, noServers, noServers, null ); - when( rediscovery.lookupClusterComposition( any( RoutingTable.class ), any( ConnectionPool.class ), any( InternalBookmark.class ), any() ) ) - .thenReturn( completedFuture( new ClusterCompositionLookupResult( clusterComposition ) ) ); + ClusterComposition clusterComposition = new ClusterComposition(1, noServers, noServers, noServers, null); + when(rediscovery.lookupClusterComposition( + any(RoutingTable.class), any(ConnectionPool.class), any(InternalBookmark.class), any())) + .thenReturn(completedFuture(new ClusterCompositionLookupResult(clusterComposition))); return rediscovery; } - private static ConnectionPool newConnectionPoolMock() - { - return newConnectionPoolMockWithFailures( emptySet() ); + private static ConnectionPool newConnectionPoolMock() { + return newConnectionPoolMockWithFailures(emptySet()); } - private static ConnectionPool newConnectionPoolMockWithFailures( - Set unavailableAddresses ) - { - ConnectionPool pool = mock( ConnectionPool.class ); - when( pool.acquire( any( BoltServerAddress.class ) ) ).then( invocation -> - { - BoltServerAddress requestedAddress = invocation.getArgument( 0 ); - if ( unavailableAddresses.contains( requestedAddress ) ) - { - return Futures.failedFuture( new ServiceUnavailableException( requestedAddress + " is unavailable!" ) ); + private static ConnectionPool newConnectionPoolMockWithFailures(Set unavailableAddresses) { + ConnectionPool pool = mock(ConnectionPool.class); + when(pool.acquire(any(BoltServerAddress.class))).then(invocation -> { + BoltServerAddress requestedAddress = invocation.getArgument(0); + if (unavailableAddresses.contains(requestedAddress)) { + return Futures.failedFuture(new ServiceUnavailableException(requestedAddress + " is unavailable!")); } - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( requestedAddress ); - return completedFuture( connection ); - } ); + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(requestedAddress); + return completedFuture(connection); + }); return pool; } - private static RoutingTableHandler newRoutingTableHandler( RoutingTable routingTable, Rediscovery rediscovery, ConnectionPool connectionPool ) - { - return new RoutingTableHandlerImpl( routingTable, rediscovery, connectionPool, newRoutingTableRegistryMock(), DEV_NULL_LOGGING, - STALE_ROUTING_TABLE_PURGE_DELAY_MS ); + private static RoutingTableHandler newRoutingTableHandler( + RoutingTable routingTable, Rediscovery rediscovery, ConnectionPool connectionPool) { + return new RoutingTableHandlerImpl( + routingTable, + rediscovery, + connectionPool, + newRoutingTableRegistryMock(), + DEV_NULL_LOGGING, + STALE_ROUTING_TABLE_PURGE_DELAY_MS); } - private static RoutingTableHandler newRoutingTableHandler( RoutingTable routingTable, Rediscovery rediscovery, ConnectionPool connectionPool, - RoutingTableRegistry routingTableRegistry ) - { - return new RoutingTableHandlerImpl( routingTable, rediscovery, connectionPool, routingTableRegistry, DEV_NULL_LOGGING, - STALE_ROUTING_TABLE_PURGE_DELAY_MS ); + private static RoutingTableHandler newRoutingTableHandler( + RoutingTable routingTable, + Rediscovery rediscovery, + ConnectionPool connectionPool, + RoutingTableRegistry routingTableRegistry) { + return new RoutingTableHandlerImpl( + routingTable, + rediscovery, + connectionPool, + routingTableRegistry, + DEV_NULL_LOGGING, + STALE_ROUTING_TABLE_PURGE_DELAY_MS); } } 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 ffd93d309d..280c11abb4 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 @@ -18,26 +18,6 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.ValueSource; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.DatabaseName; -import org.neo4j.driver.internal.InternalBookmark; -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; - import static java.util.concurrent.CompletableFuture.completedFuture; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; @@ -64,171 +44,185 @@ import static org.neo4j.driver.internal.util.ClusterCompositionUtil.F; import static org.neo4j.driver.util.TestUtil.await; -class RoutingTableRegistryImplTest -{ +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.DatabaseName; +import org.neo4j.driver.internal.InternalBookmark; +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() throws Throwable - { + void factoryShouldCreateARoutingTableWithSameDatabaseName() throws Throwable { Clock clock = Clock.SYSTEM; - RoutingTableHandlerFactory factory = - new RoutingTableHandlerFactory( mock( ConnectionPool.class ), mock( RediscoveryImpl.class ), clock, DEV_NULL_LOGGING, - STALE_ROUTING_TABLE_PURGE_DELAY_MS ); - - RoutingTableHandler handler = factory.newInstance( database( "Molly" ), null ); + RoutingTableHandlerFactory factory = new RoutingTableHandlerFactory( + mock(ConnectionPool.class), + mock(RediscoveryImpl.class), + clock, + DEV_NULL_LOGGING, + STALE_ROUTING_TABLE_PURGE_DELAY_MS); + + RoutingTableHandler handler = factory.newInstance(database("Molly"), null); RoutingTable table = handler.routingTable(); - assertThat( table.database().description(), equalTo( "Molly" ) ); + assertThat(table.database().description(), equalTo("Molly")); - assertThat( table.routers().size(), equalTo( 0 ) ); - assertThat( table.readers().size(), equalTo( 0 ) ); - assertThat( table.writers().size(), equalTo( 0 ) ); + assertThat(table.routers().size(), equalTo(0)); + assertThat(table.readers().size(), equalTo(0)); + assertThat(table.writers().size(), equalTo(0)); - assertTrue( table.isStaleFor( AccessMode.READ ) ); - assertTrue( table.isStaleFor( AccessMode.WRITE ) ); + assertTrue(table.isStaleFor(AccessMode.READ)); + assertTrue(table.isStaleFor(AccessMode.WRITE)); } @ParameterizedTest - @ValueSource( strings = {SYSTEM_DATABASE_NAME, "", "database", " molly "} ) - void shouldCreateRoutingTableHandlerIfAbsentWhenFreshRoutingTable( String databaseName ) throws Throwable - { + @ValueSource(strings = {SYSTEM_DATABASE_NAME, "", "database", " molly "}) + void shouldCreateRoutingTableHandlerIfAbsentWhenFreshRoutingTable(String databaseName) throws Throwable { // Given - ConcurrentMap map = new ConcurrentHashMap<>(); + ConcurrentMap map = new ConcurrentHashMap<>(); RoutingTableHandlerFactory factory = mockedHandlerFactory(); - RoutingTableRegistryImpl routingTables = newRoutingTables( map, factory ); + RoutingTableRegistryImpl routingTables = newRoutingTables(map, factory); // When - DatabaseName database = database( databaseName ); - routingTables.ensureRoutingTable( new ImmutableConnectionContext( database, InternalBookmark.empty(), AccessMode.READ ) ); + DatabaseName database = database(databaseName); + routingTables.ensureRoutingTable( + new ImmutableConnectionContext(database, InternalBookmark.empty(), AccessMode.READ)); // Then - assertTrue( map.containsKey( database ) ); - verify( factory ).newInstance( eq( database ), eq( routingTables ) ); + assertTrue(map.containsKey(database)); + verify(factory).newInstance(eq(database), eq(routingTables)); } @ParameterizedTest - @ValueSource( strings = {SYSTEM_DATABASE_NAME, "", "database", " molly "} ) - void shouldReturnExistingRoutingTableHandlerWhenFreshRoutingTable( String databaseName ) throws Throwable - { + @ValueSource(strings = {SYSTEM_DATABASE_NAME, "", "database", " molly "}) + void shouldReturnExistingRoutingTableHandlerWhenFreshRoutingTable(String databaseName) throws Throwable { // Given - ConcurrentMap map = new ConcurrentHashMap<>(); + ConcurrentMap map = new ConcurrentHashMap<>(); RoutingTableHandler handler = mockedRoutingTableHandler(); - DatabaseName database = database( databaseName ); - map.put( database, handler ); + DatabaseName database = database(databaseName); + map.put(database, handler); RoutingTableHandlerFactory factory = mockedHandlerFactory(); - RoutingTableRegistryImpl routingTables = newRoutingTables( map, factory ); - ImmutableConnectionContext context = new ImmutableConnectionContext( database, InternalBookmark.empty(), AccessMode.READ ); + RoutingTableRegistryImpl routingTables = newRoutingTables(map, factory); + ImmutableConnectionContext context = + new ImmutableConnectionContext(database, InternalBookmark.empty(), AccessMode.READ); // When - RoutingTableHandler actual = await( routingTables.ensureRoutingTable( context ) ); + RoutingTableHandler actual = await(routingTables.ensureRoutingTable(context)); // Then it is the one we put in map that is picked up. - verify( handler ).ensureRoutingTable( context ); + verify(handler).ensureRoutingTable(context); // Then it is the one we put in map that is picked up. - assertEquals( handler, actual ); + assertEquals(handler, actual); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldReturnFreshRoutingTable( AccessMode mode ) throws Throwable - { + @EnumSource(AccessMode.class) + void shouldReturnFreshRoutingTable(AccessMode mode) throws Throwable { // Given - ConcurrentMap map = new ConcurrentHashMap<>(); + ConcurrentMap map = new ConcurrentHashMap<>(); RoutingTableHandler handler = mockedRoutingTableHandler(); - RoutingTableHandlerFactory factory = mockedHandlerFactory( handler ); - RoutingTableRegistryImpl routingTables = new RoutingTableRegistryImpl( map, factory, null, null, null, DEV_NULL_LOGGING ); + RoutingTableHandlerFactory factory = mockedHandlerFactory(handler); + RoutingTableRegistryImpl routingTables = + new RoutingTableRegistryImpl(map, factory, null, null, null, DEV_NULL_LOGGING); - ImmutableConnectionContext context = new ImmutableConnectionContext( defaultDatabase(), InternalBookmark.empty(), mode ); + ImmutableConnectionContext context = + new ImmutableConnectionContext(defaultDatabase(), InternalBookmark.empty(), mode); // When - routingTables.ensureRoutingTable( context ); + routingTables.ensureRoutingTable(context); // Then - verify( handler ).ensureRoutingTable( context ); + verify(handler).ensureRoutingTable(context); } @Test - void shouldReturnServersInAllRoutingTables() throws Throwable - { + void shouldReturnServersInAllRoutingTables() throws Throwable { // Given - ConcurrentMap map = new ConcurrentHashMap<>(); - map.put( database( "Apple" ), mockedRoutingTableHandler( A, B, C ) ); - map.put( database( "Banana" ), mockedRoutingTableHandler( B, C, D ) ); - map.put( database( "Orange" ), mockedRoutingTableHandler( E, F, C ) ); + ConcurrentMap map = new ConcurrentHashMap<>(); + map.put(database("Apple"), mockedRoutingTableHandler(A, B, C)); + map.put(database("Banana"), mockedRoutingTableHandler(B, C, D)); + map.put(database("Orange"), mockedRoutingTableHandler(E, F, C)); RoutingTableHandlerFactory factory = mockedHandlerFactory(); - RoutingTableRegistryImpl routingTables = new RoutingTableRegistryImpl( map, factory, null, null, null, DEV_NULL_LOGGING ); + RoutingTableRegistryImpl routingTables = + new RoutingTableRegistryImpl(map, factory, null, null, null, DEV_NULL_LOGGING); // When Set servers = routingTables.allServers(); // Then - assertThat( servers, containsInAnyOrder( A, B, C, D, E, F ) ); + assertThat(servers, containsInAnyOrder(A, B, C, D, E, F)); } @Test - void shouldRemoveRoutingTableHandler() throws Throwable - { + void shouldRemoveRoutingTableHandler() throws Throwable { // Given - ConcurrentMap map = new ConcurrentHashMap<>(); - map.put( database( "Apple" ), mockedRoutingTableHandler( A ) ); - map.put( database( "Banana" ), mockedRoutingTableHandler( B ) ); - map.put( database( "Orange" ), mockedRoutingTableHandler( C ) ); + ConcurrentMap map = new ConcurrentHashMap<>(); + map.put(database("Apple"), mockedRoutingTableHandler(A)); + map.put(database("Banana"), mockedRoutingTableHandler(B)); + map.put(database("Orange"), mockedRoutingTableHandler(C)); RoutingTableHandlerFactory factory = mockedHandlerFactory(); - RoutingTableRegistryImpl routingTables = newRoutingTables( map, factory ); + RoutingTableRegistryImpl routingTables = newRoutingTables(map, factory); // When - routingTables.remove( database( "Apple" ) ); - routingTables.remove( database( "Banana" ) ); + routingTables.remove(database("Apple")); + routingTables.remove(database("Banana")); // Then - assertThat( routingTables.allServers(), contains( C ) ); + assertThat(routingTables.allServers(), contains(C)); } @Test - void shouldRemoveStaleRoutingTableHandlers() throws Throwable - { - ConcurrentMap map = new ConcurrentHashMap<>(); - map.put( database( "Apple" ), mockedRoutingTableHandler( A ) ); - map.put( database( "Banana" ), mockedRoutingTableHandler( B ) ); - map.put( database( "Orange" ), mockedRoutingTableHandler( C ) ); + void shouldRemoveStaleRoutingTableHandlers() throws Throwable { + ConcurrentMap map = new ConcurrentHashMap<>(); + map.put(database("Apple"), mockedRoutingTableHandler(A)); + map.put(database("Banana"), mockedRoutingTableHandler(B)); + map.put(database("Orange"), mockedRoutingTableHandler(C)); RoutingTableHandlerFactory factory = mockedHandlerFactory(); - RoutingTableRegistryImpl routingTables = newRoutingTables( map, factory ); + RoutingTableRegistryImpl routingTables = newRoutingTables(map, factory); // When routingTables.removeAged(); // Then - assertThat( routingTables.allServers(), empty() ); + assertThat(routingTables.allServers(), empty()); } - private RoutingTableHandler mockedRoutingTableHandler( BoltServerAddress... servers ) - { - RoutingTableHandler handler = mock( RoutingTableHandler.class ); - when( handler.servers() ).thenReturn( new HashSet<>( Arrays.asList( servers ) ) ); - when( handler.isRoutingTableAged() ).thenReturn( true ); + private RoutingTableHandler mockedRoutingTableHandler(BoltServerAddress... servers) { + RoutingTableHandler handler = mock(RoutingTableHandler.class); + when(handler.servers()).thenReturn(new HashSet<>(Arrays.asList(servers))); + when(handler.isRoutingTableAged()).thenReturn(true); return handler; } - private RoutingTableRegistryImpl newRoutingTables( ConcurrentMap handlers, RoutingTableHandlerFactory factory ) - { - return new RoutingTableRegistryImpl( handlers, factory, null, null, null, DEV_NULL_LOGGING ); + private RoutingTableRegistryImpl newRoutingTables( + ConcurrentMap handlers, RoutingTableHandlerFactory factory) { + return new RoutingTableRegistryImpl(handlers, factory, null, null, null, DEV_NULL_LOGGING); } - private RoutingTableHandlerFactory mockedHandlerFactory( RoutingTableHandler handler ) - { - RoutingTableHandlerFactory factory = mock( RoutingTableHandlerFactory.class ); - when( factory.newInstance( any(), any() ) ).thenReturn( handler ); + private RoutingTableHandlerFactory mockedHandlerFactory(RoutingTableHandler handler) { + RoutingTableHandlerFactory factory = mock(RoutingTableHandlerFactory.class); + when(factory.newInstance(any(), any())).thenReturn(handler); return factory; } - private RoutingTableHandlerFactory mockedHandlerFactory() - { - return mockedHandlerFactory( mockedRoutingTableHandler() ); + private RoutingTableHandlerFactory mockedHandlerFactory() { + return mockedHandlerFactory(mockedRoutingTableHandler()); } - private RoutingTableHandler mockedRoutingTableHandler() - { - RoutingTableHandler handler = mock( RoutingTableHandler.class ); - when( handler.ensureRoutingTable( any() ) ).thenReturn( completedFuture( mock( RoutingTable.class ) ) ); + private RoutingTableHandler mockedRoutingTableHandler() { + RoutingTableHandler handler = mock(RoutingTableHandler.class); + when(handler.ensureRoutingTable(any())).thenReturn(completedFuture(mock(RoutingTable.class))); return handler; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunnerTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunnerTest.java index 7bb13949ee..2faef17900 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunnerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/SingleDatabaseRoutingProcedureRunnerTest.java @@ -18,24 +18,6 @@ */ package org.neo4j.driver.internal.cluster; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; -import java.util.stream.Stream; - -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Query; -import org.neo4j.driver.Record; -import org.neo4j.driver.Value; -import org.neo4j.driver.exceptions.FatalDiscoveryException; -import org.neo4j.driver.internal.BookmarkHolder; -import org.neo4j.driver.internal.spi.Connection; - import static java.util.Collections.EMPTY_MAP; import static java.util.Collections.singletonList; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -54,96 +36,102 @@ import static org.neo4j.driver.internal.cluster.SingleDatabaseRoutingProcedureRunner.ROUTING_CONTEXT; import static org.neo4j.driver.util.TestUtil.await; -class SingleDatabaseRoutingProcedureRunnerTest extends AbstractRoutingProcedureRunnerTest -{ +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; +import org.neo4j.driver.Value; +import org.neo4j.driver.exceptions.FatalDiscoveryException; +import org.neo4j.driver.internal.BookmarkHolder; +import org.neo4j.driver.internal.spi.Connection; + +class SingleDatabaseRoutingProcedureRunnerTest extends AbstractRoutingProcedureRunnerTest { @Test - void shouldCallGetRoutingTableWithEmptyMap() - { - TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner( RoutingContext.EMPTY ); - RoutingProcedureResponse response = await( runner.run( connection(), defaultDatabase(), empty(), null ) ); + void shouldCallGetRoutingTableWithEmptyMap() { + TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner(RoutingContext.EMPTY); + RoutingProcedureResponse response = await(runner.run(connection(), defaultDatabase(), empty(), null)); - assertTrue( response.isSuccess() ); - assertEquals( 1, response.records().size() ); + assertTrue(response.isSuccess()); + assertEquals(1, response.records().size()); - assertThat( runner.bookmarkHolder, equalTo( BookmarkHolder.NO_OP ) ); - assertThat( runner.connection.databaseName(), equalTo( defaultDatabase() ) ); - assertThat( runner.connection.mode(), equalTo( AccessMode.WRITE ) ); + assertThat(runner.bookmarkHolder, equalTo(BookmarkHolder.NO_OP)); + assertThat(runner.connection.databaseName(), equalTo(defaultDatabase())); + assertThat(runner.connection.mode(), equalTo(AccessMode.WRITE)); - Query query = generateRoutingQuery( EMPTY_MAP ); - assertThat( runner.procedure, equalTo(query) ); + Query query = generateRoutingQuery(EMPTY_MAP); + assertThat(runner.procedure, equalTo(query)); } @Test - void shouldCallGetRoutingTableWithParam() - { - URI uri = URI.create( "neo4j://localhost/?key1=value1&key2=value2" ); - RoutingContext context = new RoutingContext( uri ); + void shouldCallGetRoutingTableWithParam() { + URI uri = URI.create("neo4j://localhost/?key1=value1&key2=value2"); + RoutingContext context = new RoutingContext(uri); - TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner( context ); - RoutingProcedureResponse response = await( runner.run( connection(), defaultDatabase(), empty(), null ) ); + TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner(context); + RoutingProcedureResponse response = await(runner.run(connection(), defaultDatabase(), empty(), null)); - assertTrue( response.isSuccess() ); - assertEquals( 1, response.records().size() ); + assertTrue(response.isSuccess()); + assertEquals(1, response.records().size()); - assertThat( runner.bookmarkHolder, equalTo( BookmarkHolder.NO_OP ) ); - assertThat( runner.connection.databaseName(), equalTo( defaultDatabase() ) ); - assertThat( runner.connection.mode(), equalTo( AccessMode.WRITE ) ); + assertThat(runner.bookmarkHolder, equalTo(BookmarkHolder.NO_OP)); + assertThat(runner.connection.databaseName(), equalTo(defaultDatabase())); + assertThat(runner.connection.mode(), equalTo(AccessMode.WRITE)); - Query query = generateRoutingQuery( context.toMap() ); - assertThat( response.procedure(), equalTo(query) ); - assertThat( runner.procedure, equalTo(query) ); + Query query = generateRoutingQuery(context.toMap()); + assertThat(response.procedure(), equalTo(query)); + assertThat(runner.procedure, equalTo(query)); } @ParameterizedTest - @MethodSource( "invalidDatabaseNames" ) - void shouldErrorWhenDatabaseIsNotAbsent( String db ) throws Throwable - { - TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner( RoutingContext.EMPTY ); - assertThrows( FatalDiscoveryException.class, () -> await( runner.run( connection(), database( db ), empty(), null ) ) ); + @MethodSource("invalidDatabaseNames") + void shouldErrorWhenDatabaseIsNotAbsent(String db) throws Throwable { + TestRoutingProcedureRunner runner = new TestRoutingProcedureRunner(RoutingContext.EMPTY); + assertThrows(FatalDiscoveryException.class, () -> await(runner.run(connection(), database(db), empty(), null))); } - SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( RoutingContext context ) - { - return new TestRoutingProcedureRunner( context ); + SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner(RoutingContext context) { + return new TestRoutingProcedureRunner(context); } - SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( RoutingContext context, CompletionStage> runProcedureResult ) - { - return new TestRoutingProcedureRunner( context, runProcedureResult ); + SingleDatabaseRoutingProcedureRunner singleDatabaseRoutingProcedureRunner( + RoutingContext context, CompletionStage> runProcedureResult) { + return new TestRoutingProcedureRunner(context, runProcedureResult); } - private static Stream invalidDatabaseNames() - { - return Stream.of( SYSTEM_DATABASE_NAME, "This is a string", "null" ); + private static Stream invalidDatabaseNames() { + return Stream.of(SYSTEM_DATABASE_NAME, "This is a string", "null"); } - private static Query generateRoutingQuery(Map context ) - { - Value parameters = parameters( ROUTING_CONTEXT, context ); - return new Query( GET_ROUTING_TABLE, parameters ); + private static Query generateRoutingQuery(Map context) { + Value parameters = parameters(ROUTING_CONTEXT, context); + return new Query(GET_ROUTING_TABLE, parameters); } - private static class TestRoutingProcedureRunner extends SingleDatabaseRoutingProcedureRunner - { + private static class TestRoutingProcedureRunner extends SingleDatabaseRoutingProcedureRunner { final CompletionStage> runProcedureResult; private Connection connection; private Query procedure; private BookmarkHolder bookmarkHolder; - TestRoutingProcedureRunner( RoutingContext context ) - { - this( context, completedFuture( singletonList( mock( Record.class ) ) ) ); + TestRoutingProcedureRunner(RoutingContext context) { + this(context, completedFuture(singletonList(mock(Record.class)))); } - TestRoutingProcedureRunner( RoutingContext context, CompletionStage> runProcedureResult ) - { - super( context ); + TestRoutingProcedureRunner(RoutingContext context, CompletionStage> runProcedureResult) { + super(context); this.runProcedureResult = runProcedureResult; } @Override - CompletionStage> runProcedure(Connection connection, Query procedure, BookmarkHolder bookmarkHolder ) - { + CompletionStage> runProcedure( + Connection connection, Query procedure, BookmarkHolder bookmarkHolder) { this.connection = connection; this.procedure = procedure; this.bookmarkHolder = bookmarkHolder; diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LeastConnectedLoadBalancingStrategyTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LeastConnectedLoadBalancingStrategyTest.java index 092e46ea2b..02a66a8e8f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LeastConnectedLoadBalancingStrategyTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LeastConnectedLoadBalancingStrategyTest.java @@ -18,18 +18,6 @@ */ package org.neo4j.driver.internal.cluster.loadbalancing; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; - -import java.util.Arrays; -import java.util.Collections; - -import org.neo4j.driver.Logger; -import org.neo4j.driver.Logging; -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.spi.ConnectionPool; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.ArgumentMatchers.any; @@ -42,156 +30,152 @@ import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.internal.util.ClusterCompositionUtil.A; -class LeastConnectedLoadBalancingStrategyTest -{ +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.neo4j.driver.Logger; +import org.neo4j.driver.Logging; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.spi.ConnectionPool; + +class LeastConnectedLoadBalancingStrategyTest { @Mock private ConnectionPool connectionPool; + private LeastConnectedLoadBalancingStrategy strategy; @BeforeEach - void setUp() - { - openMocks( this ); - strategy = new LeastConnectedLoadBalancingStrategy( connectionPool, DEV_NULL_LOGGING ); + void setUp() { + openMocks(this); + strategy = new LeastConnectedLoadBalancingStrategy(connectionPool, DEV_NULL_LOGGING); } @Test - void shouldHandleEmptyReaders() - { - assertNull( strategy.selectReader( Collections.emptyList() ) ); + void shouldHandleEmptyReaders() { + assertNull(strategy.selectReader(Collections.emptyList())); } @Test - void shouldHandleEmptyWriters() - { - assertNull( strategy.selectWriter( Collections.emptyList() ) ); + void shouldHandleEmptyWriters() { + assertNull(strategy.selectWriter(Collections.emptyList())); } @Test - void shouldHandleSingleReaderWithoutActiveConnections() - { - BoltServerAddress address = new BoltServerAddress( "reader", 9999 ); + void shouldHandleSingleReaderWithoutActiveConnections() { + BoltServerAddress address = new BoltServerAddress("reader", 9999); - assertEquals( address, strategy.selectReader( Collections.singletonList( address ) ) ); + assertEquals(address, strategy.selectReader(Collections.singletonList(address))); } @Test - void shouldHandleSingleWriterWithoutActiveConnections() - { - BoltServerAddress address = new BoltServerAddress( "writer", 9999 ); + void shouldHandleSingleWriterWithoutActiveConnections() { + BoltServerAddress address = new BoltServerAddress("writer", 9999); - assertEquals( address, strategy.selectWriter( Collections.singletonList( address ) ) ); + assertEquals(address, strategy.selectWriter(Collections.singletonList(address))); } @Test - void shouldHandleSingleReaderWithActiveConnections() - { - BoltServerAddress address = new BoltServerAddress( "reader", 9999 ); - when( connectionPool.inUseConnections( address ) ).thenReturn( 42 ); + void shouldHandleSingleReaderWithActiveConnections() { + BoltServerAddress address = new BoltServerAddress("reader", 9999); + when(connectionPool.inUseConnections(address)).thenReturn(42); - assertEquals( address, strategy.selectReader( Collections.singletonList( address ) ) ); + assertEquals(address, strategy.selectReader(Collections.singletonList(address))); } @Test - void shouldHandleSingleWriterWithActiveConnections() - { - BoltServerAddress address = new BoltServerAddress( "writer", 9999 ); - when( connectionPool.inUseConnections( address ) ).thenReturn( 24 ); + void shouldHandleSingleWriterWithActiveConnections() { + BoltServerAddress address = new BoltServerAddress("writer", 9999); + when(connectionPool.inUseConnections(address)).thenReturn(24); - assertEquals( address, strategy.selectWriter( Collections.singletonList( address ) ) ); + assertEquals(address, strategy.selectWriter(Collections.singletonList(address))); } @Test - void shouldHandleMultipleReadersWithActiveConnections() - { - BoltServerAddress address1 = new BoltServerAddress( "reader", 1 ); - BoltServerAddress address2 = new BoltServerAddress( "reader", 2 ); - BoltServerAddress address3 = new BoltServerAddress( "reader", 3 ); + void shouldHandleMultipleReadersWithActiveConnections() { + BoltServerAddress address1 = new BoltServerAddress("reader", 1); + BoltServerAddress address2 = new BoltServerAddress("reader", 2); + BoltServerAddress address3 = new BoltServerAddress("reader", 3); - when( connectionPool.inUseConnections( address1 ) ).thenReturn( 3 ); - when( connectionPool.inUseConnections( address2 ) ).thenReturn( 4 ); - when( connectionPool.inUseConnections( address3 ) ).thenReturn( 1 ); + when(connectionPool.inUseConnections(address1)).thenReturn(3); + when(connectionPool.inUseConnections(address2)).thenReturn(4); + when(connectionPool.inUseConnections(address3)).thenReturn(1); - assertEquals( address3, strategy.selectReader( Arrays.asList( address1, address2, address3 ) ) ); + assertEquals(address3, strategy.selectReader(Arrays.asList(address1, address2, address3))); } @Test - void shouldHandleMultipleWritersWithActiveConnections() - { - BoltServerAddress address1 = new BoltServerAddress( "writer", 1 ); - BoltServerAddress address2 = new BoltServerAddress( "writer", 2 ); - BoltServerAddress address3 = new BoltServerAddress( "writer", 3 ); - BoltServerAddress address4 = new BoltServerAddress( "writer", 4 ); - - when( connectionPool.inUseConnections( address1 ) ).thenReturn( 5 ); - when( connectionPool.inUseConnections( address2 ) ).thenReturn( 6 ); - when( connectionPool.inUseConnections( address3 ) ).thenReturn( 0 ); - when( connectionPool.inUseConnections( address4 ) ).thenReturn( 1 ); - - assertEquals( address3, - strategy.selectWriter( Arrays.asList( address1, address2, address3, address4 ) ) ); + void shouldHandleMultipleWritersWithActiveConnections() { + BoltServerAddress address1 = new BoltServerAddress("writer", 1); + BoltServerAddress address2 = new BoltServerAddress("writer", 2); + BoltServerAddress address3 = new BoltServerAddress("writer", 3); + BoltServerAddress address4 = new BoltServerAddress("writer", 4); + + when(connectionPool.inUseConnections(address1)).thenReturn(5); + when(connectionPool.inUseConnections(address2)).thenReturn(6); + when(connectionPool.inUseConnections(address3)).thenReturn(0); + when(connectionPool.inUseConnections(address4)).thenReturn(1); + + assertEquals(address3, strategy.selectWriter(Arrays.asList(address1, address2, address3, address4))); } @Test - void shouldReturnDifferentReaderOnEveryInvocationWhenNoActiveConnections() - { - BoltServerAddress address1 = new BoltServerAddress( "reader", 1 ); - BoltServerAddress address2 = new BoltServerAddress( "reader", 2 ); - BoltServerAddress address3 = new BoltServerAddress( "reader", 3 ); - - assertEquals( address1, strategy.selectReader( Arrays.asList( address1, address2, address3 ) ) ); - assertEquals( address2, strategy.selectReader( Arrays.asList( address1, address2, address3 ) ) ); - assertEquals( address3, strategy.selectReader( Arrays.asList( address1, address2, address3 ) ) ); - - assertEquals( address1, strategy.selectReader( Arrays.asList( address1, address2, address3 ) ) ); - assertEquals( address2, strategy.selectReader( Arrays.asList( address1, address2, address3 ) ) ); - assertEquals( address3, strategy.selectReader( Arrays.asList( address1, address2, address3 ) ) ); + void shouldReturnDifferentReaderOnEveryInvocationWhenNoActiveConnections() { + BoltServerAddress address1 = new BoltServerAddress("reader", 1); + BoltServerAddress address2 = new BoltServerAddress("reader", 2); + BoltServerAddress address3 = new BoltServerAddress("reader", 3); + + assertEquals(address1, strategy.selectReader(Arrays.asList(address1, address2, address3))); + assertEquals(address2, strategy.selectReader(Arrays.asList(address1, address2, address3))); + assertEquals(address3, strategy.selectReader(Arrays.asList(address1, address2, address3))); + + assertEquals(address1, strategy.selectReader(Arrays.asList(address1, address2, address3))); + assertEquals(address2, strategy.selectReader(Arrays.asList(address1, address2, address3))); + assertEquals(address3, strategy.selectReader(Arrays.asList(address1, address2, address3))); } @Test - void shouldReturnDifferentWriterOnEveryInvocationWhenNoActiveConnections() - { - BoltServerAddress address1 = new BoltServerAddress( "writer", 1 ); - BoltServerAddress address2 = new BoltServerAddress( "writer", 2 ); + void shouldReturnDifferentWriterOnEveryInvocationWhenNoActiveConnections() { + BoltServerAddress address1 = new BoltServerAddress("writer", 1); + BoltServerAddress address2 = new BoltServerAddress("writer", 2); - assertEquals( address1, strategy.selectReader( Arrays.asList( address1, address2 ) ) ); - assertEquals( address2, strategy.selectReader( Arrays.asList( address1, address2 ) ) ); + assertEquals(address1, strategy.selectReader(Arrays.asList(address1, address2))); + assertEquals(address2, strategy.selectReader(Arrays.asList(address1, address2))); - assertEquals( address1, strategy.selectReader( Arrays.asList( address1, address2 ) ) ); - assertEquals( address2, strategy.selectReader( Arrays.asList( address1, address2 ) ) ); + assertEquals(address1, strategy.selectReader(Arrays.asList(address1, address2))); + assertEquals(address2, strategy.selectReader(Arrays.asList(address1, address2))); } @Test - void shouldTraceLogWhenNoAddressSelected() - { - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + void shouldTraceLogWhenNoAddressSelected() { + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); - LoadBalancingStrategy strategy = new LeastConnectedLoadBalancingStrategy( connectionPool, logging ); + LoadBalancingStrategy strategy = new LeastConnectedLoadBalancingStrategy(connectionPool, logging); - strategy.selectReader( Collections.emptyList() ); - strategy.selectWriter( Collections.emptyList() ); + strategy.selectReader(Collections.emptyList()); + strategy.selectWriter(Collections.emptyList()); - verify( logger ).trace( startsWith( "Unable to select" ), eq( "reader" ) ); - verify( logger ).trace( startsWith( "Unable to select" ), eq( "writer" ) ); + verify(logger).trace(startsWith("Unable to select"), eq("reader")); + verify(logger).trace(startsWith("Unable to select"), eq("writer")); } @Test - void shouldTraceLogSelectedAddress() - { - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + void shouldTraceLogSelectedAddress() { + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); - when( connectionPool.inUseConnections( any( BoltServerAddress.class ) ) ).thenReturn( 42 ); + when(connectionPool.inUseConnections(any(BoltServerAddress.class))).thenReturn(42); - LoadBalancingStrategy strategy = new LeastConnectedLoadBalancingStrategy( connectionPool, logging ); + LoadBalancingStrategy strategy = new LeastConnectedLoadBalancingStrategy(connectionPool, logging); - strategy.selectReader( Collections.singletonList( A ) ); - strategy.selectWriter( Collections.singletonList( A ) ); + strategy.selectReader(Collections.singletonList(A)); + strategy.selectWriter(Collections.singletonList(A)); - verify( logger ).trace( startsWith( "Selected" ), eq( "reader" ), eq( A ), eq( 42 ) ); - verify( logger ).trace( startsWith( "Selected" ), eq( "writer" ), eq( A ), eq( 42 ) ); + verify(logger).trace(startsWith("Selected"), eq("reader"), eq(A), eq(42)); + verify(logger).trace(startsWith("Selected"), eq("writer"), eq(A), eq(42)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancerTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancerTest.java index c9ad387d2f..b1ab5df688 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancerTest.java @@ -18,47 +18,6 @@ */ package org.neo4j.driver.internal.cluster.loadbalancing; -import io.netty.util.concurrent.GlobalEventExecutor; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.ValueSource; -import org.mockito.InOrder; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; - -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.exceptions.AuthenticationException; -import org.neo4j.driver.exceptions.SecurityException; -import org.neo4j.driver.exceptions.ServiceUnavailableException; -import org.neo4j.driver.exceptions.SessionExpiredException; -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.DatabaseName; -import org.neo4j.driver.internal.DatabaseNameUtil; -import org.neo4j.driver.internal.async.ConnectionContext; -import org.neo4j.driver.internal.async.connection.RoutingConnection; -import org.neo4j.driver.internal.cluster.ClusterComposition; -import org.neo4j.driver.internal.cluster.ClusterRoutingTable; -import org.neo4j.driver.internal.cluster.Rediscovery; -import org.neo4j.driver.internal.cluster.RoutingTable; -import org.neo4j.driver.internal.cluster.RoutingTableHandler; -import org.neo4j.driver.internal.cluster.RoutingTableRegistry; -import org.neo4j.driver.internal.messaging.BoltProtocol; -import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.spi.ConnectionPool; -import org.neo4j.driver.internal.util.FakeClock; -import org.neo4j.driver.internal.util.Futures; -import org.neo4j.driver.internal.util.ServerVersion; - import static java.util.Arrays.asList; import static java.util.Collections.emptySet; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -94,390 +53,428 @@ import static org.neo4j.driver.util.TestUtil.asOrderedSet; import static org.neo4j.driver.util.TestUtil.await; -class LoadBalancerTest -{ +import io.netty.util.concurrent.GlobalEventExecutor; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InOrder; +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.exceptions.AuthenticationException; +import org.neo4j.driver.exceptions.SecurityException; +import org.neo4j.driver.exceptions.ServiceUnavailableException; +import org.neo4j.driver.exceptions.SessionExpiredException; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.DatabaseName; +import org.neo4j.driver.internal.DatabaseNameUtil; +import org.neo4j.driver.internal.async.ConnectionContext; +import org.neo4j.driver.internal.async.connection.RoutingConnection; +import org.neo4j.driver.internal.cluster.ClusterComposition; +import org.neo4j.driver.internal.cluster.ClusterRoutingTable; +import org.neo4j.driver.internal.cluster.Rediscovery; +import org.neo4j.driver.internal.cluster.RoutingTable; +import org.neo4j.driver.internal.cluster.RoutingTableHandler; +import org.neo4j.driver.internal.cluster.RoutingTableRegistry; +import org.neo4j.driver.internal.messaging.BoltProtocol; +import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.spi.ConnectionPool; +import org.neo4j.driver.internal.util.FakeClock; +import org.neo4j.driver.internal.util.Futures; +import org.neo4j.driver.internal.util.ServerVersion; + +class LoadBalancerTest { @ParameterizedTest - @EnumSource( AccessMode.class ) - void returnsCorrectAccessMode( AccessMode mode ) - { + @EnumSource(AccessMode.class) + void returnsCorrectAccessMode(AccessMode mode) { ConnectionPool connectionPool = newConnectionPoolMock(); - RoutingTable routingTable = mock( RoutingTable.class ); - List readerAddresses = Collections.singletonList( A ); - List writerAddresses = Collections.singletonList( B ); - when( routingTable.readers() ).thenReturn( readerAddresses ); - when( routingTable.writers() ).thenReturn( writerAddresses ); + RoutingTable routingTable = mock(RoutingTable.class); + List readerAddresses = Collections.singletonList(A); + List writerAddresses = Collections.singletonList(B); + when(routingTable.readers()).thenReturn(readerAddresses); + when(routingTable.writers()).thenReturn(writerAddresses); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTable ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTable); - Connection acquired = await( loadBalancer.acquireConnection( contextWithMode( mode ) ) ); + Connection acquired = await(loadBalancer.acquireConnection(contextWithMode(mode))); - assertThat( acquired, instanceOf( RoutingConnection.class ) ); - assertThat( acquired.mode(), equalTo( mode ) ); + assertThat(acquired, instanceOf(RoutingConnection.class)); + assertThat(acquired.mode(), equalTo(mode)); } @ParameterizedTest - @ValueSource( strings = {"", "foo", "data"} ) - void returnsCorrectDatabaseName( String databaseName ) - { + @ValueSource(strings = {"", "foo", "data"}) + void returnsCorrectDatabaseName(String databaseName) { ConnectionPool connectionPool = newConnectionPoolMock(); - RoutingTable routingTable = mock( RoutingTable.class ); - List writerAddresses = Collections.singletonList( A ); - when( routingTable.writers() ).thenReturn( writerAddresses ); + RoutingTable routingTable = mock(RoutingTable.class); + List writerAddresses = Collections.singletonList(A); + when(routingTable.writers()).thenReturn(writerAddresses); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTable ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTable); - Connection acquired = await( loadBalancer.acquireConnection( contextWithDatabase( databaseName ) ) ); + Connection acquired = await(loadBalancer.acquireConnection(contextWithDatabase(databaseName))); - assertThat( acquired, instanceOf( RoutingConnection.class ) ); - assertThat( acquired.databaseName().description(), equalTo( databaseName ) ); - verify( connectionPool ).acquire( A ); + assertThat(acquired, instanceOf(RoutingConnection.class)); + assertThat(acquired.databaseName().description(), equalTo(databaseName)); + verify(connectionPool).acquire(A); } @Test - void shouldThrowWhenRediscoveryReturnsNoSuitableServers() - { + void shouldThrowWhenRediscoveryReturnsNoSuitableServers() { ConnectionPool connectionPool = newConnectionPoolMock(); - RoutingTable routingTable = mock( RoutingTable.class ); - when( routingTable.readers() ).thenReturn( Collections.emptyList() ); - when( routingTable.writers() ).thenReturn( Collections.emptyList() ); + RoutingTable routingTable = mock(RoutingTable.class); + when(routingTable.readers()).thenReturn(Collections.emptyList()); + when(routingTable.writers()).thenReturn(Collections.emptyList()); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTable ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTable); - SessionExpiredException error1 = - assertThrows( SessionExpiredException.class, () -> await( loadBalancer.acquireConnection( contextWithMode( READ ) ) ) ); - assertThat( error1.getMessage(), startsWith( "Failed to obtain connection towards READ server" ) ); + SessionExpiredException error1 = assertThrows( + SessionExpiredException.class, () -> await(loadBalancer.acquireConnection(contextWithMode(READ)))); + assertThat(error1.getMessage(), startsWith("Failed to obtain connection towards READ server")); - SessionExpiredException error2 = - assertThrows( SessionExpiredException.class, () -> await( loadBalancer.acquireConnection( contextWithMode( WRITE ) ) ) ); - assertThat( error2.getMessage(), startsWith( "Failed to obtain connection towards WRITE server" ) ); + SessionExpiredException error2 = assertThrows( + SessionExpiredException.class, () -> await(loadBalancer.acquireConnection(contextWithMode(WRITE)))); + assertThat(error2.getMessage(), startsWith("Failed to obtain connection towards WRITE server")); } @Test - void shouldSelectLeastConnectedAddress() - { + void shouldSelectLeastConnectedAddress() { ConnectionPool connectionPool = newConnectionPoolMock(); - when( connectionPool.inUseConnections( A ) ).thenReturn( 0 ); - when( connectionPool.inUseConnections( B ) ).thenReturn( 20 ); - when( connectionPool.inUseConnections( C ) ).thenReturn( 0 ); + when(connectionPool.inUseConnections(A)).thenReturn(0); + when(connectionPool.inUseConnections(B)).thenReturn(20); + when(connectionPool.inUseConnections(C)).thenReturn(0); - RoutingTable routingTable = mock( RoutingTable.class ); - List readerAddresses = Arrays.asList( A, B, C ); - when( routingTable.readers() ).thenReturn( readerAddresses ); + RoutingTable routingTable = mock(RoutingTable.class); + List readerAddresses = Arrays.asList(A, B, C); + when(routingTable.readers()).thenReturn(readerAddresses); - - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTable ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTable); Set seenAddresses = new HashSet<>(); - for ( int i = 0; i < 10; i++ ) - { - Connection connection = await( loadBalancer.acquireConnection( newBoltV4ConnectionContext() ) ); - seenAddresses.add( connection.serverAddress() ); + for (int i = 0; i < 10; i++) { + Connection connection = await(loadBalancer.acquireConnection(newBoltV4ConnectionContext())); + seenAddresses.add(connection.serverAddress()); } // server B should never be selected because it has many active connections - assertEquals( 2, seenAddresses.size() ); - assertTrue( seenAddresses.containsAll( asList( A, C ) ) ); + assertEquals(2, seenAddresses.size()); + assertTrue(seenAddresses.containsAll(asList(A, C))); } @Test - void shouldRoundRobinWhenNoActiveConnections() - { + void shouldRoundRobinWhenNoActiveConnections() { ConnectionPool connectionPool = newConnectionPoolMock(); - RoutingTable routingTable = mock( RoutingTable.class ); - List readerAddresses = Arrays.asList( A, B, C ); - when( routingTable.readers() ).thenReturn( readerAddresses ); + RoutingTable routingTable = mock(RoutingTable.class); + List readerAddresses = Arrays.asList(A, B, C); + when(routingTable.readers()).thenReturn(readerAddresses); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTable ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTable); Set seenAddresses = new HashSet<>(); - for ( int i = 0; i < 10; i++ ) - { - Connection connection = await( loadBalancer.acquireConnection( newBoltV4ConnectionContext() ) ); - seenAddresses.add( connection.serverAddress() ); + for (int i = 0; i < 10; i++) { + Connection connection = await(loadBalancer.acquireConnection(newBoltV4ConnectionContext())); + seenAddresses.add(connection.serverAddress()); } - assertEquals( 3, seenAddresses.size() ); - assertTrue( seenAddresses.containsAll( asList( A, B, C ) ) ); + assertEquals(3, seenAddresses.size()); + assertTrue(seenAddresses.containsAll(asList(A, B, C))); } @Test - void shouldTryMultipleServersAfterRediscovery() - { - Set unavailableAddresses = asOrderedSet( A ); - ConnectionPool connectionPool = newConnectionPoolMockWithFailures( unavailableAddresses ); + void shouldTryMultipleServersAfterRediscovery() { + Set unavailableAddresses = asOrderedSet(A); + ConnectionPool connectionPool = newConnectionPoolMockWithFailures(unavailableAddresses); - RoutingTable routingTable = new ClusterRoutingTable( defaultDatabase(), new FakeClock() ); - routingTable.update( new ClusterComposition( -1, new LinkedHashSet<>( Arrays.asList( A, B ) ), emptySet(), emptySet(), null ) ); + RoutingTable routingTable = new ClusterRoutingTable(defaultDatabase(), new FakeClock()); + routingTable.update( + new ClusterComposition(-1, new LinkedHashSet<>(Arrays.asList(A, B)), emptySet(), emptySet(), null)); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTable ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTable); - Connection connection = await( loadBalancer.acquireConnection( newBoltV4ConnectionContext() ) ); + Connection connection = await(loadBalancer.acquireConnection(newBoltV4ConnectionContext())); - assertNotNull( connection ); - assertEquals( B, connection.serverAddress() ); + assertNotNull(connection); + assertEquals(B, connection.serverAddress()); // routing table should've forgotten A - assertArrayEquals( new BoltServerAddress[]{B}, routingTable.readers().toArray() ); + assertArrayEquals(new BoltServerAddress[] {B}, routingTable.readers().toArray()); } @Test - void shouldFailWithResolverError() throws Throwable - { - ConnectionPool pool = mock( ConnectionPool.class ); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenThrow( new RuntimeException( "hi there" ) ); + void shouldFailWithResolverError() throws Throwable { + ConnectionPool pool = mock(ConnectionPool.class); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenThrow(new RuntimeException("hi there")); - LoadBalancer loadBalancer = newLoadBalancer( pool, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(pool, rediscovery); - RuntimeException exception = assertThrows( RuntimeException.class, () -> await( loadBalancer.supportsMultiDb() ) ); - assertThat( exception.getMessage(), equalTo( "hi there" ) ); + RuntimeException exception = assertThrows(RuntimeException.class, () -> await(loadBalancer.supportsMultiDb())); + assertThat(exception.getMessage(), equalTo("hi there")); } @Test - void shouldFailAfterTryingAllServers() throws Throwable - { - Set unavailableAddresses = asOrderedSet( A, B ); - ConnectionPool connectionPool = newConnectionPoolMockWithFailures( unavailableAddresses ); + void shouldFailAfterTryingAllServers() throws Throwable { + Set unavailableAddresses = asOrderedSet(A, B); + ConnectionPool connectionPool = newConnectionPoolMockWithFailures(unavailableAddresses); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenReturn(Arrays.asList(A, B)); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, rediscovery); - ServiceUnavailableException exception = assertThrows( ServiceUnavailableException.class, () -> await( loadBalancer.supportsMultiDb() ) ); + ServiceUnavailableException exception = + assertThrows(ServiceUnavailableException.class, () -> await(loadBalancer.supportsMultiDb())); Throwable[] suppressed = exception.getSuppressed(); - assertThat( suppressed.length, equalTo( 2 ) ); // one for A, one for B - assertThat( suppressed[0].getMessage(), containsString( A.toString() ) ); - assertThat( suppressed[1].getMessage(), containsString( B.toString() ) ); - verify( connectionPool, times( 2 ) ).acquire( any() ); + assertThat(suppressed.length, equalTo(2)); // one for A, one for B + assertThat(suppressed[0].getMessage(), containsString(A.toString())); + assertThat(suppressed[1].getMessage(), containsString(B.toString())); + verify(connectionPool, times(2)).acquire(any()); } @Test - void shouldFailEarlyOnSecurityError() throws Throwable - { - Set unavailableAddresses = asOrderedSet( A, B ); - ConnectionPool connectionPool = newConnectionPoolMockWithFailures( unavailableAddresses, address -> new SecurityException( "code", "hi there" ) ); + void shouldFailEarlyOnSecurityError() throws Throwable { + Set unavailableAddresses = asOrderedSet(A, B); + ConnectionPool connectionPool = newConnectionPoolMockWithFailures( + unavailableAddresses, address -> new SecurityException("code", "hi there")); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenReturn(Arrays.asList(A, B)); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, rediscovery); - SecurityException exception = assertThrows( SecurityException.class, () -> await( loadBalancer.supportsMultiDb() ) ); - assertThat( exception.getMessage(), startsWith( "hi there" ) ); - verify( connectionPool, times( 1 ) ).acquire( any() ); + SecurityException exception = + assertThrows(SecurityException.class, () -> await(loadBalancer.supportsMultiDb())); + assertThat(exception.getMessage(), startsWith("hi there")); + verify(connectionPool, times(1)).acquire(any()); } @Test - void shouldSuccessOnFirstSuccessfulServer() throws Throwable - { - Set unavailableAddresses = asOrderedSet( A, B ); - ConnectionPool connectionPool = newConnectionPoolMockWithFailures( unavailableAddresses ); + void shouldSuccessOnFirstSuccessfulServer() throws Throwable { + Set unavailableAddresses = asOrderedSet(A, B); + ConnectionPool connectionPool = newConnectionPoolMockWithFailures(unavailableAddresses); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B, C, D ) ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenReturn(Arrays.asList(A, B, C, D)); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, rediscovery); - assertTrue( await( loadBalancer.supportsMultiDb() ) ); - verify( connectionPool, times( 3 ) ).acquire( any() ); + assertTrue(await(loadBalancer.supportsMultiDb())); + verify(connectionPool, times(3)).acquire(any()); } @Test - void shouldThrowModifiedErrorWhenSupportMultiDbTestFails() throws Throwable - { - Set unavailableAddresses = asOrderedSet( A, B ); - ConnectionPool connectionPool = newConnectionPoolMockWithFailures( unavailableAddresses ); + void shouldThrowModifiedErrorWhenSupportMultiDbTestFails() throws Throwable { + Set unavailableAddresses = asOrderedSet(A, B); + ConnectionPool connectionPool = newConnectionPoolMockWithFailures(unavailableAddresses); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenReturn(Arrays.asList(A, B)); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, rediscovery); - ServiceUnavailableException exception = assertThrows( ServiceUnavailableException.class, () -> await( loadBalancer.verifyConnectivity() ) ); - assertThat( exception.getMessage(), startsWith( "Unable to connect to database management service," ) ); + ServiceUnavailableException exception = + assertThrows(ServiceUnavailableException.class, () -> await(loadBalancer.verifyConnectivity())); + assertThat(exception.getMessage(), startsWith("Unable to connect to database management service,")); } @Test - void shouldFailEarlyOnSecurityErrorWhenSupportMultiDbTestFails() throws Throwable - { - Set unavailableAddresses = asOrderedSet( A, B ); - ConnectionPool connectionPool = newConnectionPoolMockWithFailures( unavailableAddresses, address -> new AuthenticationException( "code", "error" ) ); + void shouldFailEarlyOnSecurityErrorWhenSupportMultiDbTestFails() throws Throwable { + Set unavailableAddresses = asOrderedSet(A, B); + ConnectionPool connectionPool = newConnectionPoolMockWithFailures( + unavailableAddresses, address -> new AuthenticationException("code", "error")); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenReturn(Arrays.asList(A, B)); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, rediscovery); - AuthenticationException exception = assertThrows( AuthenticationException.class, () -> await( loadBalancer.verifyConnectivity() ) ); - assertThat( exception.getMessage(), startsWith( "error" ) ); + AuthenticationException exception = + assertThrows(AuthenticationException.class, () -> await(loadBalancer.verifyConnectivity())); + assertThat(exception.getMessage(), startsWith("error")); } @Test - void shouldThrowModifiedErrorWhenRefreshRoutingTableFails() throws Throwable - { + void shouldThrowModifiedErrorWhenRefreshRoutingTableFails() throws Throwable { ConnectionPool connectionPool = newConnectionPoolMock(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenReturn(Arrays.asList(A, B)); - RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); - when( routingTables.ensureRoutingTable( any( ConnectionContext.class ) ) ).thenThrow( new ServiceUnavailableException( "boooo" ) ); + RoutingTableRegistry routingTables = mock(RoutingTableRegistry.class); + when(routingTables.ensureRoutingTable(any(ConnectionContext.class))) + .thenThrow(new ServiceUnavailableException("boooo")); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables, rediscovery); - ServiceUnavailableException exception = assertThrows( ServiceUnavailableException.class, () -> await( loadBalancer.verifyConnectivity() ) ); - assertThat( exception.getMessage(), startsWith( "Unable to connect to database management service," ) ); - verify( routingTables ).ensureRoutingTable( any( ConnectionContext.class ) ); + ServiceUnavailableException exception = + assertThrows(ServiceUnavailableException.class, () -> await(loadBalancer.verifyConnectivity())); + assertThat(exception.getMessage(), startsWith("Unable to connect to database management service,")); + verify(routingTables).ensureRoutingTable(any(ConnectionContext.class)); } @Test - void shouldThrowOriginalErrorWhenRefreshRoutingTableFails() throws Throwable - { + void shouldThrowOriginalErrorWhenRefreshRoutingTableFails() throws Throwable { ConnectionPool connectionPool = newConnectionPoolMock(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenReturn(Arrays.asList(A, B)); - RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); - when( routingTables.ensureRoutingTable( any( ConnectionContext.class ) ) ).thenThrow( new RuntimeException( "boo" ) ); + RoutingTableRegistry routingTables = mock(RoutingTableRegistry.class); + when(routingTables.ensureRoutingTable(any(ConnectionContext.class))).thenThrow(new RuntimeException("boo")); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables, rediscovery); - RuntimeException exception = assertThrows( RuntimeException.class, () -> await( loadBalancer.verifyConnectivity() ) ); - assertThat( exception.getMessage(), startsWith( "boo" ) ); - verify( routingTables ).ensureRoutingTable( any( ConnectionContext.class ) ); + RuntimeException exception = + assertThrows(RuntimeException.class, () -> await(loadBalancer.verifyConnectivity())); + assertThat(exception.getMessage(), startsWith("boo")); + verify(routingTables).ensureRoutingTable(any(ConnectionContext.class)); } @Test - void shouldReturnSuccessVerifyConnectivity() throws Throwable - { + void shouldReturnSuccessVerifyConnectivity() throws Throwable { ConnectionPool connectionPool = newConnectionPoolMock(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.resolve() ).thenReturn( Arrays.asList( A, B ) ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.resolve()).thenReturn(Arrays.asList(A, B)); - RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); - when( routingTables.ensureRoutingTable( any( ConnectionContext.class ) ) ).thenReturn( Futures.completedWithNull() ); + RoutingTableRegistry routingTables = mock(RoutingTableRegistry.class); + when(routingTables.ensureRoutingTable(any(ConnectionContext.class))).thenReturn(Futures.completedWithNull()); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables, rediscovery ); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables, rediscovery); - await( loadBalancer.verifyConnectivity() ); - verify( routingTables ).ensureRoutingTable( any( ConnectionContext.class ) ); + await(loadBalancer.verifyConnectivity()); + verify(routingTables).ensureRoutingTable(any(ConnectionContext.class)); } @ParameterizedTest - @ValueSource( booleans = {true, false} ) - void expectsCompetedDatabaseNameAfterRoutingTableRegistry( boolean completed ) throws Throwable - { + @ValueSource(booleans = {true, false}) + void expectsCompetedDatabaseNameAfterRoutingTableRegistry(boolean completed) throws Throwable { ConnectionPool connectionPool = newConnectionPoolMock(); - RoutingTable routingTable = mock( RoutingTable.class ); - List readerAddresses = Collections.singletonList( A ); - List writerAddresses = Collections.singletonList( B ); - when( routingTable.readers() ).thenReturn( readerAddresses ); - when( routingTable.writers() ).thenReturn( writerAddresses ); - RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); - RoutingTableHandler handler = mock( RoutingTableHandler.class ); - when( handler.routingTable() ).thenReturn( routingTable ); - when( routingTables.ensureRoutingTable( any( ConnectionContext.class ) ) ).thenReturn( CompletableFuture.completedFuture( handler ) ); - Rediscovery rediscovery = mock( Rediscovery.class ); - LoadBalancer loadBalancer = - new LoadBalancer( connectionPool, routingTables, rediscovery, new LeastConnectedLoadBalancingStrategy( connectionPool, DEV_NULL_LOGGING ), - GlobalEventExecutor.INSTANCE, DEV_NULL_LOGGING ); - ConnectionContext context = mock( ConnectionContext.class ); - CompletableFuture databaseNameFuture = spy( new CompletableFuture<>() ); - if ( completed ) - { - databaseNameFuture.complete( DatabaseNameUtil.systemDatabase() ); + RoutingTable routingTable = mock(RoutingTable.class); + List readerAddresses = Collections.singletonList(A); + List writerAddresses = Collections.singletonList(B); + when(routingTable.readers()).thenReturn(readerAddresses); + when(routingTable.writers()).thenReturn(writerAddresses); + RoutingTableRegistry routingTables = mock(RoutingTableRegistry.class); + RoutingTableHandler handler = mock(RoutingTableHandler.class); + when(handler.routingTable()).thenReturn(routingTable); + when(routingTables.ensureRoutingTable(any(ConnectionContext.class))) + .thenReturn(CompletableFuture.completedFuture(handler)); + Rediscovery rediscovery = mock(Rediscovery.class); + LoadBalancer loadBalancer = new LoadBalancer( + connectionPool, + routingTables, + rediscovery, + new LeastConnectedLoadBalancingStrategy(connectionPool, DEV_NULL_LOGGING), + GlobalEventExecutor.INSTANCE, + DEV_NULL_LOGGING); + ConnectionContext context = mock(ConnectionContext.class); + CompletableFuture databaseNameFuture = spy(new CompletableFuture<>()); + if (completed) { + databaseNameFuture.complete(DatabaseNameUtil.systemDatabase()); } - when( context.databaseNameFuture() ).thenReturn( databaseNameFuture ); - when( context.mode() ).thenReturn( WRITE ); + when(context.databaseNameFuture()).thenReturn(databaseNameFuture); + when(context.mode()).thenReturn(WRITE); - Executable action = () -> await( loadBalancer.acquireConnection( context ) ); - if ( completed ) - { + Executable action = () -> await(loadBalancer.acquireConnection(context)); + if (completed) { action.execute(); - } - else - { - assertThrows( IllegalStateException.class, action, ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER.get().getMessage() ); + } else { + assertThrows( + IllegalStateException.class, + action, + ConnectionContext.PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER + .get() + .getMessage()); } - InOrder inOrder = inOrder( routingTables, context, databaseNameFuture ); - inOrder.verify( routingTables ).ensureRoutingTable( context ); - inOrder.verify( context ).databaseNameFuture(); - inOrder.verify( databaseNameFuture ).isDone(); - if ( completed ) - { - inOrder.verify( databaseNameFuture ).join(); + InOrder inOrder = inOrder(routingTables, context, databaseNameFuture); + inOrder.verify(routingTables).ensureRoutingTable(context); + inOrder.verify(context).databaseNameFuture(); + inOrder.verify(databaseNameFuture).isDone(); + if (completed) { + inOrder.verify(databaseNameFuture).join(); } } - private static ConnectionPool newConnectionPoolMock() - { - return newConnectionPoolMockWithFailures( emptySet() ); + private static ConnectionPool newConnectionPoolMock() { + return newConnectionPoolMockWithFailures(emptySet()); } - private static ConnectionPool newConnectionPoolMockWithFailures( Set unavailableAddresses ) - { - return newConnectionPoolMockWithFailures( unavailableAddresses, address -> new ServiceUnavailableException( address + " is unavailable!" ) ); + private static ConnectionPool newConnectionPoolMockWithFailures(Set unavailableAddresses) { + return newConnectionPoolMockWithFailures( + unavailableAddresses, address -> new ServiceUnavailableException(address + " is unavailable!")); } - private static ConnectionPool newConnectionPoolMockWithFailures( Set unavailableAddresses, Function errorAction ) - { - ConnectionPool pool = mock( ConnectionPool.class ); - when( pool.acquire( any( BoltServerAddress.class ) ) ).then( invocation -> - { - BoltServerAddress requestedAddress = invocation.getArgument( 0 ); - if ( unavailableAddresses.contains( requestedAddress ) ) - { - return Futures.failedFuture( errorAction.apply( requestedAddress ) ); + private static ConnectionPool newConnectionPoolMockWithFailures( + Set unavailableAddresses, Function errorAction) { + ConnectionPool pool = mock(ConnectionPool.class); + when(pool.acquire(any(BoltServerAddress.class))).then(invocation -> { + BoltServerAddress requestedAddress = invocation.getArgument(0); + if (unavailableAddresses.contains(requestedAddress)) { + return Futures.failedFuture(errorAction.apply(requestedAddress)); } - return completedFuture( newBoltV4Connection( requestedAddress ) ); - } ); + return completedFuture(newBoltV4Connection(requestedAddress)); + }); return pool; } - private static Connection newBoltV4Connection( BoltServerAddress address ) - { - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( address ); - when( connection.protocol() ).thenReturn( BoltProtocol.forVersion( BoltProtocolV42.VERSION ) ); - when( connection.serverVersion() ).thenReturn( ServerVersion.v4_1_0 ); - when( connection.release() ).thenReturn( completedWithNull() ); + private static Connection newBoltV4Connection(BoltServerAddress address) { + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(address); + when(connection.protocol()).thenReturn(BoltProtocol.forVersion(BoltProtocolV42.VERSION)); + when(connection.serverVersion()).thenReturn(ServerVersion.v4_1_0); + when(connection.release()).thenReturn(completedWithNull()); return connection; } - private static ConnectionContext newBoltV4ConnectionContext() - { - return simple( true ); + private static ConnectionContext newBoltV4ConnectionContext() { + return simple(true); } - private static LoadBalancer newLoadBalancer( ConnectionPool connectionPool, RoutingTable routingTable ) - { + private static LoadBalancer newLoadBalancer(ConnectionPool connectionPool, RoutingTable routingTable) { // Used only in testing - RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); - RoutingTableHandler handler = mock( RoutingTableHandler.class ); - when( handler.routingTable() ).thenReturn( routingTable ); - when( routingTables.ensureRoutingTable( any( ConnectionContext.class ) ) ).thenReturn( CompletableFuture.completedFuture( handler ) ); - Rediscovery rediscovery = mock( Rediscovery.class ); - return new LoadBalancer( connectionPool, routingTables, rediscovery, new LeastConnectedLoadBalancingStrategy( connectionPool, DEV_NULL_LOGGING ), - GlobalEventExecutor.INSTANCE, DEV_NULL_LOGGING ); + RoutingTableRegistry routingTables = mock(RoutingTableRegistry.class); + RoutingTableHandler handler = mock(RoutingTableHandler.class); + when(handler.routingTable()).thenReturn(routingTable); + when(routingTables.ensureRoutingTable(any(ConnectionContext.class))) + .thenReturn(CompletableFuture.completedFuture(handler)); + Rediscovery rediscovery = mock(Rediscovery.class); + return new LoadBalancer( + connectionPool, + routingTables, + rediscovery, + new LeastConnectedLoadBalancingStrategy(connectionPool, DEV_NULL_LOGGING), + GlobalEventExecutor.INSTANCE, + DEV_NULL_LOGGING); } - private static LoadBalancer newLoadBalancer( ConnectionPool connectionPool, Rediscovery rediscovery ) - { + private static LoadBalancer newLoadBalancer(ConnectionPool connectionPool, Rediscovery rediscovery) { // Used only in testing - RoutingTableRegistry routingTables = mock( RoutingTableRegistry.class ); - return newLoadBalancer( connectionPool, routingTables, rediscovery ); + RoutingTableRegistry routingTables = mock(RoutingTableRegistry.class); + return newLoadBalancer(connectionPool, routingTables, rediscovery); } - private static LoadBalancer newLoadBalancer( ConnectionPool connectionPool, RoutingTableRegistry routingTables, Rediscovery rediscovery ) - { + private static LoadBalancer newLoadBalancer( + ConnectionPool connectionPool, RoutingTableRegistry routingTables, Rediscovery rediscovery) { // Used only in testing - return new LoadBalancer( connectionPool, routingTables, rediscovery, new LeastConnectedLoadBalancingStrategy( connectionPool, DEV_NULL_LOGGING ), - GlobalEventExecutor.INSTANCE, DEV_NULL_LOGGING ); + return new LoadBalancer( + connectionPool, + routingTables, + rediscovery, + new LeastConnectedLoadBalancingStrategy(connectionPool, DEV_NULL_LOGGING), + GlobalEventExecutor.INSTANCE, + DEV_NULL_LOGGING); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinArrayIndexTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinArrayIndexTest.java index 2be6a429c3..f0410e5ed4 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinArrayIndexTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinArrayIndexTest.java @@ -18,50 +18,44 @@ */ package org.neo4j.driver.internal.cluster.loadbalancing; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; -class RoundRobinArrayIndexTest -{ +import org.junit.jupiter.api.Test; + +class RoundRobinArrayIndexTest { @Test - void shouldHandleZeroLength() - { + void shouldHandleZeroLength() { RoundRobinArrayIndex roundRobinIndex = new RoundRobinArrayIndex(); - int index = roundRobinIndex.next( 0 ); + int index = roundRobinIndex.next(0); - assertEquals( -1, index ); + assertEquals(-1, index); } @Test - void shouldReturnIndexesInRoundRobinOrder() - { + void shouldReturnIndexesInRoundRobinOrder() { RoundRobinArrayIndex roundRobinIndex = new RoundRobinArrayIndex(); - for ( int i = 0; i < 10; i++ ) - { - int index = roundRobinIndex.next( 10 ); - assertEquals( i, index ); + for (int i = 0; i < 10; i++) { + int index = roundRobinIndex.next(10); + assertEquals(i, index); } - for ( int i = 0; i < 5; i++ ) - { - int index = roundRobinIndex.next( 5 ); - assertEquals( i, index ); + for (int i = 0; i < 5; i++) { + int index = roundRobinIndex.next(5); + assertEquals(i, index); } } @Test - void shouldHandleOverflow() - { + void shouldHandleOverflow() { int arrayLength = 10; - RoundRobinArrayIndex roundRobinIndex = new RoundRobinArrayIndex( Integer.MAX_VALUE - 1 ); + RoundRobinArrayIndex roundRobinIndex = new RoundRobinArrayIndex(Integer.MAX_VALUE - 1); - assertEquals( (Integer.MAX_VALUE - 1) % arrayLength, roundRobinIndex.next( arrayLength ) ); - assertEquals( Integer.MAX_VALUE % arrayLength, roundRobinIndex.next( arrayLength ) ); - assertEquals( 0, roundRobinIndex.next( arrayLength ) ); - assertEquals( 1, roundRobinIndex.next( arrayLength ) ); - assertEquals( 2, roundRobinIndex.next( arrayLength ) ); + assertEquals((Integer.MAX_VALUE - 1) % arrayLength, roundRobinIndex.next(arrayLength)); + assertEquals(Integer.MAX_VALUE % arrayLength, roundRobinIndex.next(arrayLength)); + assertEquals(0, roundRobinIndex.next(arrayLength)); + assertEquals(1, roundRobinIndex.next(arrayLength)); + assertEquals(2, roundRobinIndex.next(arrayLength)); } } 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 48356abf69..aa574d532b 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 @@ -18,10 +18,24 @@ */ package org.neo4j.driver.internal.cluster.loadbalancing; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Logging.none; +import static org.neo4j.driver.internal.DatabaseNameUtil.SYSTEM_DATABASE_NAME; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.cluster.RediscoveryUtil.contextWithDatabase; +import static org.neo4j.driver.internal.cluster.RoutingSettings.STALE_ROUTING_TABLE_PURGE_DELAY_MS; +import static org.neo4j.driver.util.TestUtil.await; + import io.netty.bootstrap.Bootstrap; import io.netty.util.concurrent.GlobalEventExecutor; -import org.junit.jupiter.api.Test; - import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; @@ -39,10 +53,9 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Logging; -import org.neo4j.driver.internal.metrics.MetricsListener; import org.neo4j.driver.exceptions.FatalDiscoveryException; import org.neo4j.driver.exceptions.ProtocolException; import org.neo4j.driver.internal.BoltServerAddress; @@ -59,341 +72,316 @@ import org.neo4j.driver.internal.cluster.RoutingTableRegistry; import org.neo4j.driver.internal.cluster.RoutingTableRegistryImpl; import org.neo4j.driver.internal.metrics.DevNullMetricsListener; +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 static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Logging.none; -import static org.neo4j.driver.internal.DatabaseNameUtil.SYSTEM_DATABASE_NAME; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.cluster.RediscoveryUtil.contextWithDatabase; -import static org.neo4j.driver.internal.cluster.RoutingSettings.STALE_ROUTING_TABLE_PURGE_DELAY_MS; -import static org.neo4j.driver.util.TestUtil.await; - -class RoutingTableAndConnectionPoolTest -{ - private static final BoltServerAddress A = new BoltServerAddress( "localhost:30000" ); - private static final BoltServerAddress B = new BoltServerAddress( "localhost:30001" ); - private static final BoltServerAddress C = new BoltServerAddress( "localhost:30002" ); - private static final BoltServerAddress D = new BoltServerAddress( "localhost:30003" ); - private static final BoltServerAddress E = new BoltServerAddress( "localhost:30004" ); - private static final BoltServerAddress F = new BoltServerAddress( "localhost:30005" ); - private static final List SERVERS = Collections.synchronizedList( new LinkedList<>( Arrays.asList( null, A, B, C, D, E, F ) ) ); +class RoutingTableAndConnectionPoolTest { + private static final BoltServerAddress A = new BoltServerAddress("localhost:30000"); + private static final BoltServerAddress B = new BoltServerAddress("localhost:30001"); + private static final BoltServerAddress C = new BoltServerAddress("localhost:30002"); + private static final BoltServerAddress D = new BoltServerAddress("localhost:30003"); + private static final BoltServerAddress E = new BoltServerAddress("localhost:30004"); + private static final BoltServerAddress F = new BoltServerAddress("localhost:30005"); + private static final List SERVERS = + Collections.synchronizedList(new LinkedList<>(Arrays.asList(null, A, B, C, D, E, F))); - private static final String[] DATABASES = new String[]{"", SYSTEM_DATABASE_NAME, "my database"}; + 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 Logging logging = none(); @Test - void shouldAddServerToRoutingTableAndConnectionPool() - { + void shouldAddServerToRoutingTableAndConnectionPool() { // Given ConnectionPool connectionPool = newConnectionPool(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ).thenReturn( clusterComposition( A ) ); - RoutingTableRegistryImpl routingTables = newRoutingTables( connectionPool, rediscovery ); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())).thenReturn(clusterComposition(A)); + RoutingTableRegistryImpl routingTables = newRoutingTables(connectionPool, rediscovery); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables); // When - await( loadBalancer.acquireConnection( contextWithDatabase( "neo4j" ) ) ); + await(loadBalancer.acquireConnection(contextWithDatabase("neo4j"))); // Then - assertThat( routingTables.allServers().size(), equalTo( 1 ) ); - assertTrue( routingTables.allServers().contains( A ) ); - assertTrue( routingTables.contains( database( "neo4j" ) ) ); - assertTrue( connectionPool.isOpen( A ) ); + assertThat(routingTables.allServers().size(), equalTo(1)); + assertTrue(routingTables.allServers().contains(A)); + assertTrue(routingTables.contains(database("neo4j"))); + assertTrue(connectionPool.isOpen(A)); } @Test - void shouldNotAddToRoutingTableWhenFailedWithRoutingError() - { + void shouldNotAddToRoutingTableWhenFailedWithRoutingError() { // Given ConnectionPool connectionPool = newConnectionPool(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ) - .thenReturn( Futures.failedFuture( new FatalDiscoveryException( "No database found" ) ) ); - RoutingTableRegistryImpl routingTables = newRoutingTables( connectionPool, rediscovery ); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())) + .thenReturn(Futures.failedFuture(new FatalDiscoveryException("No database found"))); + RoutingTableRegistryImpl routingTables = newRoutingTables(connectionPool, rediscovery); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables); // When - assertThrows( FatalDiscoveryException.class, () -> await( loadBalancer.acquireConnection( contextWithDatabase( "neo4j" ) ) ) ); + assertThrows( + FatalDiscoveryException.class, + () -> await(loadBalancer.acquireConnection(contextWithDatabase("neo4j")))); // Then - assertTrue( routingTables.allServers().isEmpty() ); - assertFalse( routingTables.contains( database( "neo4j" ) ) ); - assertFalse( connectionPool.isOpen( A ) ); + assertTrue(routingTables.allServers().isEmpty()); + assertFalse(routingTables.contains(database("neo4j"))); + assertFalse(connectionPool.isOpen(A)); } @Test - void shouldNotAddToRoutingTableWhenFailedWithProtocolError() - { + void shouldNotAddToRoutingTableWhenFailedWithProtocolError() { // Given ConnectionPool connectionPool = newConnectionPool(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ) - .thenReturn( Futures.failedFuture( new ProtocolException( "No database found" ) ) ); - RoutingTableRegistryImpl routingTables = newRoutingTables( connectionPool, rediscovery ); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())) + .thenReturn(Futures.failedFuture(new ProtocolException("No database found"))); + RoutingTableRegistryImpl routingTables = newRoutingTables(connectionPool, rediscovery); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables); // When - assertThrows( ProtocolException.class, () -> await( loadBalancer.acquireConnection( contextWithDatabase( "neo4j" ) ) ) ); + assertThrows( + ProtocolException.class, () -> await(loadBalancer.acquireConnection(contextWithDatabase("neo4j")))); // Then - assertTrue( routingTables.allServers().isEmpty() ); - assertFalse( routingTables.contains( database( "neo4j" ) ) ); - assertFalse( connectionPool.isOpen( A ) ); + assertTrue(routingTables.allServers().isEmpty()); + assertFalse(routingTables.contains(database("neo4j"))); + assertFalse(connectionPool.isOpen(A)); } @Test - void shouldNotAddToRoutingTableWhenFailedWithSecurityError() - { + void shouldNotAddToRoutingTableWhenFailedWithSecurityError() { // Given ConnectionPool connectionPool = newConnectionPool(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ) - .thenReturn( Futures.failedFuture( new SecurityException( "No database found" ) ) ); - RoutingTableRegistryImpl routingTables = newRoutingTables( connectionPool, rediscovery ); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())) + .thenReturn(Futures.failedFuture(new SecurityException("No database found"))); + RoutingTableRegistryImpl routingTables = newRoutingTables(connectionPool, rediscovery); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables); // When - assertThrows( SecurityException.class, () -> await( loadBalancer.acquireConnection( contextWithDatabase( "neo4j" ) ) ) ); + assertThrows( + SecurityException.class, () -> await(loadBalancer.acquireConnection(contextWithDatabase("neo4j")))); // Then - assertTrue( routingTables.allServers().isEmpty() ); - assertFalse( routingTables.contains( database( "neo4j" ) ) ); - assertFalse( connectionPool.isOpen( A ) ); + assertTrue(routingTables.allServers().isEmpty()); + assertFalse(routingTables.contains(database("neo4j"))); + assertFalse(connectionPool.isOpen(A)); } @Test - void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired() - { + void shouldNotRemoveNewlyAddedRoutingTableEvenIfItIsExpired() { // Given ConnectionPool connectionPool = newConnectionPool(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ).thenReturn( expiredClusterComposition( A ) ); - RoutingTableRegistryImpl routingTables = newRoutingTables( connectionPool, rediscovery ); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())).thenReturn(expiredClusterComposition(A)); + RoutingTableRegistryImpl routingTables = newRoutingTables(connectionPool, rediscovery); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables); // When - Connection connection = await( loadBalancer.acquireConnection( contextWithDatabase( "neo4j" ) ) ); - await( connection.release() ); + Connection connection = await(loadBalancer.acquireConnection(contextWithDatabase("neo4j"))); + await(connection.release()); // Then - assertTrue( routingTables.contains( database( "neo4j" ) ) ); + assertTrue(routingTables.contains(database("neo4j"))); - assertThat( routingTables.allServers().size(), equalTo( 1 ) ); - assertTrue( routingTables.allServers().contains( A ) ); + assertThat(routingTables.allServers().size(), equalTo(1)); + assertTrue(routingTables.allServers().contains(A)); - assertTrue( connectionPool.isOpen( A ) ); + assertTrue(connectionPool.isOpen(A)); } @Test - void shouldRemoveExpiredRoutingTableAndServers() - { + void shouldRemoveExpiredRoutingTableAndServers() { // Given ConnectionPool connectionPool = newConnectionPool(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ) - .thenReturn( expiredClusterComposition( A ) ) - .thenReturn( clusterComposition( B ) ); - RoutingTableRegistryImpl routingTables = newRoutingTables( connectionPool, rediscovery ); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())) + .thenReturn(expiredClusterComposition(A)) + .thenReturn(clusterComposition(B)); + RoutingTableRegistryImpl routingTables = newRoutingTables(connectionPool, rediscovery); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables); // When - Connection connection = await( loadBalancer.acquireConnection( contextWithDatabase( "neo4j" ) ) ); - await( connection.release() ); - await( loadBalancer.acquireConnection( contextWithDatabase( "foo" ) ) ); + Connection connection = await(loadBalancer.acquireConnection(contextWithDatabase("neo4j"))); + await(connection.release()); + await(loadBalancer.acquireConnection(contextWithDatabase("foo"))); // Then - assertFalse( routingTables.contains( database( "neo4j" ) ) ); - assertTrue( routingTables.contains( database( "foo" ) ) ); + assertFalse(routingTables.contains(database("neo4j"))); + assertTrue(routingTables.contains(database("foo"))); - assertThat( routingTables.allServers().size(), equalTo( 1 ) ); - assertTrue( routingTables.allServers().contains( B ) ); + assertThat(routingTables.allServers().size(), equalTo(1)); + assertTrue(routingTables.allServers().contains(B)); - assertTrue( connectionPool.isOpen( B ) ); + assertTrue(connectionPool.isOpen(B)); } @Test - void shouldRemoveExpiredRoutingTableButNotServer() - { + void shouldRemoveExpiredRoutingTableButNotServer() { // Given ConnectionPool connectionPool = newConnectionPool(); - Rediscovery rediscovery = mock( Rediscovery.class ); - when( rediscovery.lookupClusterComposition( any(), any(), any(), any() ) ) - .thenReturn( expiredClusterComposition( A ) ) - .thenReturn( clusterComposition( B ) ); - RoutingTableRegistryImpl routingTables = newRoutingTables( connectionPool, rediscovery ); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables ); + Rediscovery rediscovery = mock(Rediscovery.class); + when(rediscovery.lookupClusterComposition(any(), any(), any(), any())) + .thenReturn(expiredClusterComposition(A)) + .thenReturn(clusterComposition(B)); + RoutingTableRegistryImpl routingTables = newRoutingTables(connectionPool, rediscovery); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables); // When - await( loadBalancer.acquireConnection( contextWithDatabase( "neo4j" ) ) ); - await( loadBalancer.acquireConnection( contextWithDatabase( "foo" ) ) ); + await(loadBalancer.acquireConnection(contextWithDatabase("neo4j"))); + await(loadBalancer.acquireConnection(contextWithDatabase("foo"))); // Then - assertThat( routingTables.allServers().size(), equalTo( 1 ) ); - assertTrue( routingTables.allServers().contains( B ) ); - assertTrue( connectionPool.isOpen( B ) ); - assertFalse( routingTables.contains( database( "neo4j" ) ) ); - assertTrue( routingTables.contains( database( "foo" ) ) ); + assertThat(routingTables.allServers().size(), equalTo(1)); + assertTrue(routingTables.allServers().contains(B)); + assertTrue(connectionPool.isOpen(B)); + assertFalse(routingTables.contains(database("neo4j"))); + assertTrue(routingTables.contains(database("foo"))); // I still have A as A's connection is in use - assertTrue( connectionPool.isOpen( A ) ); + assertTrue(connectionPool.isOpen(A)); } @Test - void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwable - { + void shouldHandleAddAndRemoveFromRoutingTableAndConnectionPool() throws Throwable { // Given ConnectionPool connectionPool = newConnectionPool(); Rediscovery rediscovery = new RandomizedRediscovery(); - RoutingTableRegistry routingTables = newRoutingTables( connectionPool, rediscovery ); - LoadBalancer loadBalancer = newLoadBalancer( connectionPool, routingTables ); + RoutingTableRegistry routingTables = newRoutingTables(connectionPool, rediscovery); + LoadBalancer loadBalancer = newLoadBalancer(connectionPool, routingTables); // When - acquireAndReleaseConnections( loadBalancer ); + acquireAndReleaseConnections(loadBalancer); Set servers = routingTables.allServers(); BoltServerAddress openServer = null; - for ( BoltServerAddress server : servers ) - { - if ( connectionPool.isOpen( server ) ) - { + for (BoltServerAddress server : servers) { + if (connectionPool.isOpen(server)) { openServer = server; break; } } - assertNotNull( servers ); + assertNotNull(servers); // if we remove the open server from servers, then the connection pool should remove the server from the pool. - SERVERS.remove( openServer ); + SERVERS.remove(openServer); // ensure rediscovery is necessary on subsequent interaction - Arrays.stream( DATABASES ).map( DatabaseNameUtil::database ).forEach( routingTables::remove ); - acquireAndReleaseConnections( loadBalancer ); + Arrays.stream(DATABASES).map(DatabaseNameUtil::database).forEach(routingTables::remove); + acquireAndReleaseConnections(loadBalancer); - assertFalse( connectionPool.isOpen( openServer ) ); + assertFalse(connectionPool.isOpen(openServer)); } - private void acquireAndReleaseConnections( LoadBalancer loadBalancer ) throws InterruptedException - { - ExecutorService executorService = Executors.newFixedThreadPool( 4 ); + private void acquireAndReleaseConnections(LoadBalancer loadBalancer) throws InterruptedException { + ExecutorService executorService = Executors.newFixedThreadPool(4); int count = 100; Future[] futures = new Future[count]; - for ( int i = 0; i < count; i++ ) - { - Future future = executorService.submit( () -> { - int index = random.nextInt( DATABASES.length ); - CompletionStage task = loadBalancer.acquireConnection( contextWithDatabase( DATABASES[index] ) ).thenCompose( Connection::release ); - await( task ); - } ); + for (int i = 0; i < count; i++) { + Future future = executorService.submit(() -> { + int index = random.nextInt(DATABASES.length); + CompletionStage task = loadBalancer + .acquireConnection(contextWithDatabase(DATABASES[index])) + .thenCompose(Connection::release); + await(task); + }); futures[i] = future; } executorService.shutdown(); - executorService.awaitTermination( 10, TimeUnit.SECONDS ); + executorService.awaitTermination(10, TimeUnit.SECONDS); List errors = new ArrayList<>(); - for ( Future f : futures ) - { - try - { + for (Future f : futures) { + try { f.get(); - } - catch ( ExecutionException e ) - { - errors.add( e.getCause() ); + } catch (ExecutionException e) { + errors.add(e.getCause()); } } // Then - assertThat( errors.size(), equalTo( 0 ) ); + assertThat(errors.size(), equalTo(0)); } - private ConnectionPool newConnectionPool() - { + private ConnectionPool newConnectionPool() { MetricsListener metrics = DevNullMetricsListener.INSTANCE; - PoolSettings poolSettings = new PoolSettings( 10, 5000, -1, -1 ); - Bootstrap bootstrap = BootstrapFactory.newBootstrap( 1 ); - NettyChannelTracker channelTracker = new NettyChannelTracker( metrics, bootstrap.config().group().next(), logging ); - NettyChannelHealthChecker channelHealthChecker = new NettyChannelHealthChecker( poolSettings, clock, logging ); - - return new TestConnectionPool( bootstrap, channelTracker, channelHealthChecker, poolSettings, metrics, logging, clock, true ); + PoolSettings poolSettings = new PoolSettings(10, 5000, -1, -1); + Bootstrap bootstrap = BootstrapFactory.newBootstrap(1); + NettyChannelTracker channelTracker = + new NettyChannelTracker(metrics, bootstrap.config().group().next(), logging); + NettyChannelHealthChecker channelHealthChecker = new NettyChannelHealthChecker(poolSettings, clock, logging); + + return new TestConnectionPool( + bootstrap, channelTracker, channelHealthChecker, poolSettings, metrics, logging, clock, true); } - private RoutingTableRegistryImpl newRoutingTables( ConnectionPool connectionPool, Rediscovery rediscovery ) - { - return new RoutingTableRegistryImpl( connectionPool, rediscovery, clock, logging, STALE_ROUTING_TABLE_PURGE_DELAY_MS ); + private RoutingTableRegistryImpl newRoutingTables(ConnectionPool connectionPool, Rediscovery rediscovery) { + return new RoutingTableRegistryImpl( + connectionPool, rediscovery, clock, logging, STALE_ROUTING_TABLE_PURGE_DELAY_MS); } - private LoadBalancer newLoadBalancer( ConnectionPool connectionPool, RoutingTableRegistry routingTables ) - { - Rediscovery rediscovery = mock( Rediscovery.class ); - return new LoadBalancer( connectionPool, routingTables, rediscovery, new LeastConnectedLoadBalancingStrategy( connectionPool, logging ), - GlobalEventExecutor.INSTANCE, logging ); + private LoadBalancer newLoadBalancer(ConnectionPool connectionPool, RoutingTableRegistry routingTables) { + Rediscovery rediscovery = mock(Rediscovery.class); + return new LoadBalancer( + connectionPool, + routingTables, + rediscovery, + new LeastConnectedLoadBalancingStrategy(connectionPool, logging), + GlobalEventExecutor.INSTANCE, + logging); } - private CompletableFuture clusterComposition( BoltServerAddress... addresses ) - { - return clusterComposition( Duration.ofSeconds( 30 ).toMillis(), addresses ); + private CompletableFuture clusterComposition(BoltServerAddress... addresses) { + return clusterComposition(Duration.ofSeconds(30).toMillis(), addresses); } - private CompletableFuture expiredClusterComposition( BoltServerAddress... addresses ) - { - return clusterComposition( -STALE_ROUTING_TABLE_PURGE_DELAY_MS - 1, addresses ); + private CompletableFuture expiredClusterComposition( + BoltServerAddress... addresses) { + return clusterComposition(-STALE_ROUTING_TABLE_PURGE_DELAY_MS - 1, addresses); } - private CompletableFuture clusterComposition( long expireAfterMs, BoltServerAddress... addresses ) - { - HashSet servers = new HashSet<>( Arrays.asList( addresses ) ); - ClusterComposition composition = new ClusterComposition( clock.millis() + expireAfterMs, servers, servers, servers, null ); - return CompletableFuture.completedFuture( new ClusterCompositionLookupResult( composition ) ); + private CompletableFuture clusterComposition( + long expireAfterMs, BoltServerAddress... addresses) { + HashSet servers = new HashSet<>(Arrays.asList(addresses)); + ClusterComposition composition = + new ClusterComposition(clock.millis() + expireAfterMs, servers, servers, servers, null); + return CompletableFuture.completedFuture(new ClusterCompositionLookupResult(composition)); } - private class RandomizedRediscovery implements Rediscovery - { + private class RandomizedRediscovery implements Rediscovery { @Override - public CompletionStage lookupClusterComposition( RoutingTable routingTable, ConnectionPool connectionPool, - Bookmark bookmark, String impersonatedUser ) - { + public CompletionStage lookupClusterComposition( + RoutingTable routingTable, ConnectionPool connectionPool, Bookmark bookmark, String impersonatedUser) { // when looking up a new routing table, we return a valid random routing table back Set servers = new HashSet<>(); - for ( int i = 0; i < 3; i++ ) - { - int index = random.nextInt( SERVERS.size() ); - BoltServerAddress server = SERVERS.get( index ); - if ( server != null ) - { - servers.add( server ); + for (int i = 0; i < 3; i++) { + int index = random.nextInt(SERVERS.size()); + BoltServerAddress server = SERVERS.get(index); + if (server != null) { + servers.add(server); } } - if ( servers.size() == 0 ) - { + if (servers.size() == 0) { BoltServerAddress address = SERVERS.stream() - .filter( Objects::nonNull ) - .findFirst() - .orElseThrow( () -> new RuntimeException( "No non null server addresses are available" ) ); - servers.add( address ); + .filter(Objects::nonNull) + .findFirst() + .orElseThrow(() -> new RuntimeException("No non null server addresses are available")); + servers.add(address); } - ClusterComposition composition = new ClusterComposition( clock.millis() + 1, servers, servers, servers, null ); - return CompletableFuture.completedFuture( new ClusterCompositionLookupResult( composition ) ); + ClusterComposition composition = + new ClusterComposition(clock.millis() + 1, servers, servers, servers, null); + return CompletableFuture.completedFuture(new ClusterCompositionLookupResult(composition)); } @Override - public List resolve() - { - throw new UnsupportedOperationException( "Not implemented" ); + public List resolve() { + throw new UnsupportedOperationException("Not implemented"); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cursor/AsyncResultCursorOnlyFactoryTest.java b/driver/src/test/java/org/neo4j/driver/internal/cursor/AsyncResultCursorOnlyFactoryTest.java index c1e67eac1e..4090b48cad 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cursor/AsyncResultCursorOnlyFactoryTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cursor/AsyncResultCursorOnlyFactoryTest.java @@ -18,18 +18,6 @@ */ package org.neo4j.driver.internal.cursor; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.CompletionStage; - -import org.neo4j.driver.internal.handlers.PullAllResponseHandler; -import org.neo4j.driver.internal.handlers.RunResponseHandler; -import org.neo4j.driver.internal.handlers.pulln.AutoPullResponseHandler; -import org.neo4j.driver.internal.messaging.Message; -import org.neo4j.driver.internal.spi.Connection; - import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertThat; @@ -41,102 +29,104 @@ import static org.neo4j.driver.internal.util.Futures.getNow; import static org.neo4j.driver.util.TestUtil.await; -class AsyncResultCursorOnlyFactoryTest -{ +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.handlers.PullAllResponseHandler; +import org.neo4j.driver.internal.handlers.RunResponseHandler; +import org.neo4j.driver.internal.handlers.pulln.AutoPullResponseHandler; +import org.neo4j.driver.internal.messaging.Message; +import org.neo4j.driver.internal.spi.Connection; + +class AsyncResultCursorOnlyFactoryTest { // asyncResult @Test - void shouldReturnAsyncResultWhenRunSucceeded() - { + void shouldReturnAsyncResultWhenRunSucceeded() { // Given - Connection connection = mock( Connection.class ); - ResultCursorFactory cursorFactory = newResultCursorFactory( connection, null ); + Connection connection = mock(Connection.class); + ResultCursorFactory cursorFactory = newResultCursorFactory(connection, null); // When CompletionStage cursorFuture = cursorFactory.asyncResult(); // Then - verifyRunCompleted( connection, cursorFuture ); + verifyRunCompleted(connection, cursorFuture); } @Test - void shouldReturnAsyncResultWithRunErrorWhenRunFailed() - { + void shouldReturnAsyncResultWithRunErrorWhenRunFailed() { // Given - Throwable error = new RuntimeException( "Hi there" ); - ResultCursorFactory cursorFactory = newResultCursorFactory( error ); + Throwable error = new RuntimeException("Hi there"); + ResultCursorFactory cursorFactory = newResultCursorFactory(error); // When CompletionStage cursorFuture = cursorFactory.asyncResult(); // Then - AsyncResultCursor cursor = getNow( cursorFuture ); - Throwable actual = assertThrows( error.getClass(), () -> await( cursor.mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + AsyncResultCursor cursor = getNow(cursorFuture); + Throwable actual = assertThrows(error.getClass(), () -> await(cursor.mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } @Test - void shouldPrePopulateRecords() - { + void shouldPrePopulateRecords() { // Given - Connection connection = mock( Connection.class ); - Message runMessage = mock( Message.class ); + Connection connection = mock(Connection.class); + Message runMessage = mock(Message.class); - RunResponseHandler runHandler = mock( RunResponseHandler.class ); + RunResponseHandler runHandler = mock(RunResponseHandler.class); CompletableFuture runFuture = new CompletableFuture<>(); - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - ResultCursorFactory cursorFactory = new AsyncResultCursorOnlyFactory( connection, runMessage, runHandler, runFuture, pullAllHandler ); + ResultCursorFactory cursorFactory = + new AsyncResultCursorOnlyFactory(connection, runMessage, runHandler, runFuture, pullAllHandler); // When cursorFactory.asyncResult(); // Then - verify( pullAllHandler ).prePopulateRecords(); + verify(pullAllHandler).prePopulateRecords(); } // rxResult @Test - void shouldErrorForRxResult() - { + void shouldErrorForRxResult() { // Given - ResultCursorFactory cursorFactory = newResultCursorFactory( null ); + ResultCursorFactory cursorFactory = newResultCursorFactory(null); // When & Then CompletionStage rxCursorFuture = cursorFactory.rxResult(); - CompletionException error = assertThrows( CompletionException.class, () -> getNow( rxCursorFuture ) ); - assertThat( error.getCause().getMessage(), containsString( "Driver is connected to the database that does not support driver reactive API" ) ); + CompletionException error = assertThrows(CompletionException.class, () -> getNow(rxCursorFuture)); + assertThat( + error.getCause().getMessage(), + containsString("Driver is connected to the database that does not support driver reactive API")); } - private AsyncResultCursorOnlyFactory newResultCursorFactory( Connection connection, Throwable runError ) - { - Message runMessage = mock( Message.class ); + private AsyncResultCursorOnlyFactory newResultCursorFactory(Connection connection, Throwable runError) { + Message runMessage = mock(Message.class); - RunResponseHandler runHandler = mock( RunResponseHandler.class ); + RunResponseHandler runHandler = mock(RunResponseHandler.class); CompletableFuture runFuture = new CompletableFuture<>(); - if ( runError != null ) - { - runFuture.completeExceptionally( runError ); - } - else - { - runFuture.complete( null ); + if (runError != null) { + runFuture.completeExceptionally(runError); + } else { + runFuture.complete(null); } - AutoPullResponseHandler pullHandler = mock( AutoPullResponseHandler.class ); + AutoPullResponseHandler pullHandler = mock(AutoPullResponseHandler.class); - return new AsyncResultCursorOnlyFactory( connection, runMessage, runHandler, runFuture, pullHandler ); + return new AsyncResultCursorOnlyFactory(connection, runMessage, runHandler, runFuture, pullHandler); } - private AsyncResultCursorOnlyFactory newResultCursorFactory( Throwable runError ) - { - Connection connection = mock( Connection.class ); - return newResultCursorFactory( connection, runError ); + private AsyncResultCursorOnlyFactory newResultCursorFactory(Throwable runError) { + Connection connection = mock(Connection.class); + return newResultCursorFactory(connection, runError); } - private void verifyRunCompleted( Connection connection, CompletionStage cursorFuture ) - { - verify( connection ).write( any( Message.class ), any( RunResponseHandler.class ) ); - assertThat( getNow( cursorFuture ), instanceOf( AsyncResultCursor.class ) ); + private void verifyRunCompleted(Connection connection, CompletionStage cursorFuture) { + verify(connection).write(any(Message.class), any(RunResponseHandler.class)); + assertThat(getNow(cursorFuture), instanceOf(AsyncResultCursor.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cursor/DisposableAsyncResultCursorTest.java b/driver/src/test/java/org/neo4j/driver/internal/cursor/DisposableAsyncResultCursorTest.java index dce0ba1481..8d1614e4ec 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cursor/DisposableAsyncResultCursorTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cursor/DisposableAsyncResultCursorTest.java @@ -18,13 +18,6 @@ */ package org.neo4j.driver.internal.cursor; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.CompletableFuture; - -import org.neo4j.driver.internal.util.Futures; - import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -36,93 +29,89 @@ import static org.mockito.Mockito.when; import static org.neo4j.driver.util.TestUtil.await; -class DisposableAsyncResultCursorTest -{ +import java.util.concurrent.CompletableFuture; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.util.Futures; + +class DisposableAsyncResultCursorTest { DisposableAsyncResultCursor cursor; AsyncResultCursor delegate; @BeforeEach - void beforeEach() - { - delegate = mock( AsyncResultCursor.class ); - - when( delegate.consumeAsync() ).thenReturn( Futures.completedWithNull() ); - when( delegate.discardAllFailureAsync() ).thenReturn( Futures.completedWithNull() ); - when( delegate.peekAsync() ).thenReturn( Futures.completedWithNull() ); - when( delegate.nextAsync() ).thenReturn( Futures.completedWithNull() ); - when( delegate.singleAsync() ).thenReturn( Futures.completedWithNull() ); - when( delegate.forEachAsync( any() ) ).thenReturn( Futures.completedWithNull() ); - when( delegate.listAsync() ).thenReturn( Futures.completedWithNull() ); - when( delegate.listAsync( any() ) ).thenReturn( Futures.completedWithNull() ); - when( delegate.pullAllFailureAsync() ).thenReturn( Futures.completedWithNull() ); - when( delegate.mapSuccessfulRunCompletionAsync() ).thenReturn( CompletableFuture.completedFuture( delegate ) ); - - cursor = new DisposableAsyncResultCursor( delegate ); + void beforeEach() { + delegate = mock(AsyncResultCursor.class); + + when(delegate.consumeAsync()).thenReturn(Futures.completedWithNull()); + when(delegate.discardAllFailureAsync()).thenReturn(Futures.completedWithNull()); + when(delegate.peekAsync()).thenReturn(Futures.completedWithNull()); + when(delegate.nextAsync()).thenReturn(Futures.completedWithNull()); + when(delegate.singleAsync()).thenReturn(Futures.completedWithNull()); + when(delegate.forEachAsync(any())).thenReturn(Futures.completedWithNull()); + when(delegate.listAsync()).thenReturn(Futures.completedWithNull()); + when(delegate.listAsync(any())).thenReturn(Futures.completedWithNull()); + when(delegate.pullAllFailureAsync()).thenReturn(Futures.completedWithNull()); + when(delegate.mapSuccessfulRunCompletionAsync()).thenReturn(CompletableFuture.completedFuture(delegate)); + + cursor = new DisposableAsyncResultCursor(delegate); } @Test - void summaryShouldDisposeCursor() - { + void summaryShouldDisposeCursor() { // When - await( cursor.consumeAsync() ); + await(cursor.consumeAsync()); // Then - assertTrue( cursor.isDisposed() ); + assertTrue(cursor.isDisposed()); } @Test - void consumeShouldDisposeCursor() - { + void consumeShouldDisposeCursor() { // When - await( cursor.discardAllFailureAsync() ); + await(cursor.discardAllFailureAsync()); // Then - assertTrue( cursor.isDisposed() ); + assertTrue(cursor.isDisposed()); } @Test - void shouldNotDisposeCursor() - { + void shouldNotDisposeCursor() { // When cursor.keys(); - await( cursor.peekAsync() ); - await( cursor.nextAsync() ); - await( cursor.singleAsync() ); - await( cursor.forEachAsync( record -> - { - } ) ); - await( cursor.listAsync() ); - await( cursor.listAsync( record -> record ) ); - await( cursor.pullAllFailureAsync() ); + await(cursor.peekAsync()); + await(cursor.nextAsync()); + await(cursor.singleAsync()); + await(cursor.forEachAsync(record -> {})); + await(cursor.listAsync()); + await(cursor.listAsync(record -> record)); + await(cursor.pullAllFailureAsync()); // Then - assertFalse( cursor.isDisposed() ); + assertFalse(cursor.isDisposed()); } @Test - void shouldReturnItselfOnMapSuccessfulRunCompletionAsync() - { + void shouldReturnItselfOnMapSuccessfulRunCompletionAsync() { // When - AsyncResultCursor actual = await( cursor.mapSuccessfulRunCompletionAsync() ); + AsyncResultCursor actual = await(cursor.mapSuccessfulRunCompletionAsync()); // Then - then( delegate ).should().mapSuccessfulRunCompletionAsync(); - assertSame( cursor, actual ); + then(delegate).should().mapSuccessfulRunCompletionAsync(); + assertSame(cursor, actual); } @Test - void shouldFailOnMapSuccessfulRunCompletionAsyncFailure() - { + void shouldFailOnMapSuccessfulRunCompletionAsyncFailure() { // Given - Throwable error = mock( Throwable.class ); - given( delegate.mapSuccessfulRunCompletionAsync() ).willReturn( Futures.failedFuture( error ) ); + Throwable error = mock(Throwable.class); + given(delegate.mapSuccessfulRunCompletionAsync()).willReturn(Futures.failedFuture(error)); // When - Throwable actual = assertThrows( Throwable.class, () -> await( cursor.mapSuccessfulRunCompletionAsync() ) ); + Throwable actual = assertThrows(Throwable.class, () -> await(cursor.mapSuccessfulRunCompletionAsync())); // Then - then( delegate ).should().mapSuccessfulRunCompletionAsync(); - assertSame( error, actual ); + then(delegate).should().mapSuccessfulRunCompletionAsync(); + assertSame(error, actual); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cursor/ResultCursorFactoryImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/cursor/ResultCursorFactoryImplTest.java index b67cc3ba03..95a8940b0c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cursor/ResultCursorFactoryImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cursor/ResultCursorFactoryImplTest.java @@ -18,17 +18,6 @@ */ package org.neo4j.driver.internal.cursor; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - -import org.neo4j.driver.internal.handlers.PullAllResponseHandler; -import org.neo4j.driver.internal.handlers.RunResponseHandler; -import org.neo4j.driver.internal.handlers.pulln.PullResponseHandler; -import org.neo4j.driver.internal.messaging.Message; -import org.neo4j.driver.internal.spi.Connection; - import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertThat; import static org.junit.jupiter.api.Assertions.assertSame; @@ -40,128 +29,125 @@ import static org.neo4j.driver.internal.util.Futures.getNow; import static org.neo4j.driver.util.TestUtil.await; -class ResultCursorFactoryImplTest -{ +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.handlers.PullAllResponseHandler; +import org.neo4j.driver.internal.handlers.RunResponseHandler; +import org.neo4j.driver.internal.handlers.pulln.PullResponseHandler; +import org.neo4j.driver.internal.messaging.Message; +import org.neo4j.driver.internal.spi.Connection; + +class ResultCursorFactoryImplTest { // asyncResult @Test - void shouldReturnAsyncResultWhenRunSucceeded() - { + void shouldReturnAsyncResultWhenRunSucceeded() { // Given - Connection connection = mock( Connection.class ); - ResultCursorFactory cursorFactory = newResultCursorFactory( connection, null ); + Connection connection = mock(Connection.class); + ResultCursorFactory cursorFactory = newResultCursorFactory(connection, null); // When CompletionStage cursorFuture = cursorFactory.asyncResult(); // Then - verifyRunCompleted( connection, cursorFuture ); + verifyRunCompleted(connection, cursorFuture); } @Test - void shouldReturnAsyncResultWithRunErrorWhenRunFailed() - { + void shouldReturnAsyncResultWithRunErrorWhenRunFailed() { // Given - Throwable error = new RuntimeException( "Hi there" ); - ResultCursorFactory cursorFactory = newResultCursorFactory( error ); + Throwable error = new RuntimeException("Hi there"); + ResultCursorFactory cursorFactory = newResultCursorFactory(error); // When CompletionStage cursorFuture = cursorFactory.asyncResult(); // Then - AsyncResultCursor cursor = getNow( cursorFuture ); - Throwable actual = assertThrows( error.getClass(), () -> await( cursor.mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + AsyncResultCursor cursor = getNow(cursorFuture); + Throwable actual = assertThrows(error.getClass(), () -> await(cursor.mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } @Test - void shouldPrePopulateRecords() - { + void shouldPrePopulateRecords() { // Given - Connection connection = mock( Connection.class ); - Message runMessage = mock( Message.class ); + Connection connection = mock(Connection.class); + Message runMessage = mock(Message.class); - RunResponseHandler runHandler = mock( RunResponseHandler.class ); + RunResponseHandler runHandler = mock(RunResponseHandler.class); CompletableFuture runFuture = new CompletableFuture<>(); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - ResultCursorFactory cursorFactory = new ResultCursorFactoryImpl( connection, runMessage, runHandler, runFuture, pullHandler, pullAllHandler ); + ResultCursorFactory cursorFactory = + new ResultCursorFactoryImpl(connection, runMessage, runHandler, runFuture, pullHandler, pullAllHandler); // When cursorFactory.asyncResult(); // Then - verify( pullAllHandler ).prePopulateRecords(); - verifyNoMoreInteractions( pullHandler ); + verify(pullAllHandler).prePopulateRecords(); + verifyNoMoreInteractions(pullHandler); } // rxResult @Test - void shouldReturnRxResultWhenRunSucceeded() - { + void shouldReturnRxResultWhenRunSucceeded() { // Given - Connection connection = mock( Connection.class ); - ResultCursorFactory cursorFactory = newResultCursorFactory( connection, null ); + Connection connection = mock(Connection.class); + ResultCursorFactory cursorFactory = newResultCursorFactory(connection, null); // When CompletionStage cursorFuture = cursorFactory.rxResult(); // Then - verifyRxRunCompleted( connection, cursorFuture ); + verifyRxRunCompleted(connection, cursorFuture); } @Test - void shouldReturnRxResultWhenRunFailed() - { + void shouldReturnRxResultWhenRunFailed() { // Given - Connection connection = mock( Connection.class ); - Throwable error = new RuntimeException( "Hi there" ); - ResultCursorFactory cursorFactory = newResultCursorFactory( connection, error ); + Connection connection = mock(Connection.class); + Throwable error = new RuntimeException("Hi there"); + ResultCursorFactory cursorFactory = newResultCursorFactory(connection, error); // When CompletionStage cursorFuture = cursorFactory.rxResult(); // Then - verifyRxRunCompleted( connection, cursorFuture ); + verifyRxRunCompleted(connection, cursorFuture); } - private ResultCursorFactoryImpl newResultCursorFactory( Connection connection, Throwable runError ) - { - Message runMessage = mock( Message.class ); + private ResultCursorFactoryImpl newResultCursorFactory(Connection connection, Throwable runError) { + Message runMessage = mock(Message.class); - RunResponseHandler runHandler = mock( RunResponseHandler.class ); + RunResponseHandler runHandler = mock(RunResponseHandler.class); CompletableFuture runFuture = new CompletableFuture<>(); - if ( runError != null ) - { - runFuture.completeExceptionally( runError ); - } - else - { - runFuture.complete( null ); + if (runError != null) { + runFuture.completeExceptionally(runError); + } else { + runFuture.complete(null); } - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - PullAllResponseHandler pullAllHandler = mock( PullAllResponseHandler.class ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + PullAllResponseHandler pullAllHandler = mock(PullAllResponseHandler.class); - return new ResultCursorFactoryImpl( connection, runMessage, runHandler, runFuture, pullHandler, pullAllHandler ); + return new ResultCursorFactoryImpl(connection, runMessage, runHandler, runFuture, pullHandler, pullAllHandler); } - private ResultCursorFactoryImpl newResultCursorFactory( Throwable runError ) - { - Connection connection = mock( Connection.class ); - return newResultCursorFactory( connection, runError ); + private ResultCursorFactoryImpl newResultCursorFactory(Throwable runError) { + Connection connection = mock(Connection.class); + return newResultCursorFactory(connection, runError); } - private void verifyRunCompleted( Connection connection, CompletionStage cursorFuture ) - { - verify( connection ).write( any( Message.class ), any( RunResponseHandler.class ) ); - assertThat( getNow( cursorFuture ), instanceOf( AsyncResultCursor.class ) ); + private void verifyRunCompleted(Connection connection, CompletionStage cursorFuture) { + verify(connection).write(any(Message.class), any(RunResponseHandler.class)); + assertThat(getNow(cursorFuture), instanceOf(AsyncResultCursor.class)); } - private void verifyRxRunCompleted( Connection connection, CompletionStage cursorFuture ) - { - verify( connection ).writeAndFlush( any( Message.class ), any( RunResponseHandler.class ) ); - assertThat( getNow( cursorFuture ), instanceOf( RxResultCursorImpl.class ) ); + private void verifyRxRunCompleted(Connection connection, CompletionStage cursorFuture) { + verify(connection).writeAndFlush(any(Message.class), any(RunResponseHandler.class)); + assertThat(getNow(cursorFuture), instanceOf(RxResultCursorImpl.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/cursor/RxResultCursorImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/cursor/RxResultCursorImplTest.java index cbb17380cf..bfd5a25d48 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cursor/RxResultCursorImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cursor/RxResultCursorImplTest.java @@ -18,23 +18,6 @@ */ package org.neo4j.driver.internal.cursor; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; -import java.util.function.BiConsumer; - -import org.neo4j.driver.exceptions.ResultConsumedException; -import org.neo4j.driver.internal.handlers.RunResponseHandler; -import org.neo4j.driver.internal.handlers.pulln.PullResponseHandler; -import org.neo4j.driver.internal.reactive.util.ListBasedPullHandler; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.summary.ResultSummary; - import static java.util.Arrays.asList; import static junit.framework.TestCase.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -53,169 +36,173 @@ import static org.neo4j.driver.internal.util.Futures.completedWithNull; import static org.neo4j.driver.internal.util.Futures.failedFuture; -class RxResultCursorImplTest -{ +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutionException; +import java.util.function.BiConsumer; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.neo4j.driver.exceptions.ResultConsumedException; +import org.neo4j.driver.internal.handlers.RunResponseHandler; +import org.neo4j.driver.internal.handlers.pulln.PullResponseHandler; +import org.neo4j.driver.internal.reactive.util.ListBasedPullHandler; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.summary.ResultSummary; + +class RxResultCursorImplTest { @Test - void shouldInstallSummaryConsumerWithoutReportingError() - { + void shouldInstallSummaryConsumerWithoutReportingError() { // Given - RuntimeException error = new RuntimeException( "Hi" ); - RunResponseHandler runHandler = newRunResponseHandler( error ); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); + RuntimeException error = new RuntimeException("Hi"); + RunResponseHandler runHandler = newRunResponseHandler(error); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); // When - new RxResultCursorImpl( error, runHandler, pullHandler ); + new RxResultCursorImpl(error, runHandler, pullHandler); // Then - verify( pullHandler ).installSummaryConsumer( any( BiConsumer.class ) ); - verifyNoMoreInteractions( pullHandler ); + verify(pullHandler).installSummaryConsumer(any(BiConsumer.class)); + verifyNoMoreInteractions(pullHandler); } @Test - void shouldReturnQueryKeys() - { + void shouldReturnQueryKeys() { // Given RunResponseHandler runHandler = newRunResponseHandler(); - List expected = asList( "key1", "key2", "key3" ); - runHandler.onSuccess( Collections.singletonMap( "fields", value( expected ) ) ); + List expected = asList("key1", "key2", "key3"); + runHandler.onSuccess(Collections.singletonMap("fields", value(expected))); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); // When - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); List actual = cursor.keys(); // Then - assertEquals( expected, actual ); + assertEquals(expected, actual); } @Test - void shouldSupportReturnQueryKeysMultipleTimes() - { + void shouldSupportReturnQueryKeysMultipleTimes() { // Given RunResponseHandler runHandler = newRunResponseHandler(); - List expected = asList( "key1", "key2", "key3" ); - runHandler.onSuccess( Collections.singletonMap( "fields", value( expected ) ) ); + List expected = asList("key1", "key2", "key3"); + runHandler.onSuccess(Collections.singletonMap("fields", value(expected))); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); // When - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // Then List actual = cursor.keys(); - assertEquals( expected, actual ); + assertEquals(expected, actual); // Many times actual = cursor.keys(); - assertEquals( expected, actual ); + assertEquals(expected, actual); actual = cursor.keys(); - assertEquals( expected, actual ); + assertEquals(expected, actual); } @Test - void shouldPull() - { + void shouldPull() { // Given RunResponseHandler runHandler = newRunResponseHandler(); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // When - cursor.request( 100 ); + cursor.request(100); // Then - verify( pullHandler ).request( 100 ); + verify(pullHandler).request(100); } @Test - void shouldPullUnboundedOnLongMax() - { + void shouldPullUnboundedOnLongMax() { // Given RunResponseHandler runHandler = newRunResponseHandler(); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // When - cursor.request( Long.MAX_VALUE ); + cursor.request(Long.MAX_VALUE); // Then - verify( pullHandler ).request( -1 ); + verify(pullHandler).request(-1); } @Test - void shouldCancel() - { + void shouldCancel() { // Given RunResponseHandler runHandler = newRunResponseHandler(); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // When cursor.cancel(); // Then - verify( pullHandler ).cancel(); + verify(pullHandler).cancel(); } @Test - void shouldInstallRecordConsumerAndReportError() - { + void shouldInstallRecordConsumerAndReportError() { // Given - RuntimeException error = new RuntimeException( "Hi" ); - BiConsumer recordConsumer = mock( BiConsumer.class ); + RuntimeException error = new RuntimeException("Hi"); + BiConsumer recordConsumer = mock(BiConsumer.class); // When - RunResponseHandler runHandler = newRunResponseHandler( error ); + RunResponseHandler runHandler = newRunResponseHandler(error); PullResponseHandler pullHandler = new ListBasedPullHandler(); - RxResultCursor cursor = new RxResultCursorImpl( error, runHandler, pullHandler ); - cursor.installRecordConsumer( recordConsumer ); + RxResultCursor cursor = new RxResultCursorImpl(error, runHandler, pullHandler); + cursor.installRecordConsumer(recordConsumer); // Then - verify( recordConsumer ).accept( null, error ); - verifyNoMoreInteractions( recordConsumer ); + verify(recordConsumer).accept(null, error); + verifyNoMoreInteractions(recordConsumer); } @Test - void shouldReturnSummaryFuture() - { + void shouldReturnSummaryFuture() { // Given RunResponseHandler runHandler = newRunResponseHandler(); PullResponseHandler pullHandler = new ListBasedPullHandler(); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // When - cursor.installRecordConsumer( DISCARD_RECORD_CONSUMER ); - cursor.request( 10 ); + cursor.installRecordConsumer(DISCARD_RECORD_CONSUMER); + cursor.request(10); cursor.summaryAsync(); // Then - assertTrue( cursor.isDone() ); + assertTrue(cursor.isDone()); } @Test - void shouldNotAllowToInstallRecordConsumerAfterSummary() - { + void shouldNotAllowToInstallRecordConsumerAfterSummary() { // Given RunResponseHandler runHandler = newRunResponseHandler(); PullResponseHandler pullHandler = new ListBasedPullHandler(); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // When cursor.summaryAsync(); // Then - assertThrows( ResultConsumedException.class, () -> cursor.installRecordConsumer( null ) ); + assertThrows(ResultConsumedException.class, () -> cursor.installRecordConsumer(null)); } @Test - void shouldAllowToCallSummaryMultipleTimes() - { + void shouldAllowToCallSummaryMultipleTimes() { // Given RunResponseHandler runHandler = newRunResponseHandler(); PullResponseHandler pullHandler = new ListBasedPullHandler(); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // When cursor.summaryAsync(); @@ -226,99 +213,98 @@ void shouldAllowToCallSummaryMultipleTimes() } @Test - void shouldOnlyInstallRecordConsumerOnce() - { + void shouldOnlyInstallRecordConsumerOnce() { // Given RunResponseHandler runHandler = newRunResponseHandler(); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // When - cursor.installRecordConsumer( DISCARD_RECORD_CONSUMER ); // any consumer - cursor.installRecordConsumer( DISCARD_RECORD_CONSUMER ); // any consumer + cursor.installRecordConsumer(DISCARD_RECORD_CONSUMER); // any consumer + cursor.installRecordConsumer(DISCARD_RECORD_CONSUMER); // any consumer // Then - verify( pullHandler ).installRecordConsumer( any() ); + verify(pullHandler).installRecordConsumer(any()); } @Test - void shouldCancelIfNotPulled() - { + void shouldCancelIfNotPulled() { // Given RunResponseHandler runHandler = newRunResponseHandler(); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); // When cursor.summaryAsync(); // Then - verify( pullHandler ).installRecordConsumer( DISCARD_RECORD_CONSUMER ); - verify( pullHandler ).cancel(); - assertFalse( cursor.isDone() ); + verify(pullHandler).installRecordConsumer(DISCARD_RECORD_CONSUMER); + verify(pullHandler).cancel(); + assertFalse(cursor.isDone()); } @Test - void shouldPropagateSummaryErrorViaSummaryStageWhenItIsRetrievedExternally() throws ExecutionException, InterruptedException - { + void shouldPropagateSummaryErrorViaSummaryStageWhenItIsRetrievedExternally() + throws ExecutionException, InterruptedException { // Given - RunResponseHandler runHandler = mock( RunResponseHandler.class ); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - @SuppressWarnings( "unchecked" ) - ArgumentCaptor> summaryConsumerCaptor = ArgumentCaptor.forClass( BiConsumer.class ); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); - verify( pullHandler, times( 1 ) ).installSummaryConsumer( summaryConsumerCaptor.capture() ); - BiConsumer summaryConsumer = summaryConsumerCaptor.getValue(); - RuntimeException exception = mock( RuntimeException.class ); + RunResponseHandler runHandler = mock(RunResponseHandler.class); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + @SuppressWarnings("unchecked") + ArgumentCaptor> summaryConsumerCaptor = + ArgumentCaptor.forClass(BiConsumer.class); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); + verify(pullHandler, times(1)).installSummaryConsumer(summaryConsumerCaptor.capture()); + BiConsumer summaryConsumer = summaryConsumerCaptor.getValue(); + RuntimeException exception = mock(RuntimeException.class); // When CompletionStage summaryStage = cursor.summaryAsync(); CompletionStage discardStage = cursor.discardAllFailureAsync(); - summaryConsumer.accept( null, exception ); + summaryConsumer.accept(null, exception); // Then - verify( pullHandler ).installRecordConsumer( DISCARD_RECORD_CONSUMER ); - verify( pullHandler ).cancel(); - ExecutionException actualException = assertThrows( ExecutionException.class, () -> summaryStage.toCompletableFuture().get() ); - assertSame( exception, actualException.getCause() ); - assertNull( discardStage.toCompletableFuture().get() ); + verify(pullHandler).installRecordConsumer(DISCARD_RECORD_CONSUMER); + verify(pullHandler).cancel(); + ExecutionException actualException = assertThrows( + ExecutionException.class, + () -> summaryStage.toCompletableFuture().get()); + assertSame(exception, actualException.getCause()); + assertNull(discardStage.toCompletableFuture().get()); } @Test - void shouldPropagateSummaryErrorViaDiscardStageWhenSummaryStageIsNotRetrievedExternally() throws ExecutionException, InterruptedException - { + void shouldPropagateSummaryErrorViaDiscardStageWhenSummaryStageIsNotRetrievedExternally() + throws ExecutionException, InterruptedException { // Given - RunResponseHandler runHandler = mock( RunResponseHandler.class ); - PullResponseHandler pullHandler = mock( PullResponseHandler.class ); - @SuppressWarnings( "unchecked" ) - ArgumentCaptor> summaryConsumerCaptor = ArgumentCaptor.forClass( BiConsumer.class ); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); - verify( pullHandler, times( 1 ) ).installSummaryConsumer( summaryConsumerCaptor.capture() ); - BiConsumer summaryConsumer = summaryConsumerCaptor.getValue(); - RuntimeException exception = mock( RuntimeException.class ); + RunResponseHandler runHandler = mock(RunResponseHandler.class); + PullResponseHandler pullHandler = mock(PullResponseHandler.class); + @SuppressWarnings("unchecked") + ArgumentCaptor> summaryConsumerCaptor = + ArgumentCaptor.forClass(BiConsumer.class); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); + verify(pullHandler, times(1)).installSummaryConsumer(summaryConsumerCaptor.capture()); + BiConsumer summaryConsumer = summaryConsumerCaptor.getValue(); + RuntimeException exception = mock(RuntimeException.class); // When CompletionStage discardStage = cursor.discardAllFailureAsync(); - summaryConsumer.accept( null, exception ); + summaryConsumer.accept(null, exception); // Then - verify( pullHandler ).installRecordConsumer( DISCARD_RECORD_CONSUMER ); - verify( pullHandler ).cancel(); - assertSame( exception, discardStage.toCompletableFuture().get().getCause() ); + verify(pullHandler).installRecordConsumer(DISCARD_RECORD_CONSUMER); + verify(pullHandler).cancel(); + assertSame(exception, discardStage.toCompletableFuture().get().getCause()); } - private static RunResponseHandler newRunResponseHandler( CompletableFuture runFuture ) - { - return new RunResponseHandler( runFuture, METADATA_EXTRACTOR, mock( Connection.class ), null ); + private static RunResponseHandler newRunResponseHandler(CompletableFuture runFuture) { + return new RunResponseHandler(runFuture, METADATA_EXTRACTOR, mock(Connection.class), null); } - private static RunResponseHandler newRunResponseHandler( Throwable error ) - { - return newRunResponseHandler( failedFuture( error ) ); + private static RunResponseHandler newRunResponseHandler(Throwable error) { + return newRunResponseHandler(failedFuture(error)); } - private static RunResponseHandler newRunResponseHandler() - { - return newRunResponseHandler( completedWithNull() ); + private static RunResponseHandler newRunResponseHandler() { + return newRunResponseHandler(completedWithNull()); } } 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 b8d6e17661..c118a24baa 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 @@ -18,19 +18,6 @@ */ package org.neo4j.driver.internal.handlers; -import io.netty.channel.embedded.EmbeddedChannel; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.ImmediateEventExecutor; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.CompletableFuture; - -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; - import static java.util.Collections.emptyMap; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -43,66 +30,68 @@ import static org.neo4j.driver.internal.async.connection.ChannelAttributes.lastUsedTimestamp; import static org.neo4j.driver.internal.util.Futures.completedWithNull; -class ChannelReleasingResetResponseHandlerTest -{ +import io.netty.channel.embedded.EmbeddedChannel; +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 { private final EmbeddedChannel channel = new EmbeddedChannel(); - private final InboundMessageDispatcher messageDispatcher = mock( InboundMessageDispatcher.class ); + private final InboundMessageDispatcher messageDispatcher = mock(InboundMessageDispatcher.class); @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldReleaseChannelOnSuccess() - { + void shouldReleaseChannelOnSuccess() { ExtendedChannelPool pool = newChannelPoolMock(); FakeClock clock = new FakeClock(); - clock.progress( 5 ); + clock.progress(5); CompletableFuture releaseFuture = new CompletableFuture<>(); - ChannelReleasingResetResponseHandler handler = newHandler( pool, clock, releaseFuture ); + ChannelReleasingResetResponseHandler handler = newHandler(pool, clock, releaseFuture); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - verifyLastUsedTimestamp( 5 ); - verify( pool ).release( eq( channel ) ); - assertTrue( releaseFuture.isDone() ); - assertFalse( releaseFuture.isCompletedExceptionally() ); + verifyLastUsedTimestamp(5); + verify(pool).release(eq(channel)); + assertTrue(releaseFuture.isDone()); + assertFalse(releaseFuture.isCompletedExceptionally()); } @Test - void shouldCloseAndReleaseChannelOnFailure() - { + void shouldCloseAndReleaseChannelOnFailure() { ExtendedChannelPool pool = newChannelPoolMock(); FakeClock clock = new FakeClock(); - clock.progress( 100 ); + clock.progress(100); CompletableFuture releaseFuture = new CompletableFuture<>(); - ChannelReleasingResetResponseHandler handler = newHandler( pool, clock, releaseFuture ); + ChannelReleasingResetResponseHandler handler = newHandler(pool, clock, releaseFuture); - handler.onFailure( new RuntimeException() ); + handler.onFailure(new RuntimeException()); - assertTrue( channel.closeFuture().isDone() ); - verify( pool ).release( eq( channel ) ); - assertTrue( releaseFuture.isDone() ); - assertFalse( releaseFuture.isCompletedExceptionally() ); + assertTrue(channel.closeFuture().isDone()); + verify(pool).release(eq(channel)); + assertTrue(releaseFuture.isDone()); + assertFalse(releaseFuture.isCompletedExceptionally()); } - private void verifyLastUsedTimestamp( int expectedValue ) - { - assertEquals( expectedValue, lastUsedTimestamp( channel ).intValue() ); + private void verifyLastUsedTimestamp(int expectedValue) { + assertEquals(expectedValue, lastUsedTimestamp(channel).intValue()); } - private ChannelReleasingResetResponseHandler newHandler( ExtendedChannelPool pool, Clock clock, - CompletableFuture releaseFuture ) - { - return new ChannelReleasingResetResponseHandler( channel, pool, messageDispatcher, clock, releaseFuture ); + private ChannelReleasingResetResponseHandler newHandler( + ExtendedChannelPool pool, Clock clock, CompletableFuture releaseFuture) { + return new ChannelReleasingResetResponseHandler(channel, pool, messageDispatcher, clock, releaseFuture); } - private static ExtendedChannelPool newChannelPoolMock() - { - ExtendedChannelPool pool = mock( ExtendedChannelPool.class ); - when( pool.release( any() ) ).thenReturn( completedWithNull() ); + private static ExtendedChannelPool newChannelPoolMock() { + ExtendedChannelPool pool = mock(ExtendedChannelPool.class); + when(pool.release(any())).thenReturn(completedWithNull()); return pool; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/CommitTxResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/CommitTxResponseHandlerTest.java index a0e03b5cd4..c0bcde1421 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/CommitTxResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/CommitTxResponseHandlerTest.java @@ -18,14 +18,6 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.CompletableFuture; - -import org.neo4j.driver.Bookmark; -import org.neo4j.driver.Value; -import org.neo4j.driver.internal.InternalBookmark; - import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -34,43 +26,44 @@ import static org.neo4j.driver.Values.value; import static org.neo4j.driver.util.TestUtil.await; -class CommitTxResponseHandlerTest -{ +import java.util.concurrent.CompletableFuture; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Bookmark; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.InternalBookmark; + +class CommitTxResponseHandlerTest { private final CompletableFuture future = new CompletableFuture<>(); - private final CommitTxResponseHandler handler = new CommitTxResponseHandler( future ); + private final CommitTxResponseHandler handler = new CommitTxResponseHandler(future); @Test - void shouldHandleSuccessWithoutBookmark() - { - handler.onSuccess( emptyMap() ); + void shouldHandleSuccessWithoutBookmark() { + handler.onSuccess(emptyMap()); - assertNull( await( future ) ); + assertNull(await(future)); } @Test - void shouldHandleSuccessWithBookmark() - { + void shouldHandleSuccessWithBookmark() { String bookmarkString = "neo4j:bookmark:v1:tx12345"; - handler.onSuccess( singletonMap( "bookmark", value( bookmarkString ) ) ); + handler.onSuccess(singletonMap("bookmark", value(bookmarkString))); - assertEquals( InternalBookmark.parse( bookmarkString ), await( future ) ); + assertEquals(InternalBookmark.parse(bookmarkString), await(future)); } @Test - void shouldHandleFailure() - { - RuntimeException error = new RuntimeException( "Hello" ); + void shouldHandleFailure() { + RuntimeException error = new RuntimeException("Hello"); - handler.onFailure( error ); + handler.onFailure(error); - RuntimeException receivedError = assertThrows( RuntimeException.class, () -> await( future ) ); - assertEquals( error, receivedError ); + RuntimeException receivedError = assertThrows(RuntimeException.class, () -> await(future)); + assertEquals(error, receivedError); } @Test - void shouldFailToHandleRecord() - { - assertThrows( UnsupportedOperationException.class, () -> handler.onRecord( new Value[]{value( 42 )} ) ); + void shouldFailToHandleRecord() { + assertThrows(UnsupportedOperationException.class, () -> handler.onRecord(new Value[] {value(42)})); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/HelloResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/HelloResponseHandlerTest.java index bfe0f4c502..d1bfbf2a19 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/HelloResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/HelloResponseHandlerTest.java @@ -18,18 +18,30 @@ */ package org.neo4j.driver.internal.handlers; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.connectionId; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.connectionReadTimeout; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.serverAgent; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.serverVersion; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; +import static org.neo4j.driver.internal.async.outbound.OutboundMessageHandler.NAME; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; + import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.exceptions.UntrustedServerException; @@ -42,276 +54,234 @@ import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41; import org.neo4j.driver.internal.util.ServerVersion; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.connectionId; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.connectionReadTimeout; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.serverAgent; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.serverVersion; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; -import static org.neo4j.driver.internal.async.outbound.OutboundMessageHandler.NAME; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; - -class HelloResponseHandlerTest -{ +class HelloResponseHandlerTest { private final EmbeddedChannel channel = new EmbeddedChannel(); @BeforeEach - void setUp() - { - setMessageDispatcher( channel, new InboundMessageDispatcher( channel, DEV_NULL_LOGGING ) ); + void setUp() { + setMessageDispatcher(channel, new InboundMessageDispatcher(channel, DEV_NULL_LOGGING)); ChannelPipeline pipeline = channel.pipeline(); - pipeline.addLast( NAME, new OutboundMessageHandler( new MessageFormatV3(), DEV_NULL_LOGGING ) ); - pipeline.addLast( new ChannelErrorHandler( DEV_NULL_LOGGING ) ); + pipeline.addLast(NAME, new OutboundMessageHandler(new MessageFormatV3(), DEV_NULL_LOGGING)); + pipeline.addLast(new ChannelErrorHandler(DEV_NULL_LOGGING)); } @AfterEach - void tearDown() - { + void tearDown() { channel.finishAndReleaseAll(); } @Test - void shouldSetServerVersionOnChannel() - { + void shouldSetServerVersionOnChannel() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); - Map metadata = metadata( anyServerVersion(), "bolt-1" ); - handler.onSuccess( metadata ); + Map metadata = metadata(anyServerVersion(), "bolt-1"); + handler.onSuccess(metadata); - assertTrue( channelPromise.isSuccess() ); - assertEquals( anyServerVersion(), serverVersion( channel ) ); + assertTrue(channelPromise.isSuccess()); + assertEquals(anyServerVersion(), serverVersion(channel)); } @Test - void shouldSetServerAgentOnChannel() - { + void shouldSetServerAgentOnChannel() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); String agent = "Neo4j/4.2.5"; - Map metadata = metadata( agent, "bolt-1" ); - handler.onSuccess( metadata ); + Map metadata = metadata(agent, "bolt-1"); + handler.onSuccess(metadata); - assertTrue( channelPromise.isSuccess() ); - assertEquals( agent, serverAgent( channel ) ); + assertTrue(channelPromise.isSuccess()); + assertEquals(agent, serverAgent(channel)); } @Test - void shouldThrowWhenServerVersionNotReturned() - { + void shouldThrowWhenServerVersionNotReturned() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); - Map metadata = metadata( null, "bolt-1" ); - assertThrows( UntrustedServerException.class, () -> handler.onSuccess( metadata ) ); + Map metadata = metadata(null, "bolt-1"); + assertThrows(UntrustedServerException.class, () -> handler.onSuccess(metadata)); - assertFalse( channelPromise.isSuccess() ); // initialization failed - assertTrue( channel.closeFuture().isDone() ); // channel was closed + assertFalse(channelPromise.isSuccess()); // initialization failed + assertTrue(channel.closeFuture().isDone()); // channel was closed } @Test - void shouldThrowWhenServerVersionIsNull() - { + void shouldThrowWhenServerVersionIsNull() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); - Map metadata = metadata( Values.NULL, "bolt-x" ); - assertThrows( UntrustedServerException.class, () -> handler.onSuccess( metadata ) ); + Map metadata = metadata(Values.NULL, "bolt-x"); + assertThrows(UntrustedServerException.class, () -> handler.onSuccess(metadata)); - assertFalse( channelPromise.isSuccess() ); // initialization failed - assertTrue( channel.closeFuture().isDone() ); // channel was closed + assertFalse(channelPromise.isSuccess()); // initialization failed + assertTrue(channel.closeFuture().isDone()); // channel was closed } @Test - void shouldThrowWhenServerVersionCantBeParsed() - { + void shouldThrowWhenServerVersionCantBeParsed() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); - Map metadata = metadata( "WrongServerVersion", "bolt-x" ); - assertThrows( IllegalArgumentException.class, () -> handler.onSuccess( metadata ) ); + Map metadata = metadata("WrongServerVersion", "bolt-x"); + assertThrows(IllegalArgumentException.class, () -> handler.onSuccess(metadata)); - assertFalse( channelPromise.isSuccess() ); // initialization failed - assertTrue( channel.closeFuture().isDone() ); // channel was closed + assertFalse(channelPromise.isSuccess()); // initialization failed + assertTrue(channel.closeFuture().isDone()); // channel was closed } @Test - void shouldUseProtocolVersionForServerVersionWhenConnectedWithBoltV4() - { + void shouldUseProtocolVersionForServerVersionWhenConnectedWithBoltV4() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV4.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV4.VERSION); // server used in metadata should be ignored - Map metadata = metadata( ServerVersion.vInDev, "bolt-1" ); - handler.onSuccess( metadata ); + Map metadata = metadata(ServerVersion.vInDev, "bolt-1"); + handler.onSuccess(metadata); - assertTrue( channelPromise.isSuccess() ); - assertEquals( ServerVersion.v4_0_0, serverVersion( channel ) ); + assertTrue(channelPromise.isSuccess()); + assertEquals(ServerVersion.v4_0_0, serverVersion(channel)); } @Test - void shouldUseProtocolVersionForServerVersionWhenConnectedWithBoltV41() - { + void shouldUseProtocolVersionForServerVersionWhenConnectedWithBoltV41() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV41.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV41.VERSION); // server used in metadata should be ignored - Map metadata = metadata( ServerVersion.vInDev, "bolt-1" ); - handler.onSuccess( metadata ); + Map metadata = metadata(ServerVersion.vInDev, "bolt-1"); + handler.onSuccess(metadata); - assertTrue( channelPromise.isSuccess() ); - assertEquals( ServerVersion.v4_1_0, serverVersion( channel ) ); + assertTrue(channelPromise.isSuccess()); + assertEquals(ServerVersion.v4_1_0, serverVersion(channel)); } @Test - void shouldSetConnectionIdOnChannel() - { + void shouldSetConnectionIdOnChannel() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); - Map metadata = metadata( anyServerVersion(), "bolt-42" ); - handler.onSuccess( metadata ); + Map metadata = metadata(anyServerVersion(), "bolt-42"); + handler.onSuccess(metadata); - assertTrue( channelPromise.isSuccess() ); - assertEquals( "bolt-42", connectionId( channel ) ); + assertTrue(channelPromise.isSuccess()); + assertEquals("bolt-42", connectionId(channel)); } @Test - void shouldThrowWhenConnectionIdNotReturned() - { + void shouldThrowWhenConnectionIdNotReturned() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); - Map metadata = metadata( anyServerVersion(), null ); - assertThrows( IllegalStateException.class, () -> handler.onSuccess( metadata ) ); + Map metadata = metadata(anyServerVersion(), null); + assertThrows(IllegalStateException.class, () -> handler.onSuccess(metadata)); - assertFalse( channelPromise.isSuccess() ); // initialization failed - assertTrue( channel.closeFuture().isDone() ); // channel was closed + assertFalse(channelPromise.isSuccess()); // initialization failed + assertTrue(channel.closeFuture().isDone()); // channel was closed } @Test - void shouldThrowWhenConnectionIdIsNull() - { + void shouldThrowWhenConnectionIdIsNull() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); - Map metadata = metadata( anyServerVersion(), Values.NULL ); - assertThrows( IllegalStateException.class, () -> handler.onSuccess( metadata ) ); + Map metadata = metadata(anyServerVersion(), Values.NULL); + assertThrows(IllegalStateException.class, () -> handler.onSuccess(metadata)); - assertFalse( channelPromise.isSuccess() ); // initialization failed - assertTrue( channel.closeFuture().isDone() ); // channel was closed + assertFalse(channelPromise.isSuccess()); // initialization failed + assertTrue(channel.closeFuture().isDone()); // channel was closed } @Test - void shouldCloseChannelOnFailure() throws Exception - { + void shouldCloseChannelOnFailure() throws Exception { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV3.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV3.VERSION); - RuntimeException error = new RuntimeException( "Hi!" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("Hi!"); + handler.onFailure(error); ChannelFuture channelCloseFuture = channel.closeFuture(); - channelCloseFuture.await( 5, TimeUnit.SECONDS ); + channelCloseFuture.await(5, TimeUnit.SECONDS); - assertTrue( channelCloseFuture.isSuccess() ); - assertTrue( channelPromise.isDone() ); - assertEquals( error, channelPromise.cause() ); + assertTrue(channelCloseFuture.isSuccess()); + assertTrue(channelPromise.isDone()); + assertEquals(error, channelPromise.cause()); } @Test - void shouldNotThrowWhenConfigurationHintsAreAbsent() - { + void shouldNotThrowWhenConfigurationHintsAreAbsent() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV41.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV41.VERSION); - Map metadata = metadata( anyServerVersion(), "bolt-x" ); - handler.onSuccess( metadata ); + Map metadata = metadata(anyServerVersion(), "bolt-x"); + handler.onSuccess(metadata); - assertTrue( channelPromise.isSuccess() ); - assertFalse( channel.closeFuture().isDone() ); + assertTrue(channelPromise.isSuccess()); + assertFalse(channel.closeFuture().isDone()); } @Test - void shouldNotThrowWhenConfigurationHintsAreEmpty() - { + void shouldNotThrowWhenConfigurationHintsAreEmpty() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV41.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV41.VERSION); - Map metadata = metadata( anyServerVersion(), "bolt-x", value( new HashMap<>() ) ); - handler.onSuccess( metadata ); + Map metadata = metadata(anyServerVersion(), "bolt-x", value(new HashMap<>())); + handler.onSuccess(metadata); - assertTrue( channelPromise.isSuccess() ); - assertFalse( channel.closeFuture().isDone() ); + assertTrue(channelPromise.isSuccess()); + assertFalse(channel.closeFuture().isDone()); } @Test - void shouldNotThrowWhenConfigurationHintsAreNull() - { + void shouldNotThrowWhenConfigurationHintsAreNull() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV41.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV41.VERSION); - Map metadata = metadata( anyServerVersion(), "bolt-x", Values.NULL ); - handler.onSuccess( metadata ); + Map metadata = metadata(anyServerVersion(), "bolt-x", Values.NULL); + handler.onSuccess(metadata); - assertTrue( channelPromise.isSuccess() ); - assertFalse( channel.closeFuture().isDone() ); + assertTrue(channelPromise.isSuccess()); + assertFalse(channel.closeFuture().isDone()); } @Test - void shouldSetConnectionTimeoutHint() - { + void shouldSetConnectionTimeoutHint() { ChannelPromise channelPromise = channel.newPromise(); - HelloResponseHandler handler = new HelloResponseHandler( channelPromise, BoltProtocolV41.VERSION ); + HelloResponseHandler handler = new HelloResponseHandler(channelPromise, BoltProtocolV41.VERSION); long timeout = 15L; - Map hints = new HashMap<>(); - hints.put( HelloResponseHandler.CONNECTION_RECEIVE_TIMEOUT_SECONDS_KEY, value( timeout ) ); - Map metadata = metadata( anyServerVersion(), "bolt-x", value( hints ) ); - handler.onSuccess( metadata ); - - assertEquals( timeout, connectionReadTimeout( channel ).orElse( null ) ); - assertTrue( channelPromise.isSuccess() ); - assertFalse( channel.closeFuture().isDone() ); + Map hints = new HashMap<>(); + hints.put(HelloResponseHandler.CONNECTION_RECEIVE_TIMEOUT_SECONDS_KEY, value(timeout)); + Map metadata = metadata(anyServerVersion(), "bolt-x", value(hints)); + handler.onSuccess(metadata); + + assertEquals(timeout, connectionReadTimeout(channel).orElse(null)); + assertTrue(channelPromise.isSuccess()); + assertFalse(channel.closeFuture().isDone()); } - private static Map metadata( Object version, Object connectionId ) - { - return metadata( version, connectionId, null ); + private static Map metadata(Object version, Object connectionId) { + return metadata(version, connectionId, null); } - private static Map metadata( Object version, Object connectionId, Value hints ) - { - Map result = new HashMap<>(); + private static Map metadata(Object version, Object connectionId, Value hints) { + Map result = new HashMap<>(); - if ( version == null ) - { - result.put( "server", null ); - } - else if ( version instanceof Value && ((Value) version).isNull() ) - { - result.put( "server", Values.NULL ); - } - else - { - result.put( "server", value( version.toString() ) ); + if (version == null) { + result.put("server", null); + } else if (version instanceof Value && ((Value) version).isNull()) { + result.put("server", Values.NULL); + } else { + result.put("server", value(version.toString())); } - if ( connectionId == null ) - { - result.put( "connection_id", null ); - } - else - { - result.put( "connection_id", value( connectionId ) ); + if (connectionId == null) { + result.put("connection_id", null); + } else { + result.put("connection_id", value(connectionId)); } - result.put( HelloResponseHandler.CONFIGURATION_HINTS_KEY, hints ); + result.put(HelloResponseHandler.CONFIGURATION_HINTS_KEY, hints); return result; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/LegacyPullAllResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/LegacyPullAllResponseHandlerTest.java index e0a5855f89..c688d75902 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/LegacyPullAllResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/LegacyPullAllResponseHandlerTest.java @@ -18,18 +18,6 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; - -import org.neo4j.driver.Query; -import org.neo4j.driver.Record; -import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.summary.ResultSummary; - import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; @@ -46,201 +34,199 @@ import static org.neo4j.driver.Values.values; import static org.neo4j.driver.util.TestUtil.await; -class LegacyPullAllResponseHandlerTest extends PullAllResponseHandlerTestBase -{ +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Query; +import org.neo4j.driver.Record; +import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.summary.ResultSummary; + +class LegacyPullAllResponseHandlerTest extends PullAllResponseHandlerTestBase { @Test - void shouldDisableAutoReadWhenTooManyRecordsArrive() - { + void shouldDisableAutoReadWhenTooManyRecordsArrive() { Connection connection = connectionMock(); - LegacyPullAllResponseHandler handler = newHandler( asList( "key1", "key2" ), connection ); + LegacyPullAllResponseHandler handler = newHandler(asList("key1", "key2"), connection); - for ( int i = 0; i < LegacyPullAllResponseHandler.RECORD_BUFFER_HIGH_WATERMARK + 1; i++ ) - { - handler.onRecord( values( 100, 200 ) ); + for (int i = 0; i < LegacyPullAllResponseHandler.RECORD_BUFFER_HIGH_WATERMARK + 1; i++) { + handler.onRecord(values(100, 200)); } - verify( connection ).disableAutoRead(); + verify(connection).disableAutoRead(); } @Test - void shouldEnableAutoReadWhenRecordsRetrievedFromBuffer() - { + void shouldEnableAutoReadWhenRecordsRetrievedFromBuffer() { Connection connection = connectionMock(); - List keys = asList( "key1", "key2" ); - LegacyPullAllResponseHandler handler = newHandler( keys, connection ); + List keys = asList("key1", "key2"); + LegacyPullAllResponseHandler handler = newHandler(keys, connection); int i; - for ( i = 0; i < LegacyPullAllResponseHandler.RECORD_BUFFER_HIGH_WATERMARK + 1; i++ ) - { - handler.onRecord( values( 100, 200 ) ); + for (i = 0; i < LegacyPullAllResponseHandler.RECORD_BUFFER_HIGH_WATERMARK + 1; i++) { + handler.onRecord(values(100, 200)); } - verify( connection, never() ).enableAutoRead(); - verify( connection ).disableAutoRead(); + verify(connection, never()).enableAutoRead(); + verify(connection).disableAutoRead(); - while ( i-- > LegacyPullAllResponseHandler.RECORD_BUFFER_LOW_WATERMARK - 1 ) - { - Record record = await( handler.nextAsync() ); - assertNotNull( record ); - assertEquals( keys, record.keys() ); - assertEquals( 100, record.get( "key1" ).asInt() ); - assertEquals( 200, record.get( "key2" ).asInt() ); + while (i-- > LegacyPullAllResponseHandler.RECORD_BUFFER_LOW_WATERMARK - 1) { + Record record = await(handler.nextAsync()); + assertNotNull(record); + assertEquals(keys, record.keys()); + assertEquals(100, record.get("key1").asInt()); + assertEquals(200, record.get("key2").asInt()); } - verify( connection ).enableAutoRead(); + verify(connection).enableAutoRead(); } @Test - void shouldNotDisableAutoReadWhenSummaryRequested() - { + void shouldNotDisableAutoReadWhenSummaryRequested() { Connection connection = connectionMock(); - List keys = asList( "key1", "key2" ); - LegacyPullAllResponseHandler handler = newHandler( keys, connection ); + List keys = asList("key1", "key2"); + LegacyPullAllResponseHandler handler = newHandler(keys, connection); CompletableFuture summaryFuture = handler.consumeAsync().toCompletableFuture(); - assertFalse( summaryFuture.isDone() ); + assertFalse(summaryFuture.isDone()); int recordCount = LegacyPullAllResponseHandler.RECORD_BUFFER_HIGH_WATERMARK + 10; - for ( int i = 0; i < recordCount; i++ ) - { - handler.onRecord( values( "a", "b" ) ); + for (int i = 0; i < recordCount; i++) { + handler.onRecord(values("a", "b")); } - verify( connection, never() ).disableAutoRead(); + verify(connection, never()).disableAutoRead(); - handler.onSuccess( emptyMap() ); - assertTrue( summaryFuture.isDone() ); + handler.onSuccess(emptyMap()); + assertTrue(summaryFuture.isDone()); - ResultSummary summary = await( summaryFuture ); - assertNotNull( summary ); - assertNull( await( handler.nextAsync() ) ); + ResultSummary summary = await(summaryFuture); + assertNotNull(summary); + assertNull(await(handler.nextAsync())); } @Test - void shouldNotDisableAutoReadWhenFailureRequested() - { + void shouldNotDisableAutoReadWhenFailureRequested() { Connection connection = connectionMock(); - List keys = asList( "key1", "key2" ); - LegacyPullAllResponseHandler handler = newHandler( keys, connection ); + List keys = asList("key1", "key2"); + LegacyPullAllResponseHandler handler = newHandler(keys, connection); - CompletableFuture failureFuture = handler.pullAllFailureAsync().toCompletableFuture(); - assertFalse( failureFuture.isDone() ); + CompletableFuture failureFuture = + handler.pullAllFailureAsync().toCompletableFuture(); + assertFalse(failureFuture.isDone()); int recordCount = LegacyPullAllResponseHandler.RECORD_BUFFER_HIGH_WATERMARK + 5; - for ( int i = 0; i < recordCount; i++ ) - { - handler.onRecord( values( 123, 456 ) ); + for (int i = 0; i < recordCount; i++) { + handler.onRecord(values(123, 456)); } - verify( connection, never() ).disableAutoRead(); + verify(connection, never()).disableAutoRead(); - IllegalStateException error = new IllegalStateException( "Wrong config" ); - handler.onFailure( error ); + IllegalStateException error = new IllegalStateException("Wrong config"); + handler.onFailure(error); - assertTrue( failureFuture.isDone() ); - assertEquals( error, await( failureFuture ) ); + assertTrue(failureFuture.isDone()); + assertEquals(error, await(failureFuture)); - for ( int i = 0; i < recordCount; i++ ) - { - Record record = await( handler.nextAsync() ); - assertNotNull( record ); - assertEquals( keys, record.keys() ); - assertEquals( 123, record.get( "key1" ).asInt() ); - assertEquals( 456, record.get( "key2" ).asInt() ); + for (int i = 0; i < recordCount; i++) { + Record record = await(handler.nextAsync()); + assertNotNull(record); + assertEquals(keys, record.keys()); + assertEquals(123, record.get("key1").asInt()); + assertEquals(456, record.get("key2").asInt()); } - assertNull( await( handler.nextAsync() ) ); + assertNull(await(handler.nextAsync())); } @Test - void shouldEnableAutoReadOnConnectionWhenFailureRequestedButNotAvailable() throws Exception - { + void shouldEnableAutoReadOnConnectionWhenFailureRequestedButNotAvailable() throws Exception { Connection connection = connectionMock(); - LegacyPullAllResponseHandler handler = newHandler( asList( "key1", "key2" ), connection ); + LegacyPullAllResponseHandler handler = newHandler(asList("key1", "key2"), connection); - handler.onRecord( values( 1, 2 ) ); - handler.onRecord( values( 3, 4 ) ); + handler.onRecord(values(1, 2)); + handler.onRecord(values(3, 4)); - verify( connection, never() ).enableAutoRead(); - verify( connection, never() ).disableAutoRead(); + verify(connection, never()).enableAutoRead(); + verify(connection, never()).disableAutoRead(); - CompletableFuture failureFuture = handler.pullAllFailureAsync().toCompletableFuture(); - assertFalse( failureFuture.isDone() ); + CompletableFuture failureFuture = + handler.pullAllFailureAsync().toCompletableFuture(); + assertFalse(failureFuture.isDone()); - verify( connection ).enableAutoRead(); - verify( connection, never() ).disableAutoRead(); + verify(connection).enableAutoRead(); + verify(connection, never()).disableAutoRead(); - assertNotNull( await( handler.nextAsync() ) ); - assertNotNull( await( handler.nextAsync() ) ); + assertNotNull(await(handler.nextAsync())); + assertNotNull(await(handler.nextAsync())); - RuntimeException error = new RuntimeException( "Oh my!" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("Oh my!"); + handler.onFailure(error); - assertTrue( failureFuture.isDone() ); - assertEquals( error, failureFuture.get() ); + assertTrue(failureFuture.isDone()); + assertEquals(error, failureFuture.get()); } @Test - void shouldNotDisableAutoReadWhenAutoReadManagementDisabled() - { + void shouldNotDisableAutoReadWhenAutoReadManagementDisabled() { Connection connection = connectionMock(); - LegacyPullAllResponseHandler handler = newHandler( asList( "key1", "key2" ), connection ); + LegacyPullAllResponseHandler handler = newHandler(asList("key1", "key2"), connection); handler.disableAutoReadManagement(); - for ( int i = 0; i < LegacyPullAllResponseHandler.RECORD_BUFFER_HIGH_WATERMARK + 1; i++ ) - { - handler.onRecord( values( 100, 200 ) ); + for (int i = 0; i < LegacyPullAllResponseHandler.RECORD_BUFFER_HIGH_WATERMARK + 1; i++) { + handler.onRecord(values(100, 200)); } - verify( connection, never() ).disableAutoRead(); + verify(connection, never()).disableAutoRead(); } @Test - void shouldReturnEmptyListInListAsyncAfterFailure() - { + void shouldReturnEmptyListInListAsyncAfterFailure() { LegacyPullAllResponseHandler handler = newHandler(); - RuntimeException error = new RuntimeException( "Hi" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("Hi"); + handler.onFailure(error); // consume the error - assertEquals( error, await( handler.pullAllFailureAsync() ) ); - assertEquals( emptyList(), await( handler.listAsync( Function.identity() ) ) ); + assertEquals(error, await(handler.pullAllFailureAsync())); + assertEquals(emptyList(), await(handler.listAsync(Function.identity()))); } - @Test void shouldEnableAutoReadOnConnectionWhenSummaryRequestedButNotAvailable() throws Exception // TODO for auto run - { + { Connection connection = connectionMock(); - PullAllResponseHandler handler = newHandler( asList( "key1", "key2", "key3" ), connection ); + PullAllResponseHandler handler = newHandler(asList("key1", "key2", "key3"), connection); - handler.onRecord( values( 1, 2, 3 ) ); - handler.onRecord( values( 4, 5, 6 ) ); + handler.onRecord(values(1, 2, 3)); + handler.onRecord(values(4, 5, 6)); - verify( connection, never() ).enableAutoRead(); - verify( connection, never() ).disableAutoRead(); + verify(connection, never()).enableAutoRead(); + verify(connection, never()).disableAutoRead(); CompletableFuture summaryFuture = handler.consumeAsync().toCompletableFuture(); - assertFalse( summaryFuture.isDone() ); + assertFalse(summaryFuture.isDone()); - verify( connection ).enableAutoRead(); - verify( connection, never() ).disableAutoRead(); + verify(connection).enableAutoRead(); + verify(connection, never()).disableAutoRead(); - assertNull( await( handler.nextAsync() ) ); + assertNull(await(handler.nextAsync())); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - assertTrue( summaryFuture.isDone() ); - assertNotNull( summaryFuture.get() ); + assertTrue(summaryFuture.isDone()); + assertNotNull(summaryFuture.get()); } - protected LegacyPullAllResponseHandler newHandler(Query query, List queryKeys, - Connection connection ) - { - RunResponseHandler runResponseHandler = - new RunResponseHandler( new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock( Connection.class ), null ); - runResponseHandler.onSuccess( singletonMap( "fields", value( queryKeys ) ) ); - return new LegacyPullAllResponseHandler( query, runResponseHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, - mock( PullResponseCompletionListener.class ) ); + protected LegacyPullAllResponseHandler newHandler(Query query, List queryKeys, Connection connection) { + RunResponseHandler runResponseHandler = new RunResponseHandler( + new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock(Connection.class), null); + runResponseHandler.onSuccess(singletonMap("fields", value(queryKeys))); + return new LegacyPullAllResponseHandler( + query, + runResponseHandler, + connection, + BoltProtocolV3.METADATA_EXTRACTOR, + mock(PullResponseCompletionListener.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/PingResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/PingResponseHandlerTest.java index 23334120c5..3c12950f1b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/PingResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/PingResponseHandlerTest.java @@ -18,13 +18,6 @@ */ package org.neo4j.driver.internal.handlers; -import io.netty.channel.Channel; -import io.netty.util.concurrent.ImmediateEventExecutor; -import io.netty.util.concurrent.Promise; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.Value; - import static java.util.Collections.emptyMap; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -32,47 +25,47 @@ import static org.mockito.Mockito.mock; import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -class PingResponseHandlerTest -{ +import io.netty.channel.Channel; +import io.netty.util.concurrent.ImmediateEventExecutor; +import io.netty.util.concurrent.Promise; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; + +class PingResponseHandlerTest { @Test - void shouldResolvePromiseOnSuccess() - { + void shouldResolvePromiseOnSuccess() { Promise promise = newPromise(); - PingResponseHandler handler = newHandler( promise ); + PingResponseHandler handler = newHandler(promise); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - assertTrue( promise.isSuccess() ); - assertTrue( promise.getNow() ); + assertTrue(promise.isSuccess()); + assertTrue(promise.getNow()); } @Test - void shouldResolvePromiseOnFailure() - { + void shouldResolvePromiseOnFailure() { Promise promise = newPromise(); - PingResponseHandler handler = newHandler( promise ); + PingResponseHandler handler = newHandler(promise); - handler.onFailure( new RuntimeException() ); + handler.onFailure(new RuntimeException()); - assertTrue( promise.isSuccess() ); - assertFalse( promise.getNow() ); + assertTrue(promise.isSuccess()); + assertFalse(promise.getNow()); } @Test - void shouldNotSupportRecordMessages() - { - PingResponseHandler handler = newHandler( newPromise() ); + void shouldNotSupportRecordMessages() { + PingResponseHandler handler = newHandler(newPromise()); - assertThrows( UnsupportedOperationException.class, () -> handler.onRecord( new Value[0] ) ); + assertThrows(UnsupportedOperationException.class, () -> handler.onRecord(new Value[0])); } - private static Promise newPromise() - { + private static Promise newPromise() { return ImmediateEventExecutor.INSTANCE.newPromise(); } - private static PingResponseHandler newHandler( Promise result ) - { - return new PingResponseHandler( result, mock( Channel.class ), DEV_NULL_LOGGING ); + private static PingResponseHandler newHandler(Promise result) { + return new PingResponseHandler(result, mock(Channel.class), DEV_NULL_LOGGING); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/PullAllResponseHandlerTestBase.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/PullAllResponseHandlerTestBase.java index 78763751d0..85bc6d1493 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/PullAllResponseHandlerTestBase.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/PullAllResponseHandlerTestBase.java @@ -18,7 +18,23 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.Values.values; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; +import static org.neo4j.driver.util.TestUtil.await; import java.io.IOException; import java.nio.channels.ClosedChannelException; @@ -26,7 +42,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.Function; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -39,681 +55,623 @@ import org.neo4j.driver.summary.QueryType; import org.neo4j.driver.summary.ResultSummary; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.Values.values; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; -import static org.neo4j.driver.util.TestUtil.await; - -public abstract class PullAllResponseHandlerTestBase -{ +public abstract class PullAllResponseHandlerTestBase { @Test - void shouldReturnNoFailureWhenAlreadySucceeded() - { + void shouldReturnNoFailureWhenAlreadySucceeded() { PullAllResponseHandler handler = newHandler(); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - Throwable failure = await( handler.pullAllFailureAsync() ); + Throwable failure = await(handler.pullAllFailureAsync()); - assertNull( failure ); + assertNull(failure); } @Test - void shouldReturnNoFailureWhenSucceededAfterFailureRequested() - { + void shouldReturnNoFailureWhenSucceededAfterFailureRequested() { PullAllResponseHandler handler = newHandler(); - CompletableFuture failureFuture = handler.pullAllFailureAsync().toCompletableFuture(); - assertFalse( failureFuture.isDone() ); + CompletableFuture failureFuture = + handler.pullAllFailureAsync().toCompletableFuture(); + assertFalse(failureFuture.isDone()); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - assertTrue( failureFuture.isDone() ); - assertNull( await( failureFuture ) ); + assertTrue(failureFuture.isDone()); + assertNull(await(failureFuture)); } @Test - void shouldReturnFailureWhenAlreadyFailed() - { + void shouldReturnFailureWhenAlreadyFailed() { PullAllResponseHandler handler = newHandler(); - RuntimeException failure = new RuntimeException( "Ops" ); - handler.onFailure( failure ); + RuntimeException failure = new RuntimeException("Ops"); + handler.onFailure(failure); - Throwable receivedFailure = await( handler.pullAllFailureAsync() ); - assertEquals( failure, receivedFailure ); + Throwable receivedFailure = await(handler.pullAllFailureAsync()); + assertEquals(failure, receivedFailure); } @Test - void shouldReturnFailureWhenFailedAfterFailureRequested() - { + void shouldReturnFailureWhenFailedAfterFailureRequested() { PullAllResponseHandler handler = newHandler(); - CompletableFuture failureFuture = handler.pullAllFailureAsync().toCompletableFuture(); - assertFalse( failureFuture.isDone() ); + CompletableFuture failureFuture = + handler.pullAllFailureAsync().toCompletableFuture(); + assertFalse(failureFuture.isDone()); - IOException failure = new IOException( "Broken pipe" ); - handler.onFailure( failure ); + IOException failure = new IOException("Broken pipe"); + handler.onFailure(failure); - assertTrue( failureFuture.isDone() ); - assertEquals( failure, await( failureFuture ) ); + assertTrue(failureFuture.isDone()); + assertEquals(failure, await(failureFuture)); } @Test - void shouldReturnFailureWhenRequestedMultipleTimes() - { + void shouldReturnFailureWhenRequestedMultipleTimes() { PullAllResponseHandler handler = newHandler(); - CompletableFuture failureFuture1 = handler.pullAllFailureAsync().toCompletableFuture(); - CompletableFuture failureFuture2 = handler.pullAllFailureAsync().toCompletableFuture(); + CompletableFuture failureFuture1 = + handler.pullAllFailureAsync().toCompletableFuture(); + CompletableFuture failureFuture2 = + handler.pullAllFailureAsync().toCompletableFuture(); - assertFalse( failureFuture1.isDone() ); - assertFalse( failureFuture2.isDone() ); + assertFalse(failureFuture1.isDone()); + assertFalse(failureFuture2.isDone()); - RuntimeException failure = new RuntimeException( "Unable to contact database" ); - handler.onFailure( failure ); + RuntimeException failure = new RuntimeException("Unable to contact database"); + handler.onFailure(failure); - assertTrue( failureFuture1.isDone() ); - assertTrue( failureFuture2.isDone() ); + assertTrue(failureFuture1.isDone()); + assertTrue(failureFuture2.isDone()); - assertEquals( failure, await( failureFuture1 ) ); - assertEquals( failure, await( failureFuture2 ) ); + assertEquals(failure, await(failureFuture1)); + assertEquals(failure, await(failureFuture2)); } @Test - void shouldReturnFailureOnlyOnceWhenFailedBeforeFailureRequested() - { + void shouldReturnFailureOnlyOnceWhenFailedBeforeFailureRequested() { PullAllResponseHandler handler = newHandler(); - ServiceUnavailableException failure = new ServiceUnavailableException( "Connection terminated" ); - handler.onFailure( failure ); + ServiceUnavailableException failure = new ServiceUnavailableException("Connection terminated"); + handler.onFailure(failure); - assertEquals( failure, await( handler.pullAllFailureAsync() ) ); - assertNull( await( handler.pullAllFailureAsync() ) ); + assertEquals(failure, await(handler.pullAllFailureAsync())); + assertNull(await(handler.pullAllFailureAsync())); } @Test - void shouldReturnFailureOnlyOnceWhenFailedAfterFailureRequested() - { + void shouldReturnFailureOnlyOnceWhenFailedAfterFailureRequested() { PullAllResponseHandler handler = newHandler(); CompletionStage failureFuture = handler.pullAllFailureAsync(); - SessionExpiredException failure = new SessionExpiredException( "Network unreachable" ); - handler.onFailure( failure ); - assertEquals( failure, await( failureFuture ) ); + SessionExpiredException failure = new SessionExpiredException("Network unreachable"); + handler.onFailure(failure); + assertEquals(failure, await(failureFuture)); - assertNull( await( handler.pullAllFailureAsync() ) ); + assertNull(await(handler.pullAllFailureAsync())); } @Test - void shouldReturnSummaryWhenAlreadyFailedAndFailureConsumed() - { - Query query = new Query( "CREATE ()" ); + void shouldReturnSummaryWhenAlreadyFailedAndFailureConsumed() { + Query query = new Query("CREATE ()"); PullAllResponseHandler handler = newHandler(query); - ServiceUnavailableException failure = new ServiceUnavailableException( "Neo4j unreachable" ); - handler.onFailure( failure ); + ServiceUnavailableException failure = new ServiceUnavailableException("Neo4j unreachable"); + handler.onFailure(failure); - assertEquals( failure, await( handler.pullAllFailureAsync() ) ); + assertEquals(failure, await(handler.pullAllFailureAsync())); - ResultSummary summary = await( handler.consumeAsync() ); - assertNotNull( summary ); - assertEquals(query, summary.query() ); + ResultSummary summary = await(handler.consumeAsync()); + assertNotNull(summary); + assertEquals(query, summary.query()); } @Test - void shouldReturnSummaryWhenAlreadySucceeded() - { - Query query = new Query( "CREATE () RETURN 42" ); + void shouldReturnSummaryWhenAlreadySucceeded() { + Query query = new Query("CREATE () RETURN 42"); PullAllResponseHandler handler = newHandler(query); - handler.onSuccess( singletonMap( "type", value( "rw" ) ) ); + handler.onSuccess(singletonMap("type", value("rw"))); - ResultSummary summary = await( handler.consumeAsync() ); + ResultSummary summary = await(handler.consumeAsync()); - assertEquals(query, summary.query() ); - assertEquals( QueryType.READ_WRITE, summary.queryType() ); + assertEquals(query, summary.query()); + assertEquals(QueryType.READ_WRITE, summary.queryType()); } @Test - void shouldReturnSummaryWhenSucceededAfterSummaryRequested() - { - Query query = new Query( "RETURN 'Hi!" ); + void shouldReturnSummaryWhenSucceededAfterSummaryRequested() { + Query query = new Query("RETURN 'Hi!"); PullAllResponseHandler handler = newHandler(query); CompletableFuture summaryFuture = handler.consumeAsync().toCompletableFuture(); - assertFalse( summaryFuture.isDone() ); + assertFalse(summaryFuture.isDone()); - handler.onSuccess( singletonMap( "type", value( "r" ) ) ); + handler.onSuccess(singletonMap("type", value("r"))); - assertTrue( summaryFuture.isDone() ); - ResultSummary summary = await( summaryFuture ); + assertTrue(summaryFuture.isDone()); + ResultSummary summary = await(summaryFuture); - assertEquals(query, summary.query() ); - assertEquals( QueryType.READ_ONLY, summary.queryType() ); + assertEquals(query, summary.query()); + assertEquals(QueryType.READ_ONLY, summary.queryType()); } @Test - void shouldReturnFailureWhenSummaryRequestedWhenAlreadyFailed() - { + void shouldReturnFailureWhenSummaryRequestedWhenAlreadyFailed() { PullAllResponseHandler handler = newHandler(); - RuntimeException failure = new RuntimeException( "Computer is burning" ); - handler.onFailure( failure ); + RuntimeException failure = new RuntimeException("Computer is burning"); + handler.onFailure(failure); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( handler.consumeAsync() ) ); - assertEquals( failure, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(handler.consumeAsync())); + assertEquals(failure, e); } @Test - void shouldReturnFailureWhenFailedAfterSummaryRequested() - { + void shouldReturnFailureWhenFailedAfterSummaryRequested() { PullAllResponseHandler handler = newHandler(); CompletableFuture summaryFuture = handler.consumeAsync().toCompletableFuture(); - assertFalse( summaryFuture.isDone() ); + assertFalse(summaryFuture.isDone()); - IOException failure = new IOException( "FAILED to write" ); - handler.onFailure( failure ); + IOException failure = new IOException("FAILED to write"); + handler.onFailure(failure); - assertTrue( summaryFuture.isDone() ); - Exception e = assertThrows( Exception.class, () -> await( summaryFuture ) ); - assertEquals( failure, e ); + assertTrue(summaryFuture.isDone()); + Exception e = assertThrows(Exception.class, () -> await(summaryFuture)); + assertEquals(failure, e); } @Test - void shouldFailSummaryWhenRequestedMultipleTimes() - { + void shouldFailSummaryWhenRequestedMultipleTimes() { PullAllResponseHandler handler = newHandler(); CompletableFuture summaryFuture1 = handler.consumeAsync().toCompletableFuture(); CompletableFuture summaryFuture2 = handler.consumeAsync().toCompletableFuture(); - assertFalse( summaryFuture1.isDone() ); - assertFalse( summaryFuture2.isDone() ); + assertFalse(summaryFuture1.isDone()); + assertFalse(summaryFuture2.isDone()); ClosedChannelException failure = new ClosedChannelException(); - handler.onFailure( failure ); + handler.onFailure(failure); - assertTrue( summaryFuture1.isDone() ); - assertTrue( summaryFuture2.isDone() ); + assertTrue(summaryFuture1.isDone()); + assertTrue(summaryFuture2.isDone()); - Exception e1 = assertThrows( Exception.class, () -> await( summaryFuture2 ) ); - assertEquals( failure, e1 ); + Exception e1 = assertThrows(Exception.class, () -> await(summaryFuture2)); + assertEquals(failure, e1); - Exception e2 = assertThrows( Exception.class, () -> await( summaryFuture1 ) ); - assertEquals( failure, e2 ); + Exception e2 = assertThrows(Exception.class, () -> await(summaryFuture1)); + assertEquals(failure, e2); } @Test - void shouldPropagateFailureOnlyOnceFromSummary() - { - Query query = new Query( "CREATE INDEX ON :Person(name)" ); + void shouldPropagateFailureOnlyOnceFromSummary() { + Query query = new Query("CREATE INDEX ON :Person(name)"); PullAllResponseHandler handler = newHandler(query); - IllegalStateException failure = new IllegalStateException( "Some state is illegal :(" ); - handler.onFailure( failure ); + IllegalStateException failure = new IllegalStateException("Some state is illegal :("); + handler.onFailure(failure); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( handler.consumeAsync() ) ); - assertEquals( failure, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(handler.consumeAsync())); + assertEquals(failure, e); - ResultSummary summary = await( handler.consumeAsync() ); - assertNotNull( summary ); - assertEquals(query, summary.query() ); + ResultSummary summary = await(handler.consumeAsync()); + assertNotNull(summary); + assertEquals(query, summary.query()); } @Test - void shouldPeekSingleAvailableRecord() - { - List keys = asList( "key1", "key2" ); - PullAllResponseHandler handler = newHandler( keys ); - handler.onRecord( values( "a", "b" ) ); + void shouldPeekSingleAvailableRecord() { + List keys = asList("key1", "key2"); + PullAllResponseHandler handler = newHandler(keys); + handler.onRecord(values("a", "b")); - Record record = await( handler.peekAsync() ); + Record record = await(handler.peekAsync()); - assertEquals( keys, record.keys() ); - assertEquals( "a", record.get( "key1" ).asString() ); - assertEquals( "b", record.get( "key2" ).asString() ); + assertEquals(keys, record.keys()); + assertEquals("a", record.get("key1").asString()); + assertEquals("b", record.get("key2").asString()); } @Test - void shouldPeekFirstRecordWhenMultipleAvailable() - { - List keys = asList( "key1", "key2", "key3" ); - PullAllResponseHandler handler = newHandler( keys ); + void shouldPeekFirstRecordWhenMultipleAvailable() { + List keys = asList("key1", "key2", "key3"); + PullAllResponseHandler handler = newHandler(keys); - handler.onRecord( values( "a1", "b1", "c1" ) ); - handler.onRecord( values( "a2", "b2", "c2" ) ); - handler.onRecord( values( "a3", "b3", "c3" ) ); + handler.onRecord(values("a1", "b1", "c1")); + handler.onRecord(values("a2", "b2", "c2")); + handler.onRecord(values("a3", "b3", "c3")); - Record record = await( handler.peekAsync() ); + Record record = await(handler.peekAsync()); - assertEquals( keys, record.keys() ); - assertEquals( "a1", record.get( "key1" ).asString() ); - assertEquals( "b1", record.get( "key2" ).asString() ); - assertEquals( "c1", record.get( "key3" ).asString() ); + assertEquals(keys, record.keys()); + assertEquals("a1", record.get("key1").asString()); + assertEquals("b1", record.get("key2").asString()); + assertEquals("c1", record.get("key3").asString()); } @Test - void shouldPeekRecordThatBecomesAvailableLater() - { - List keys = asList( "key1", "key2" ); - PullAllResponseHandler handler = newHandler( keys ); + void shouldPeekRecordThatBecomesAvailableLater() { + List keys = asList("key1", "key2"); + PullAllResponseHandler handler = newHandler(keys); CompletableFuture recordFuture = handler.peekAsync().toCompletableFuture(); - assertFalse( recordFuture.isDone() ); + assertFalse(recordFuture.isDone()); - handler.onRecord( values( 24, 42 ) ); - assertTrue( recordFuture.isDone() ); + handler.onRecord(values(24, 42)); + assertTrue(recordFuture.isDone()); - Record record = await( recordFuture ); - assertEquals( keys, record.keys() ); - assertEquals( 24, record.get( "key1" ).asInt() ); - assertEquals( 42, record.get( "key2" ).asInt() ); + Record record = await(recordFuture); + assertEquals(keys, record.keys()); + assertEquals(24, record.get("key1").asInt()); + assertEquals(42, record.get("key2").asInt()); } @Test - void shouldPeekAvailableNothingAfterSuccess() - { - List keys = asList( "key1", "key2", "key3" ); - PullAllResponseHandler handler = newHandler( keys ); + void shouldPeekAvailableNothingAfterSuccess() { + List keys = asList("key1", "key2", "key3"); + PullAllResponseHandler handler = newHandler(keys); - handler.onRecord( values( 1, 2, 3 ) ); - handler.onSuccess( emptyMap() ); + handler.onRecord(values(1, 2, 3)); + handler.onSuccess(emptyMap()); - Record record = await( handler.peekAsync() ); - assertEquals( keys, record.keys() ); - assertEquals( 1, record.get( "key1" ).asInt() ); - assertEquals( 2, record.get( "key2" ).asInt() ); - assertEquals( 3, record.get( "key3" ).asInt() ); + Record record = await(handler.peekAsync()); + assertEquals(keys, record.keys()); + assertEquals(1, record.get("key1").asInt()); + assertEquals(2, record.get("key2").asInt()); + assertEquals(3, record.get("key3").asInt()); } @Test - void shouldPeekNothingAfterSuccess() - { + void shouldPeekNothingAfterSuccess() { PullAllResponseHandler handler = newHandler(); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - assertNull( await( handler.peekAsync() ) ); + assertNull(await(handler.peekAsync())); } @Test - void shouldPeekWhenRequestedMultipleTimes() - { - List keys = asList( "key1", "key2" ); - PullAllResponseHandler handler = newHandler( keys ); + void shouldPeekWhenRequestedMultipleTimes() { + List keys = asList("key1", "key2"); + PullAllResponseHandler handler = newHandler(keys); CompletableFuture recordFuture1 = handler.peekAsync().toCompletableFuture(); CompletableFuture recordFuture2 = handler.peekAsync().toCompletableFuture(); CompletableFuture recordFuture3 = handler.peekAsync().toCompletableFuture(); - assertFalse( recordFuture1.isDone() ); - assertFalse( recordFuture2.isDone() ); - assertFalse( recordFuture3.isDone() ); + assertFalse(recordFuture1.isDone()); + assertFalse(recordFuture2.isDone()); + assertFalse(recordFuture3.isDone()); - handler.onRecord( values( 2, 1 ) ); + handler.onRecord(values(2, 1)); - assertTrue( recordFuture1.isDone() ); - assertTrue( recordFuture2.isDone() ); - assertTrue( recordFuture3.isDone() ); + assertTrue(recordFuture1.isDone()); + assertTrue(recordFuture2.isDone()); + assertTrue(recordFuture3.isDone()); - Record record1 = await( recordFuture1 ); - Record record2 = await( recordFuture2 ); - Record record3 = await( recordFuture3 ); + Record record1 = await(recordFuture1); + Record record2 = await(recordFuture2); + Record record3 = await(recordFuture3); - assertEquals( keys, record1.keys() ); - assertEquals( keys, record2.keys() ); - assertEquals( keys, record3.keys() ); + assertEquals(keys, record1.keys()); + assertEquals(keys, record2.keys()); + assertEquals(keys, record3.keys()); - assertEquals( 2, record1.get( "key1" ).asInt() ); - assertEquals( 1, record1.get( "key2" ).asInt() ); + assertEquals(2, record1.get("key1").asInt()); + assertEquals(1, record1.get("key2").asInt()); - assertEquals( 2, record2.get( "key1" ).asInt() ); - assertEquals( 1, record2.get( "key2" ).asInt() ); + assertEquals(2, record2.get("key1").asInt()); + assertEquals(1, record2.get("key2").asInt()); - assertEquals( 2, record3.get( "key1" ).asInt() ); - assertEquals( 1, record3.get( "key2" ).asInt() ); + assertEquals(2, record3.get("key1").asInt()); + assertEquals(1, record3.get("key2").asInt()); } @Test - void shouldPropagateNotConsumedFailureInPeek() - { + void shouldPropagateNotConsumedFailureInPeek() { PullAllResponseHandler handler = newHandler(); - RuntimeException failure = new RuntimeException( "Something is wrong" ); - handler.onFailure( failure ); + RuntimeException failure = new RuntimeException("Something is wrong"); + handler.onFailure(failure); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( handler.peekAsync() ) ); - assertEquals( failure, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(handler.peekAsync())); + assertEquals(failure, e); } @Test - void shouldPropagateFailureInPeekWhenItBecomesAvailable() - { + void shouldPropagateFailureInPeekWhenItBecomesAvailable() { PullAllResponseHandler handler = newHandler(); CompletableFuture recordFuture = handler.peekAsync().toCompletableFuture(); - assertFalse( recordFuture.isDone() ); + assertFalse(recordFuture.isDone()); - RuntimeException failure = new RuntimeException( "Error" ); - handler.onFailure( failure ); + RuntimeException failure = new RuntimeException("Error"); + handler.onFailure(failure); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( recordFuture ) ); - assertEquals( failure, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(recordFuture)); + assertEquals(failure, e); } @Test - void shouldPropagateFailureInPeekOnlyOnce() - { + void shouldPropagateFailureInPeekOnlyOnce() { PullAllResponseHandler handler = newHandler(); - RuntimeException failure = new RuntimeException( "Something is wrong" ); - handler.onFailure( failure ); + RuntimeException failure = new RuntimeException("Something is wrong"); + handler.onFailure(failure); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( handler.peekAsync() ) ); - assertEquals( failure, e ); - assertNull( await( handler.peekAsync() ) ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(handler.peekAsync())); + assertEquals(failure, e); + assertNull(await(handler.peekAsync())); } @Test - void shouldReturnSingleAvailableRecordInNextAsync() - { - List keys = asList( "key1", "key2" ); - PullAllResponseHandler handler = newHandler( keys ); - handler.onRecord( values( "1", "2" ) ); + void shouldReturnSingleAvailableRecordInNextAsync() { + List keys = asList("key1", "key2"); + PullAllResponseHandler handler = newHandler(keys); + handler.onRecord(values("1", "2")); - Record record = await( handler.nextAsync() ); + Record record = await(handler.nextAsync()); - assertNotNull( record ); - assertEquals( keys, record.keys() ); - assertEquals( "1", record.get( "key1" ).asString() ); - assertEquals( "2", record.get( "key2" ).asString() ); + assertNotNull(record); + assertEquals(keys, record.keys()); + assertEquals("1", record.get("key1").asString()); + assertEquals("2", record.get("key2").asString()); } @Test - void shouldReturnNoRecordsWhenNoneAvailableInNextAsync() - { - PullAllResponseHandler handler = newHandler( asList( "key1", "key2" ) ); - handler.onSuccess( emptyMap() ); + void shouldReturnNoRecordsWhenNoneAvailableInNextAsync() { + PullAllResponseHandler handler = newHandler(asList("key1", "key2")); + handler.onSuccess(emptyMap()); - assertNull( await( handler.nextAsync() ) ); + assertNull(await(handler.nextAsync())); } @Test - void shouldReturnNoRecordsWhenSuccessComesAfterNextAsync() - { - PullAllResponseHandler handler = newHandler( asList( "key1", "key2" ) ); + void shouldReturnNoRecordsWhenSuccessComesAfterNextAsync() { + PullAllResponseHandler handler = newHandler(asList("key1", "key2")); CompletableFuture recordFuture = handler.nextAsync().toCompletableFuture(); - assertFalse( recordFuture.isDone() ); + assertFalse(recordFuture.isDone()); - handler.onSuccess( emptyMap() ); - assertTrue( recordFuture.isDone() ); + handler.onSuccess(emptyMap()); + assertTrue(recordFuture.isDone()); - assertNull( await( recordFuture ) ); + assertNull(await(recordFuture)); } @Test - void shouldPullAllAvailableRecordsWithNextAsync() - { - List keys = asList( "key1", "key2", "key3" ); - PullAllResponseHandler handler = newHandler( keys ); + void shouldPullAllAvailableRecordsWithNextAsync() { + List keys = asList("key1", "key2", "key3"); + PullAllResponseHandler handler = newHandler(keys); - handler.onRecord( values( 1, 2, 3 ) ); - handler.onRecord( values( 11, 22, 33 ) ); - handler.onRecord( values( 111, 222, 333 ) ); - handler.onRecord( values( 1111, 2222, 3333 ) ); - handler.onSuccess( emptyMap() ); + handler.onRecord(values(1, 2, 3)); + handler.onRecord(values(11, 22, 33)); + handler.onRecord(values(111, 222, 333)); + handler.onRecord(values(1111, 2222, 3333)); + handler.onSuccess(emptyMap()); - Record record1 = await( handler.nextAsync() ); - assertNotNull( record1 ); - assertEquals( keys, record1.keys() ); - assertEquals( 1, record1.get( "key1" ).asInt() ); - assertEquals( 2, record1.get( "key2" ).asInt() ); - assertEquals( 3, record1.get( "key3" ).asInt() ); + Record record1 = await(handler.nextAsync()); + assertNotNull(record1); + assertEquals(keys, record1.keys()); + assertEquals(1, record1.get("key1").asInt()); + assertEquals(2, record1.get("key2").asInt()); + assertEquals(3, record1.get("key3").asInt()); - Record record2 = await( handler.nextAsync() ); - assertNotNull( record2 ); - assertEquals( keys, record2.keys() ); - assertEquals( 11, record2.get( "key1" ).asInt() ); - assertEquals( 22, record2.get( "key2" ).asInt() ); - assertEquals( 33, record2.get( "key3" ).asInt() ); + Record record2 = await(handler.nextAsync()); + assertNotNull(record2); + assertEquals(keys, record2.keys()); + assertEquals(11, record2.get("key1").asInt()); + assertEquals(22, record2.get("key2").asInt()); + assertEquals(33, record2.get("key3").asInt()); - Record record3 = await( handler.nextAsync() ); - assertNotNull( record3 ); - assertEquals( keys, record3.keys() ); - assertEquals( 111, record3.get( "key1" ).asInt() ); - assertEquals( 222, record3.get( "key2" ).asInt() ); - assertEquals( 333, record3.get( "key3" ).asInt() ); + Record record3 = await(handler.nextAsync()); + assertNotNull(record3); + assertEquals(keys, record3.keys()); + assertEquals(111, record3.get("key1").asInt()); + assertEquals(222, record3.get("key2").asInt()); + assertEquals(333, record3.get("key3").asInt()); - Record record4 = await( handler.nextAsync() ); - assertNotNull( record4 ); - assertEquals( keys, record4.keys() ); - assertEquals( 1111, record4.get( "key1" ).asInt() ); - assertEquals( 2222, record4.get( "key2" ).asInt() ); - assertEquals( 3333, record4.get( "key3" ).asInt() ); + Record record4 = await(handler.nextAsync()); + assertNotNull(record4); + assertEquals(keys, record4.keys()); + assertEquals(1111, record4.get("key1").asInt()); + assertEquals(2222, record4.get("key2").asInt()); + assertEquals(3333, record4.get("key3").asInt()); - assertNull( await( handler.nextAsync() ) ); - assertNull( await( handler.nextAsync() ) ); + assertNull(await(handler.nextAsync())); + assertNull(await(handler.nextAsync())); } @Test - void shouldReturnRecordInNextAsyncWhenItBecomesAvailableLater() - { - List keys = asList( "key1", "key2" ); - PullAllResponseHandler handler = newHandler( keys ); + void shouldReturnRecordInNextAsyncWhenItBecomesAvailableLater() { + List keys = asList("key1", "key2"); + PullAllResponseHandler handler = newHandler(keys); CompletableFuture recordFuture = handler.nextAsync().toCompletableFuture(); - assertFalse( recordFuture.isDone() ); + assertFalse(recordFuture.isDone()); - handler.onRecord( values( 24, 42 ) ); - assertTrue( recordFuture.isDone() ); + handler.onRecord(values(24, 42)); + assertTrue(recordFuture.isDone()); - Record record = await( recordFuture ); - assertNotNull( record ); - assertEquals( keys, record.keys() ); - assertEquals( 24, record.get( "key1" ).asInt() ); - assertEquals( 42, record.get( "key2" ).asInt() ); + Record record = await(recordFuture); + assertNotNull(record); + assertEquals(keys, record.keys()); + assertEquals(24, record.get("key1").asInt()); + assertEquals(42, record.get("key2").asInt()); } @Test - void shouldReturnSameRecordOnceWhenRequestedMultipleTimesInNextAsync() - { - List keys = asList( "key1", "key2" ); - PullAllResponseHandler handler = newHandler( keys ); + void shouldReturnSameRecordOnceWhenRequestedMultipleTimesInNextAsync() { + List keys = asList("key1", "key2"); + PullAllResponseHandler handler = newHandler(keys); CompletableFuture recordFuture1 = handler.nextAsync().toCompletableFuture(); CompletableFuture recordFuture2 = handler.nextAsync().toCompletableFuture(); - assertFalse( recordFuture1.isDone() ); - assertFalse( recordFuture2.isDone() ); + assertFalse(recordFuture1.isDone()); + assertFalse(recordFuture2.isDone()); - handler.onRecord( values( "A", "B" ) ); - assertTrue( recordFuture1.isDone() ); - assertTrue( recordFuture2.isDone() ); + handler.onRecord(values("A", "B")); + assertTrue(recordFuture1.isDone()); + assertTrue(recordFuture2.isDone()); - Record record1 = await( recordFuture1 ); - Record record2 = await( recordFuture2 ); + Record record1 = await(recordFuture1); + Record record2 = await(recordFuture2); // record should be returned only once because #nextAsync() polls it - assertTrue( record1 != null || record2 != null ); + assertTrue(record1 != null || record2 != null); Record record = record1 != null ? record1 : record2; - assertNotNull( record ); - assertEquals( keys, record.keys() ); - assertEquals( "A", record.get( "key1" ).asString() ); - assertEquals( "B", record.get( "key2" ).asString() ); + assertNotNull(record); + assertEquals(keys, record.keys()); + assertEquals("A", record.get("key1").asString()); + assertEquals("B", record.get("key2").asString()); } @Test - void shouldPropagateExistingFailureInNextAsync() - { + void shouldPropagateExistingFailureInNextAsync() { PullAllResponseHandler handler = newHandler(); - RuntimeException error = new RuntimeException( "FAILED to read" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("FAILED to read"); + handler.onFailure(error); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( handler.nextAsync() ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(handler.nextAsync())); + assertEquals(error, e); } @Test - void shouldPropagateFailureInNextAsyncWhenFailureMessagesArrivesLater() - { + void shouldPropagateFailureInNextAsyncWhenFailureMessagesArrivesLater() { PullAllResponseHandler handler = newHandler(); CompletableFuture recordFuture = handler.nextAsync().toCompletableFuture(); - assertFalse( recordFuture.isDone() ); + assertFalse(recordFuture.isDone()); - RuntimeException error = new RuntimeException( "Network failed" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("Network failed"); + handler.onFailure(error); - assertTrue( recordFuture.isDone() ); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( recordFuture ) ); - assertEquals( error, e ); + assertTrue(recordFuture.isDone()); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(recordFuture)); + assertEquals(error, e); } @Test - void shouldPropagateFailureFromListAsync() - { + void shouldPropagateFailureFromListAsync() { PullAllResponseHandler handler = newHandler(); - RuntimeException error = new RuntimeException( "Hi!" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("Hi!"); + handler.onFailure(error); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( handler.listAsync( Function.identity() ) ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(handler.listAsync(Function.identity()))); + assertEquals(error, e); } @Test - void shouldPropagateFailureAfterRecordFromListAsync() - { - PullAllResponseHandler handler = newHandler( asList( "key1", "key2" ) ); + void shouldPropagateFailureAfterRecordFromListAsync() { + PullAllResponseHandler handler = newHandler(asList("key1", "key2")); - handler.onRecord( values( "a", "b" ) ); + handler.onRecord(values("a", "b")); - RuntimeException error = new RuntimeException( "Hi!" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("Hi!"); + handler.onFailure(error); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( handler.listAsync( Function.identity() ) ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(handler.listAsync(Function.identity()))); + assertEquals(error, e); } @Test - void shouldFailListAsyncWhenTransformationFunctionThrows() - { - PullAllResponseHandler handler = newHandler( asList( "key1", "key2" ) ); - handler.onRecord( values( 1, 2 ) ); - handler.onRecord( values( 3, 4 ) ); - handler.onSuccess( emptyMap() ); + void shouldFailListAsyncWhenTransformationFunctionThrows() { + PullAllResponseHandler handler = newHandler(asList("key1", "key2")); + handler.onRecord(values(1, 2)); + handler.onRecord(values(3, 4)); + handler.onSuccess(emptyMap()); - RuntimeException error = new RuntimeException( "Hi!" ); + RuntimeException error = new RuntimeException("Hi!"); - CompletionStage> stage = handler.listAsync( record -> - { - if ( record.get( 1 ).asInt() == 4 ) - { + CompletionStage> stage = handler.listAsync(record -> { + if (record.get(1).asInt() == 4) { throw error; } return 42; - } ); + }); - RuntimeException e = assertThrows( RuntimeException.class, () -> await( stage ) ); - assertEquals( error, e ); + RuntimeException e = assertThrows(RuntimeException.class, () -> await(stage)); + assertEquals(error, e); } @Test - void shouldReturnEmptyListInListAsyncAfterSuccess() - { + void shouldReturnEmptyListInListAsyncAfterSuccess() { PullAllResponseHandler handler = newHandler(); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - assertEquals( emptyList(), await( handler.listAsync( Function.identity() ) ) ); + assertEquals(emptyList(), await(handler.listAsync(Function.identity()))); } @Test - void shouldReturnTransformedListInListAsync() - { - PullAllResponseHandler handler = newHandler( singletonList( "key1" ) ); + void shouldReturnTransformedListInListAsync() { + PullAllResponseHandler handler = newHandler(singletonList("key1")); - handler.onRecord( values( 1 ) ); - handler.onRecord( values( 2 ) ); - handler.onRecord( values( 3 ) ); - handler.onRecord( values( 4 ) ); - handler.onSuccess( emptyMap() ); + handler.onRecord(values(1)); + handler.onRecord(values(2)); + handler.onRecord(values(3)); + handler.onRecord(values(4)); + handler.onSuccess(emptyMap()); - List transformedList = await( handler.listAsync( record -> record.get( 0 ).asInt() * 2 ) ); + List transformedList = + await(handler.listAsync(record -> record.get(0).asInt() * 2)); - assertEquals( asList( 2, 4, 6, 8 ), transformedList ); + assertEquals(asList(2, 4, 6, 8), transformedList); } @Test - void shouldReturnNotTransformedListInListAsync() - { - List keys = asList( "key1", "key2" ); - PullAllResponseHandler handler = newHandler( keys ); + void shouldReturnNotTransformedListInListAsync() { + List keys = asList("key1", "key2"); + PullAllResponseHandler handler = newHandler(keys); - Value[] fields1 = values( "a", "b" ); - Value[] fields2 = values( "c", "d" ); - Value[] fields3 = values( "e", "f" ); + Value[] fields1 = values("a", "b"); + Value[] fields2 = values("c", "d"); + Value[] fields3 = values("e", "f"); - handler.onRecord( fields1 ); - handler.onRecord( fields2 ); - handler.onRecord( fields3 ); - handler.onSuccess( emptyMap() ); + handler.onRecord(fields1); + handler.onRecord(fields2); + handler.onRecord(fields3); + handler.onSuccess(emptyMap()); - List list = await( handler.listAsync( Function.identity() ) ); + List list = await(handler.listAsync(Function.identity())); List expectedRecords = asList( - new InternalRecord( keys, fields1 ), - new InternalRecord( keys, fields2 ), - new InternalRecord( keys, fields3 ) ); + new InternalRecord(keys, fields1), + new InternalRecord(keys, fields2), + new InternalRecord(keys, fields3)); - assertEquals( expectedRecords, list ); + assertEquals(expectedRecords, list); } - protected T newHandler() - { - return newHandler( new Query( "RETURN 1" ) ); + + protected T newHandler() { + return newHandler(new Query("RETURN 1")); } - protected T newHandler( Query query) - { - return newHandler(query, emptyList() ); + protected T newHandler(Query query) { + return newHandler(query, emptyList()); } - protected T newHandler( List queryKeys ) - { - return newHandler( new Query( "RETURN 1" ), queryKeys, connectionMock() ); + protected T newHandler(List queryKeys) { + return newHandler(new Query("RETURN 1"), queryKeys, connectionMock()); } - protected T newHandler(Query query, List queryKeys ) - { - return newHandler(query, queryKeys, connectionMock() ); + protected T newHandler(Query query, List queryKeys) { + return newHandler(query, queryKeys, connectionMock()); } - protected T newHandler( List queryKeys, Connection connection ) - { - return newHandler( new Query( "RETURN 1" ), queryKeys, connection ); + protected T newHandler(List queryKeys, Connection connection) { + return newHandler(new Query("RETURN 1"), queryKeys, connection); } - protected abstract T newHandler(Query query, List queryKeys, Connection connection ); + protected abstract T newHandler(Query query, List queryKeys, Connection connection); - protected Connection connectionMock() - { - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( BoltServerAddress.LOCAL_DEFAULT ); - when( connection.serverVersion() ).thenReturn( anyServerVersion() ); - when( connection.protocol() ).thenReturn( BoltProtocolV43.INSTANCE ); - when( connection.serverAgent() ).thenReturn( "Neo4j/4.2.5" ); + protected Connection connectionMock() { + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(BoltServerAddress.LOCAL_DEFAULT); + when(connection.serverVersion()).thenReturn(anyServerVersion()); + when(connection.protocol()).thenReturn(BoltProtocolV43.INSTANCE); + when(connection.serverAgent()).thenReturn("Neo4j/4.2.5"); return connection; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/ResetResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/ResetResponseHandlerTest.java index 1af173a9a9..6e27331364 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/ResetResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/ResetResponseHandlerTest.java @@ -18,67 +18,58 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.CompletableFuture; - -import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; - import static java.util.Collections.emptyMap; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.neo4j.driver.Values.values; -class ResetResponseHandlerTest -{ +import java.util.concurrent.CompletableFuture; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; + +class ResetResponseHandlerTest { @Test - void shouldCompleteFutureOnSuccess() throws Exception - { + void shouldCompleteFutureOnSuccess() throws Exception { CompletableFuture future = new CompletableFuture<>(); - ResetResponseHandler handler = newHandler( future ); + ResetResponseHandler handler = newHandler(future); - assertFalse( future.isDone() ); + assertFalse(future.isDone()); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - assertTrue( future.isDone() ); - assertNull( future.get() ); + assertTrue(future.isDone()); + assertNull(future.get()); } @Test - void shouldCompleteFutureOnFailure() throws Exception - { + void shouldCompleteFutureOnFailure() throws Exception { CompletableFuture future = new CompletableFuture<>(); - ResetResponseHandler handler = newHandler( future ); + ResetResponseHandler handler = newHandler(future); - assertFalse( future.isDone() ); + assertFalse(future.isDone()); - handler.onFailure( new RuntimeException() ); + handler.onFailure(new RuntimeException()); - assertTrue( future.isDone() ); - assertNull( future.get() ); + assertTrue(future.isDone()); + assertNull(future.get()); } @Test - void shouldThrowWhenOnRecord() - { - ResetResponseHandler handler = newHandler( new CompletableFuture<>() ); + void shouldThrowWhenOnRecord() { + ResetResponseHandler handler = newHandler(new CompletableFuture<>()); - assertThrows( UnsupportedOperationException.class, () -> handler.onRecord( values( 1, 2, 3 ) ) ); + assertThrows(UnsupportedOperationException.class, () -> handler.onRecord(values(1, 2, 3))); } - private static ResetResponseHandler newHandler( CompletableFuture future ) - { - return new ResetResponseHandler( mock( InboundMessageDispatcher.class ), future ); + private static ResetResponseHandler newHandler(CompletableFuture future) { + return new ResetResponseHandler(mock(InboundMessageDispatcher.class), future); } - private static ResetResponseHandler newHandler( InboundMessageDispatcher messageDispatcher, - CompletableFuture future ) - { - return new ResetResponseHandler( messageDispatcher, future ); + private static ResetResponseHandler newHandler( + InboundMessageDispatcher messageDispatcher, CompletableFuture future) { + return new ResetResponseHandler(messageDispatcher, future); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/RouteMessageResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/RouteMessageResponseHandlerTest.java index b2f577b488..deadf06c92 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/RouteMessageResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/RouteMessageResponseHandlerTest.java @@ -18,97 +18,86 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Value; import org.neo4j.driver.Values; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class RouteMessageResponseHandlerTest -{ +class RouteMessageResponseHandlerTest { @Test - void onSuccessShouldSuccessFullyCompleteFutureWithRoutingTable() throws Exception - { - CompletableFuture> completableFuture = new CompletableFuture<>(); - RouteMessageResponseHandler responseHandler = new RouteMessageResponseHandler( completableFuture ); - Map routingTable = getRoutingTable(); - Map metadata = getMetadataWithRoutingTable( routingTable ); + void onSuccessShouldSuccessFullyCompleteFutureWithRoutingTable() throws Exception { + CompletableFuture> completableFuture = new CompletableFuture<>(); + RouteMessageResponseHandler responseHandler = new RouteMessageResponseHandler(completableFuture); + Map routingTable = getRoutingTable(); + Map metadata = getMetadataWithRoutingTable(routingTable); - responseHandler.onSuccess( metadata ); + responseHandler.onSuccess(metadata); - assertEquals( routingTable, completableFuture.getNow( null ) ); + assertEquals(routingTable, completableFuture.getNow(null)); } @Test - void onSuccessShouldExceptionallyCompleteFutureWhenMetadataDoesNotHaveRoutingTable() throws Exception - { - CompletableFuture> completableFuture = new CompletableFuture<>(); - RouteMessageResponseHandler responseHandler = new RouteMessageResponseHandler( completableFuture ); - Map metadata = new HashMap<>(); + void onSuccessShouldExceptionallyCompleteFutureWhenMetadataDoesNotHaveRoutingTable() throws Exception { + CompletableFuture> completableFuture = new CompletableFuture<>(); + RouteMessageResponseHandler responseHandler = new RouteMessageResponseHandler(completableFuture); + Map metadata = new HashMap<>(); - responseHandler.onSuccess( metadata ); + responseHandler.onSuccess(metadata); - assertThrows( CompletionException.class, () -> completableFuture.getNow( null ) ); + assertThrows(CompletionException.class, () -> completableFuture.getNow(null)); } @Test - void onFailureShouldCompleteExceptionallyWithTheOriginalException() - { - CompletableFuture> completableFuture = new CompletableFuture<>(); - RouteMessageResponseHandler responseHandler = new RouteMessageResponseHandler( completableFuture ); - RuntimeException expectedException = new RuntimeException( "Test exception" ); - - responseHandler.onFailure( expectedException ); - - assertTrue( completableFuture.isCompletedExceptionally() ); - completableFuture.handle( ( value, ex ) -> - { - assertNull( value ); - assertEquals( expectedException, ex ); - return null; - } ); + void onFailureShouldCompleteExceptionallyWithTheOriginalException() { + CompletableFuture> completableFuture = new CompletableFuture<>(); + RouteMessageResponseHandler responseHandler = new RouteMessageResponseHandler(completableFuture); + RuntimeException expectedException = new RuntimeException("Test exception"); + + responseHandler.onFailure(expectedException); + + assertTrue(completableFuture.isCompletedExceptionally()); + completableFuture.handle((value, ex) -> { + assertNull(value); + assertEquals(expectedException, ex); + return null; + }); } @Test - void onRecordShouldThrowUnsupportedOperation() - { - CompletableFuture> completableFuture = new CompletableFuture<>(); - RouteMessageResponseHandler responseHandler = new RouteMessageResponseHandler( completableFuture ); - - responseHandler.onRecord( new Value[0] ); - - assertTrue( completableFuture.isCompletedExceptionally() ); - completableFuture.handle( ( value, ex ) -> - { - assertNull( value ); - assertEquals( UnsupportedOperationException.class, ex.getClass() ); - return null; - } ); + void onRecordShouldThrowUnsupportedOperation() { + CompletableFuture> completableFuture = new CompletableFuture<>(); + RouteMessageResponseHandler responseHandler = new RouteMessageResponseHandler(completableFuture); + + responseHandler.onRecord(new Value[0]); + + assertTrue(completableFuture.isCompletedExceptionally()); + completableFuture.handle((value, ex) -> { + assertNull(value); + assertEquals(UnsupportedOperationException.class, ex.getClass()); + return null; + }); } - private Map getMetadataWithRoutingTable( Map routingTable ) - { - Map metadata = new HashMap<>(); - metadata.put( "rt", Values.value( routingTable ) ); + private Map getMetadataWithRoutingTable(Map routingTable) { + Map metadata = new HashMap<>(); + metadata.put("rt", Values.value(routingTable)); return metadata; } - private Map getRoutingTable() - { - Map routingTable = new HashMap<>(); - routingTable.put( "ttl", Values.value( 300 ) ); - routingTable.put( "addresses", Values.value( new ArrayList<>() ) ); + private Map getRoutingTable() { + Map routingTable = new HashMap<>(); + routingTable.put("ttl", Values.value(300)); + routingTable.put("addresses", Values.value(new ArrayList<>())); return routingTable; } -} \ No newline at end of file +} diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/RoutingResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/RoutingResponseHandlerTest.java index 6926e8da4c..f4ceee5a15 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/RoutingResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/RoutingResponseHandlerTest.java @@ -18,11 +18,17 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; import java.util.concurrent.CompletionException; - +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.neo4j.driver.AccessMode; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.ServiceUnavailableException; @@ -31,163 +37,139 @@ import org.neo4j.driver.internal.RoutingErrorHandler; import org.neo4j.driver.internal.spi.ResponseHandler; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; - -class RoutingResponseHandlerTest -{ +class RoutingResponseHandlerTest { @Test - void shouldUnwrapCompletionException() - { - RuntimeException error = new RuntimeException( "Hi" ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); + void shouldUnwrapCompletionException() { + RuntimeException error = new RuntimeException("Hi"); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); - Throwable handledError = handle( new CompletionException( error ), errorHandler ); + Throwable handledError = handle(new CompletionException(error), errorHandler); - assertEquals( error, handledError ); - verifyNoInteractions( errorHandler ); + assertEquals(error, handledError); + verifyNoInteractions(errorHandler); } @Test - void shouldHandleServiceUnavailableException() - { - ServiceUnavailableException error = new ServiceUnavailableException( "Hi" ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); + void shouldHandleServiceUnavailableException() { + ServiceUnavailableException error = new ServiceUnavailableException("Hi"); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); - Throwable handledError = handle( error, errorHandler ); + Throwable handledError = handle(error, errorHandler); - assertThat( handledError, instanceOf( SessionExpiredException.class ) ); - verify( errorHandler ).onConnectionFailure( LOCAL_DEFAULT ); + assertThat(handledError, instanceOf(SessionExpiredException.class)); + verify(errorHandler).onConnectionFailure(LOCAL_DEFAULT); } @Test - void shouldHandleDatabaseUnavailableError() - { - TransientException error = new TransientException( "Neo.TransientError.General.DatabaseUnavailable", "Hi" ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); + void shouldHandleDatabaseUnavailableError() { + TransientException error = new TransientException("Neo.TransientError.General.DatabaseUnavailable", "Hi"); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); - Throwable handledError = handle( error, errorHandler ); + Throwable handledError = handle(error, errorHandler); - assertEquals( error, handledError ); - verify( errorHandler ).onConnectionFailure( LOCAL_DEFAULT ); + assertEquals(error, handledError); + verify(errorHandler).onConnectionFailure(LOCAL_DEFAULT); } @Test - void shouldHandleTransientException() - { - TransientException error = new TransientException( "Neo.TransientError.Transaction.DeadlockDetected", "Hi" ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); + void shouldHandleTransientException() { + TransientException error = new TransientException("Neo.TransientError.Transaction.DeadlockDetected", "Hi"); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); - Throwable handledError = handle( error, errorHandler ); + Throwable handledError = handle(error, errorHandler); - assertEquals( error, handledError ); - verifyNoInteractions( errorHandler ); + assertEquals(error, handledError); + verifyNoInteractions(errorHandler); } @Test - void shouldHandleNotALeaderErrorWithReadAccessMode() - { - testWriteFailureWithReadAccessMode( "Neo.ClientError.Cluster.NotALeader" ); + void shouldHandleNotALeaderErrorWithReadAccessMode() { + testWriteFailureWithReadAccessMode("Neo.ClientError.Cluster.NotALeader"); } @Test - void shouldHandleNotALeaderErrorWithWriteAccessMode() - { - testWriteFailureWithWriteAccessMode( "Neo.ClientError.Cluster.NotALeader" ); + void shouldHandleNotALeaderErrorWithWriteAccessMode() { + testWriteFailureWithWriteAccessMode("Neo.ClientError.Cluster.NotALeader"); } @Test - void shouldHandleForbiddenOnReadOnlyDatabaseErrorWithReadAccessMode() - { - testWriteFailureWithReadAccessMode( "Neo.ClientError.General.ForbiddenOnReadOnlyDatabase" ); + void shouldHandleForbiddenOnReadOnlyDatabaseErrorWithReadAccessMode() { + testWriteFailureWithReadAccessMode("Neo.ClientError.General.ForbiddenOnReadOnlyDatabase"); } @Test - void shouldHandleForbiddenOnReadOnlyDatabaseErrorWithWriteAccessMode() - { - testWriteFailureWithWriteAccessMode( "Neo.ClientError.General.ForbiddenOnReadOnlyDatabase" ); + void shouldHandleForbiddenOnReadOnlyDatabaseErrorWithWriteAccessMode() { + testWriteFailureWithWriteAccessMode("Neo.ClientError.General.ForbiddenOnReadOnlyDatabase"); } @Test - void shouldHandleClientException() - { - ClientException error = new ClientException( "Neo.ClientError.Request.Invalid", "Hi" ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); + void shouldHandleClientException() { + ClientException error = new ClientException("Neo.ClientError.Request.Invalid", "Hi"); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); - Throwable handledError = handle( error, errorHandler, AccessMode.READ ); + Throwable handledError = handle(error, errorHandler, AccessMode.READ); - assertEquals( error, handledError ); - verifyNoInteractions( errorHandler ); + assertEquals(error, handledError); + verifyNoInteractions(errorHandler); } @Test - public void shouldDelegateCanManageAutoRead() - { - ResponseHandler responseHandler = mock( ResponseHandler.class ); + public void shouldDelegateCanManageAutoRead() { + ResponseHandler responseHandler = mock(ResponseHandler.class); RoutingResponseHandler routingResponseHandler = - new RoutingResponseHandler( responseHandler, LOCAL_DEFAULT, AccessMode.READ, null ); + new RoutingResponseHandler(responseHandler, LOCAL_DEFAULT, AccessMode.READ, null); routingResponseHandler.canManageAutoRead(); - verify( responseHandler ).canManageAutoRead(); + verify(responseHandler).canManageAutoRead(); } @Test - public void shouldDelegateDisableAutoReadManagement() - { - ResponseHandler responseHandler = mock( ResponseHandler.class ); + public void shouldDelegateDisableAutoReadManagement() { + ResponseHandler responseHandler = mock(ResponseHandler.class); RoutingResponseHandler routingResponseHandler = - new RoutingResponseHandler( responseHandler, LOCAL_DEFAULT, AccessMode.READ, null ); + new RoutingResponseHandler(responseHandler, LOCAL_DEFAULT, AccessMode.READ, null); routingResponseHandler.disableAutoReadManagement(); - verify( responseHandler ).disableAutoReadManagement(); + verify(responseHandler).disableAutoReadManagement(); } - private void testWriteFailureWithReadAccessMode( String code ) - { - ClientException error = new ClientException( code, "Hi" ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); + private void testWriteFailureWithReadAccessMode(String code) { + ClientException error = new ClientException(code, "Hi"); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); - Throwable handledError = handle( error, errorHandler, AccessMode.READ ); + Throwable handledError = handle(error, errorHandler, AccessMode.READ); - assertThat( handledError, instanceOf( ClientException.class ) ); - assertEquals( "Write queries cannot be performed in READ access mode.", handledError.getMessage() ); - verifyNoInteractions( errorHandler ); + assertThat(handledError, instanceOf(ClientException.class)); + assertEquals("Write queries cannot be performed in READ access mode.", handledError.getMessage()); + verifyNoInteractions(errorHandler); } - private void testWriteFailureWithWriteAccessMode( String code ) - { - ClientException error = new ClientException( code, "Hi" ); - RoutingErrorHandler errorHandler = mock( RoutingErrorHandler.class ); + private void testWriteFailureWithWriteAccessMode(String code) { + ClientException error = new ClientException(code, "Hi"); + RoutingErrorHandler errorHandler = mock(RoutingErrorHandler.class); - Throwable handledError = handle( error, errorHandler, AccessMode.WRITE ); + Throwable handledError = handle(error, errorHandler, AccessMode.WRITE); - assertThat( handledError, instanceOf( SessionExpiredException.class ) ); - assertEquals( "Server at " + LOCAL_DEFAULT + " no longer accepts writes", handledError.getMessage() ); - verify( errorHandler ).onWriteFailure( LOCAL_DEFAULT ); + assertThat(handledError, instanceOf(SessionExpiredException.class)); + assertEquals("Server at " + LOCAL_DEFAULT + " no longer accepts writes", handledError.getMessage()); + verify(errorHandler).onWriteFailure(LOCAL_DEFAULT); } - private static Throwable handle( Throwable error, RoutingErrorHandler errorHandler ) - { - return handle( error, errorHandler, AccessMode.READ ); + private static Throwable handle(Throwable error, RoutingErrorHandler errorHandler) { + return handle(error, errorHandler, AccessMode.READ); } - private static Throwable handle( Throwable error, RoutingErrorHandler errorHandler, AccessMode accessMode ) - { - ResponseHandler responseHandler = mock( ResponseHandler.class ); + private static Throwable handle(Throwable error, RoutingErrorHandler errorHandler, AccessMode accessMode) { + ResponseHandler responseHandler = mock(ResponseHandler.class); RoutingResponseHandler routingResponseHandler = - new RoutingResponseHandler( responseHandler, LOCAL_DEFAULT, accessMode, errorHandler ); + new RoutingResponseHandler(responseHandler, LOCAL_DEFAULT, accessMode, errorHandler); - routingResponseHandler.onFailure( error ); + routingResponseHandler.onFailure(error); - ArgumentCaptor handledErrorCaptor = ArgumentCaptor.forClass( Throwable.class ); - verify( responseHandler ).onFailure( handledErrorCaptor.capture() ); + ArgumentCaptor handledErrorCaptor = ArgumentCaptor.forClass(Throwable.class); + verify(responseHandler).onFailure(handledErrorCaptor.capture()); return handledErrorCaptor.getValue(); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/RunResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/RunResponseHandlerTest.java index d417cc9db8..9ee78ce6de 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/RunResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/RunResponseHandlerTest.java @@ -18,21 +18,6 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import org.neo4j.driver.exceptions.AuthorizationExpiredException; -import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; -import org.neo4j.driver.internal.async.UnmanagedTransaction; -import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.util.MetadataExtractor; - import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; @@ -53,186 +38,190 @@ import static org.neo4j.driver.Values.values; import static org.neo4j.driver.util.TestUtil.await; -class RunResponseHandlerTest -{ +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.AuthorizationExpiredException; +import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; +import org.neo4j.driver.internal.async.UnmanagedTransaction; +import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.util.MetadataExtractor; + +class RunResponseHandlerTest { @Test - void shouldNotifyRunFutureOnSuccess() throws Exception - { + void shouldNotifyRunFutureOnSuccess() throws Exception { CompletableFuture runFuture = new CompletableFuture<>(); - RunResponseHandler handler = newHandler( runFuture ); + RunResponseHandler handler = newHandler(runFuture); - assertFalse( runFuture.isDone() ); - handler.onSuccess( emptyMap() ); + assertFalse(runFuture.isDone()); + handler.onSuccess(emptyMap()); - assertTrue( runFuture.isDone() ); - assertNull( runFuture.get() ); + assertTrue(runFuture.isDone()); + assertNull(runFuture.get()); } @Test - void shouldNotifyRunFutureOnFailure() - { + void shouldNotifyRunFutureOnFailure() { CompletableFuture runFuture = new CompletableFuture<>(); - RunResponseHandler handler = newHandler( runFuture ); + RunResponseHandler handler = newHandler(runFuture); - assertFalse( runFuture.isDone() ); + assertFalse(runFuture.isDone()); RuntimeException exception = new RuntimeException(); - handler.onFailure( exception ); + handler.onFailure(exception); - assertTrue( runFuture.isCompletedExceptionally() ); - ExecutionException executionException = assertThrows( ExecutionException.class, runFuture::get ); - assertThat( executionException.getCause(), equalTo( exception ) ); + assertTrue(runFuture.isCompletedExceptionally()); + ExecutionException executionException = assertThrows(ExecutionException.class, runFuture::get); + assertThat(executionException.getCause(), equalTo(exception)); } @Test - void shouldThrowOnRecord() - { + void shouldThrowOnRecord() { RunResponseHandler handler = newHandler(); - assertThrows( UnsupportedOperationException.class, () -> handler.onRecord( values( "a", "b", "c" ) ) ); + assertThrows(UnsupportedOperationException.class, () -> handler.onRecord(values("a", "b", "c"))); } @Test - void shouldReturnNoKeysWhenFailed() - { + void shouldReturnNoKeysWhenFailed() { RunResponseHandler handler = newHandler(); - handler.onFailure( new RuntimeException() ); + handler.onFailure(new RuntimeException()); - assertEquals( emptyList(), handler.queryKeys().keys() ); - assertEquals( emptyMap(), handler.queryKeys().keyIndex() ); + assertEquals(emptyList(), handler.queryKeys().keys()); + assertEquals(emptyMap(), handler.queryKeys().keyIndex()); } @Test - void shouldReturnDefaultResultAvailableAfterWhenFailed() - { + void shouldReturnDefaultResultAvailableAfterWhenFailed() { RunResponseHandler handler = newHandler(); - handler.onFailure( new RuntimeException() ); + handler.onFailure(new RuntimeException()); - assertEquals( -1, handler.resultAvailableAfter() ); + assertEquals(-1, handler.resultAvailableAfter()); } @Test - void shouldReturnKeysWhenSucceeded() - { + void shouldReturnKeysWhenSucceeded() { RunResponseHandler handler = newHandler(); - List keys = asList( "key1", "key2", "key3" ); - Map keyIndex = new HashMap<>(); - keyIndex.put( "key1", 0 ); - keyIndex.put( "key2", 1 ); - keyIndex.put( "key3", 2 ); - handler.onSuccess( singletonMap( "fields", value( keys ) ) ); + List keys = asList("key1", "key2", "key3"); + Map keyIndex = new HashMap<>(); + keyIndex.put("key1", 0); + keyIndex.put("key2", 1); + keyIndex.put("key3", 2); + handler.onSuccess(singletonMap("fields", value(keys))); - assertEquals( keys, handler.queryKeys().keys() ); - assertEquals( keyIndex, handler.queryKeys().keyIndex() ); + assertEquals(keys, handler.queryKeys().keys()); + assertEquals(keyIndex, handler.queryKeys().keyIndex()); } @Test - void shouldReturnResultAvailableAfterWhenSucceededV3() - { - testResultAvailableAfterOnSuccess( "t_first", BoltProtocolV3.METADATA_EXTRACTOR ); + void shouldReturnResultAvailableAfterWhenSucceededV3() { + testResultAvailableAfterOnSuccess("t_first", BoltProtocolV3.METADATA_EXTRACTOR); } @Test - void shouldMarkTxAndKeepConnectionAndFailOnFailure() - { + void shouldMarkTxAndKeepConnectionAndFailOnFailure() { CompletableFuture runFuture = new CompletableFuture<>(); - Connection connection = mock( Connection.class ); - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - RunResponseHandler handler = new RunResponseHandler( runFuture, BoltProtocolV3.METADATA_EXTRACTOR, connection, tx ); + Connection connection = mock(Connection.class); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + RunResponseHandler handler = + new RunResponseHandler(runFuture, BoltProtocolV3.METADATA_EXTRACTOR, connection, tx); Throwable throwable = new RuntimeException(); - assertFalse( runFuture.isDone() ); - handler.onFailure( throwable ); + assertFalse(runFuture.isDone()); + handler.onFailure(throwable); - assertTrue( runFuture.isCompletedExceptionally() ); - Throwable actualException = assertThrows( Throwable.class, () -> await( runFuture ) ); - assertSame( throwable, actualException ); - verify( tx ).markTerminated( throwable ); - verify( connection, never() ).release(); - verify( connection, never() ).terminateAndRelease( any( String.class ) ); + assertTrue(runFuture.isCompletedExceptionally()); + Throwable actualException = assertThrows(Throwable.class, () -> await(runFuture)); + assertSame(throwable, actualException); + verify(tx).markTerminated(throwable); + verify(connection, never()).release(); + verify(connection, never()).terminateAndRelease(any(String.class)); } @Test - void shouldNotReleaseConnectionAndFailOnFailure() - { + void shouldNotReleaseConnectionAndFailOnFailure() { CompletableFuture runFuture = new CompletableFuture<>(); - Connection connection = mock( Connection.class ); - RunResponseHandler handler = new RunResponseHandler( runFuture, BoltProtocolV3.METADATA_EXTRACTOR, connection, null ); + Connection connection = mock(Connection.class); + RunResponseHandler handler = + new RunResponseHandler(runFuture, BoltProtocolV3.METADATA_EXTRACTOR, connection, null); Throwable throwable = new RuntimeException(); - assertFalse( runFuture.isDone() ); - handler.onFailure( throwable ); + assertFalse(runFuture.isDone()); + handler.onFailure(throwable); - assertTrue( runFuture.isCompletedExceptionally() ); - Throwable actualException = assertThrows( Throwable.class, () -> await( runFuture ) ); - assertSame( throwable, actualException ); - verify( connection, never() ).release(); - verify( connection, never() ).terminateAndRelease( any( String.class ) ); + assertTrue(runFuture.isCompletedExceptionally()); + Throwable actualException = assertThrows(Throwable.class, () -> await(runFuture)); + assertSame(throwable, actualException); + verify(connection, never()).release(); + verify(connection, never()).terminateAndRelease(any(String.class)); } @Test - void shouldReleaseConnectionImmediatelyAndFailOnAuthorizationExpiredExceptionFailure() - { + void shouldReleaseConnectionImmediatelyAndFailOnAuthorizationExpiredExceptionFailure() { CompletableFuture runFuture = new CompletableFuture<>(); - Connection connection = mock( Connection.class ); - RunResponseHandler handler = new RunResponseHandler( runFuture, BoltProtocolV3.METADATA_EXTRACTOR, connection, null ); - AuthorizationExpiredException authorizationExpiredException = new AuthorizationExpiredException( "code", "message" ); + Connection connection = mock(Connection.class); + RunResponseHandler handler = + new RunResponseHandler(runFuture, BoltProtocolV3.METADATA_EXTRACTOR, connection, null); + AuthorizationExpiredException authorizationExpiredException = + new AuthorizationExpiredException("code", "message"); - assertFalse( runFuture.isDone() ); - handler.onFailure( authorizationExpiredException ); + assertFalse(runFuture.isDone()); + handler.onFailure(authorizationExpiredException); - assertTrue( runFuture.isCompletedExceptionally() ); - AuthorizationExpiredException actualException = assertThrows( AuthorizationExpiredException.class, () -> await( runFuture ) ); - assertSame( authorizationExpiredException, actualException ); - verify( connection ).terminateAndRelease( AuthorizationExpiredException.DESCRIPTION ); - verify( connection, never() ).release(); + assertTrue(runFuture.isCompletedExceptionally()); + AuthorizationExpiredException actualException = + assertThrows(AuthorizationExpiredException.class, () -> await(runFuture)); + assertSame(authorizationExpiredException, actualException); + verify(connection).terminateAndRelease(AuthorizationExpiredException.DESCRIPTION); + verify(connection, never()).release(); } @Test - void shouldReleaseConnectionImmediatelyAndFailOnConnectionReadTimeoutExceptionFailure() - { + void shouldReleaseConnectionImmediatelyAndFailOnConnectionReadTimeoutExceptionFailure() { CompletableFuture runFuture = new CompletableFuture<>(); - Connection connection = mock( Connection.class ); - RunResponseHandler handler = new RunResponseHandler( runFuture, BoltProtocolV3.METADATA_EXTRACTOR, connection, null ); + Connection connection = mock(Connection.class); + RunResponseHandler handler = + new RunResponseHandler(runFuture, BoltProtocolV3.METADATA_EXTRACTOR, connection, null); - assertFalse( runFuture.isDone() ); - handler.onFailure( ConnectionReadTimeoutException.INSTANCE ); + assertFalse(runFuture.isDone()); + handler.onFailure(ConnectionReadTimeoutException.INSTANCE); - assertTrue( runFuture.isCompletedExceptionally() ); - ConnectionReadTimeoutException actualException = assertThrows( ConnectionReadTimeoutException.class, () -> await( runFuture ) ); - assertSame( ConnectionReadTimeoutException.INSTANCE, actualException ); - verify( connection ).terminateAndRelease( ConnectionReadTimeoutException.INSTANCE.getMessage() ); - verify( connection, never() ).release(); + assertTrue(runFuture.isCompletedExceptionally()); + ConnectionReadTimeoutException actualException = + assertThrows(ConnectionReadTimeoutException.class, () -> await(runFuture)); + assertSame(ConnectionReadTimeoutException.INSTANCE, actualException); + verify(connection).terminateAndRelease(ConnectionReadTimeoutException.INSTANCE.getMessage()); + verify(connection, never()).release(); } - private static void testResultAvailableAfterOnSuccess( String key, MetadataExtractor metadataExtractor ) - { - RunResponseHandler handler = newHandler( metadataExtractor ); + private static void testResultAvailableAfterOnSuccess(String key, MetadataExtractor metadataExtractor) { + RunResponseHandler handler = newHandler(metadataExtractor); - handler.onSuccess( singletonMap( key, value( 42 ) ) ); + handler.onSuccess(singletonMap(key, value(42))); - assertEquals( 42L, handler.resultAvailableAfter() ); + assertEquals(42L, handler.resultAvailableAfter()); } - private static RunResponseHandler newHandler() - { - return newHandler( BoltProtocolV3.METADATA_EXTRACTOR ); + private static RunResponseHandler newHandler() { + return newHandler(BoltProtocolV3.METADATA_EXTRACTOR); } - private static RunResponseHandler newHandler( CompletableFuture runFuture ) - { - return newHandler( runFuture, BoltProtocolV3.METADATA_EXTRACTOR ); + private static RunResponseHandler newHandler(CompletableFuture runFuture) { + return newHandler(runFuture, BoltProtocolV3.METADATA_EXTRACTOR); } - private static RunResponseHandler newHandler( MetadataExtractor metadataExtractor ) - { - return newHandler( new CompletableFuture<>(), metadataExtractor ); + private static RunResponseHandler newHandler(MetadataExtractor metadataExtractor) { + return newHandler(new CompletableFuture<>(), metadataExtractor); } - private static RunResponseHandler newHandler( CompletableFuture runFuture, MetadataExtractor metadataExtractor ) - { - return new RunResponseHandler( runFuture, metadataExtractor, mock( Connection.class ), null ); + private static RunResponseHandler newHandler( + CompletableFuture runFuture, MetadataExtractor metadataExtractor) { + return new RunResponseHandler(runFuture, metadataExtractor, mock(Connection.class), null); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/SessionPullResponseCompletionListenerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/SessionPullResponseCompletionListenerTest.java index 4b2cc67f4c..f21b40b10e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/SessionPullResponseCompletionListenerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/SessionPullResponseCompletionListenerTest.java @@ -18,10 +18,17 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; import java.util.concurrent.CompletableFuture; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Query; import org.neo4j.driver.exceptions.AuthorizationExpiredException; import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; @@ -34,103 +41,87 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; - -class SessionPullResponseCompletionListenerTest -{ +class SessionPullResponseCompletionListenerTest { @Test - void shouldReleaseConnectionOnSuccess() - { + void shouldReleaseConnectionOnSuccess() { Connection connection = newConnectionMock(); - PullResponseCompletionListener listener = new SessionPullResponseCompletionListener( connection, BookmarkHolder.NO_OP ); - ResponseHandler handler = newHandler( connection, listener ); + PullResponseCompletionListener listener = + new SessionPullResponseCompletionListener(connection, BookmarkHolder.NO_OP); + ResponseHandler handler = newHandler(connection, listener); - handler.onSuccess( emptyMap() ); + handler.onSuccess(emptyMap()); - verify( connection ).release(); + verify(connection).release(); } @Test - void shouldReleaseConnectionOnFailure() - { + void shouldReleaseConnectionOnFailure() { Connection connection = newConnectionMock(); - PullResponseCompletionListener listener = new SessionPullResponseCompletionListener( connection, BookmarkHolder.NO_OP ); - ResponseHandler handler = newHandler( connection, listener ); + PullResponseCompletionListener listener = + new SessionPullResponseCompletionListener(connection, BookmarkHolder.NO_OP); + ResponseHandler handler = newHandler(connection, listener); - handler.onFailure( new RuntimeException() ); + handler.onFailure(new RuntimeException()); - verify( connection ).release(); + verify(connection).release(); } @Test - void shouldUpdateBookmarksOnSuccess() - { + void shouldUpdateBookmarksOnSuccess() { Connection connection = newConnectionMock(); String bookmarkValue = "neo4j:bookmark:v1:tx42"; - BookmarkHolder bookmarkHolder = mock( BookmarkHolder.class ); - PullResponseCompletionListener listener = new SessionPullResponseCompletionListener( connection, bookmarkHolder ); - ResponseHandler handler = newHandler( connection, listener ); + BookmarkHolder bookmarkHolder = mock(BookmarkHolder.class); + PullResponseCompletionListener listener = new SessionPullResponseCompletionListener(connection, bookmarkHolder); + ResponseHandler handler = newHandler(connection, listener); - handler.onSuccess( singletonMap( "bookmark", value( bookmarkValue ) ) ); + handler.onSuccess(singletonMap("bookmark", value(bookmarkValue))); - verify( bookmarkHolder ).setBookmark( InternalBookmark.parse( bookmarkValue ) ); + verify(bookmarkHolder).setBookmark(InternalBookmark.parse(bookmarkValue)); } @Test - void shouldReleaseConnectionImmediatelyOnAuthorizationExpiredExceptionFailure() - { + void shouldReleaseConnectionImmediatelyOnAuthorizationExpiredExceptionFailure() { Connection connection = newConnectionMock(); - PullResponseCompletionListener listener = new SessionPullResponseCompletionListener( connection, BookmarkHolder.NO_OP ); - ResponseHandler handler = newHandler( connection, listener ); - AuthorizationExpiredException exception = new AuthorizationExpiredException( "code", "message" ); + PullResponseCompletionListener listener = + new SessionPullResponseCompletionListener(connection, BookmarkHolder.NO_OP); + ResponseHandler handler = newHandler(connection, listener); + AuthorizationExpiredException exception = new AuthorizationExpiredException("code", "message"); - handler.onFailure( exception ); + handler.onFailure(exception); - verify( connection ).terminateAndRelease( AuthorizationExpiredException.DESCRIPTION ); - verify( connection, never() ).release(); + verify(connection).terminateAndRelease(AuthorizationExpiredException.DESCRIPTION); + verify(connection, never()).release(); } @Test - void shouldReleaseConnectionImmediatelyOnConnectionReadTimeoutExceptionFailure() - { + void shouldReleaseConnectionImmediatelyOnConnectionReadTimeoutExceptionFailure() { Connection connection = newConnectionMock(); - PullResponseCompletionListener listener = new SessionPullResponseCompletionListener( connection, BookmarkHolder.NO_OP ); - ResponseHandler handler = newHandler( connection, listener ); + PullResponseCompletionListener listener = + new SessionPullResponseCompletionListener(connection, BookmarkHolder.NO_OP); + ResponseHandler handler = newHandler(connection, listener); - handler.onFailure( ConnectionReadTimeoutException.INSTANCE ); + handler.onFailure(ConnectionReadTimeoutException.INSTANCE); - verify( connection ).terminateAndRelease( ConnectionReadTimeoutException.INSTANCE.getMessage() ); - verify( connection, never() ).release(); + verify(connection).terminateAndRelease(ConnectionReadTimeoutException.INSTANCE.getMessage()); + verify(connection, never()).release(); } - private static ResponseHandler newHandler( Connection connection, PullResponseCompletionListener listener ) - { - RunResponseHandler runHandler = new RunResponseHandler( new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock( Connection.class ), null ); - BasicPullResponseHandler handler = - new BasicPullResponseHandler( new Query( "RETURN 1" ), runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, listener ); - handler.installRecordConsumer( ( record, throwable ) -> - { - } ); - handler.installSummaryConsumer( ( resultSummary, throwable ) -> - { - } ); + private static ResponseHandler newHandler(Connection connection, PullResponseCompletionListener listener) { + RunResponseHandler runHandler = new RunResponseHandler( + new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock(Connection.class), null); + BasicPullResponseHandler handler = new BasicPullResponseHandler( + new Query("RETURN 1"), runHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, listener); + handler.installRecordConsumer((record, throwable) -> {}); + handler.installSummaryConsumer((resultSummary, throwable) -> {}); return handler; } - private static Connection newConnectionMock() - { - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( BoltServerAddress.LOCAL_DEFAULT ); - when( connection.serverVersion() ).thenReturn( anyServerVersion() ); - when( connection.protocol() ).thenReturn( BoltProtocolV43.INSTANCE ); - when( connection.serverAgent() ).thenReturn( "Neo4j/4.2.5" ); + private static Connection newConnectionMock() { + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(BoltServerAddress.LOCAL_DEFAULT); + when(connection.serverVersion()).thenReturn(anyServerVersion()); + when(connection.protocol()).thenReturn(BoltProtocolV43.INSTANCE); + when(connection.serverAgent()).thenReturn("Neo4j/4.2.5"); return connection; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/TransactionPullResponseCompletionListenerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/TransactionPullResponseCompletionListenerTest.java index 287c9d2794..f603dfcb9b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/TransactionPullResponseCompletionListenerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/TransactionPullResponseCompletionListenerTest.java @@ -18,11 +18,15 @@ */ package org.neo4j.driver.internal.handlers; -import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.internal.messaging.v3.BoltProtocolV3.METADATA_EXTRACTOR; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; import java.io.IOException; import java.util.concurrent.CompletableFuture; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Query; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.exceptions.ServiceUnavailableException; @@ -35,52 +39,40 @@ import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43; import org.neo4j.driver.internal.spi.Connection; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.internal.messaging.v3.BoltProtocolV3.METADATA_EXTRACTOR; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; - -class TransactionPullResponseCompletionListenerTest -{ +class TransactionPullResponseCompletionListenerTest { @Test - void shouldMarkTransactionAsTerminatedOnFailures() - { - testErrorHandling( new ClientException( "Neo.ClientError.Cluster.NotALeader", "" ) ); - testErrorHandling( new ClientException( "Neo.ClientError.Procedure.ProcedureCallFailed", "" ) ); - testErrorHandling( new TransientException( "Neo.TransientError.Transaction.Terminated", "" ) ); - testErrorHandling( new TransientException( "Neo.TransientError.General.DatabaseUnavailable", "" ) ); + void shouldMarkTransactionAsTerminatedOnFailures() { + testErrorHandling(new ClientException("Neo.ClientError.Cluster.NotALeader", "")); + testErrorHandling(new ClientException("Neo.ClientError.Procedure.ProcedureCallFailed", "")); + testErrorHandling(new TransientException("Neo.TransientError.Transaction.Terminated", "")); + testErrorHandling(new TransientException("Neo.TransientError.General.DatabaseUnavailable", "")); - testErrorHandling( new RuntimeException() ); - testErrorHandling( new IOException() ); - testErrorHandling( new ServiceUnavailableException( "" ) ); - testErrorHandling( new SessionExpiredException( "" ) ); - testErrorHandling( new SessionExpiredException( "" ) ); - testErrorHandling( new ClientException( "Neo.ClientError.Request.Invalid" ) ); + testErrorHandling(new RuntimeException()); + testErrorHandling(new IOException()); + testErrorHandling(new ServiceUnavailableException("")); + testErrorHandling(new SessionExpiredException("")); + testErrorHandling(new SessionExpiredException("")); + testErrorHandling(new ClientException("Neo.ClientError.Request.Invalid")); } - private static void testErrorHandling( Throwable error ) - { - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( BoltServerAddress.LOCAL_DEFAULT ); - when( connection.serverVersion() ).thenReturn( anyServerVersion() ); - when( connection.protocol() ).thenReturn( BoltProtocolV43.INSTANCE ); - when( connection.serverAgent() ).thenReturn( "Neo4j/4.2.5" ); - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.isOpen() ).thenReturn( true ); - TransactionPullResponseCompletionListener listener = new TransactionPullResponseCompletionListener( tx ); - RunResponseHandler runHandler = new RunResponseHandler( new CompletableFuture<>(), METADATA_EXTRACTOR, null, null ); - PullResponseHandler handler = new BasicPullResponseHandler( new Query( "RETURN 1" ), runHandler, - connection, METADATA_EXTRACTOR, listener ); - handler.installRecordConsumer( ( record, throwable ) -> - { - } ); - handler.installSummaryConsumer( ( resultSummary, throwable ) -> - { - } ); + private static void testErrorHandling(Throwable error) { + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(BoltServerAddress.LOCAL_DEFAULT); + when(connection.serverVersion()).thenReturn(anyServerVersion()); + when(connection.protocol()).thenReturn(BoltProtocolV43.INSTANCE); + when(connection.serverAgent()).thenReturn("Neo4j/4.2.5"); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.isOpen()).thenReturn(true); + TransactionPullResponseCompletionListener listener = new TransactionPullResponseCompletionListener(tx); + RunResponseHandler runHandler = + new RunResponseHandler(new CompletableFuture<>(), METADATA_EXTRACTOR, null, null); + PullResponseHandler handler = new BasicPullResponseHandler( + new Query("RETURN 1"), runHandler, connection, METADATA_EXTRACTOR, listener); + handler.installRecordConsumer((record, throwable) -> {}); + handler.installSummaryConsumer((resultSummary, throwable) -> {}); - handler.onFailure( error ); + handler.onFailure(error); - verify( tx ).markTerminated( error ); + verify(tx).markTerminated(error); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/AutoPullResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/AutoPullResponseHandlerTest.java index adc4317456..71cd324629 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/AutoPullResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/AutoPullResponseHandlerTest.java @@ -18,15 +18,24 @@ */ package org.neo4j.driver.internal.handlers.pulln; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; -import org.mockito.Mockito; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.Values.values; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.DEFAULT_FETCH_SIZE; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; - +import org.junit.jupiter.api.Test; +import org.mockito.InOrder; +import org.mockito.Mockito; import org.neo4j.driver.Query; import org.neo4j.driver.Value; import org.neo4j.driver.internal.handlers.PullAllResponseHandlerTestBase; @@ -37,163 +46,150 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.value.BooleanValue; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.Values.values; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.DEFAULT_FETCH_SIZE; - -class AutoPullResponseHandlerTest extends PullAllResponseHandlerTestBase -{ +class AutoPullResponseHandlerTest extends PullAllResponseHandlerTestBase { @Override - protected AutoPullResponseHandler newHandler( Query query, List queryKeys, Connection connection ) - { - RunResponseHandler runResponseHandler = - new RunResponseHandler( new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock( Connection.class ), null ); - runResponseHandler.onSuccess( singletonMap( "fields", value( queryKeys ) ) ); - AutoPullResponseHandler handler = - new AutoPullResponseHandler( query, runResponseHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, - mock( PullResponseCompletionListener.class ), - DEFAULT_FETCH_SIZE ); + protected AutoPullResponseHandler newHandler(Query query, List queryKeys, Connection connection) { + RunResponseHandler runResponseHandler = new RunResponseHandler( + new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock(Connection.class), null); + runResponseHandler.onSuccess(singletonMap("fields", value(queryKeys))); + AutoPullResponseHandler handler = new AutoPullResponseHandler( + query, + runResponseHandler, + connection, + BoltProtocolV3.METADATA_EXTRACTOR, + mock(PullResponseCompletionListener.class), + DEFAULT_FETCH_SIZE); handler.prePopulateRecords(); return handler; } - protected AutoPullResponseHandler newHandler( Query query, Connection connection, long fetchSize ) - { - RunResponseHandler runResponseHandler = - new RunResponseHandler( new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock( Connection.class ), null ); - runResponseHandler.onSuccess( emptyMap() ); - AutoPullResponseHandler handler = - new AutoPullResponseHandler( query, runResponseHandler, connection, BoltProtocolV3.METADATA_EXTRACTOR, - mock( PullResponseCompletionListener.class ), - fetchSize ); + protected AutoPullResponseHandler newHandler(Query query, Connection connection, long fetchSize) { + RunResponseHandler runResponseHandler = new RunResponseHandler( + new CompletableFuture<>(), BoltProtocolV3.METADATA_EXTRACTOR, mock(Connection.class), null); + runResponseHandler.onSuccess(emptyMap()); + AutoPullResponseHandler handler = new AutoPullResponseHandler( + query, + runResponseHandler, + connection, + BoltProtocolV3.METADATA_EXTRACTOR, + mock(PullResponseCompletionListener.class), + fetchSize); handler.prePopulateRecords(); return handler; } @Test - void shouldKeepRequestingWhenBetweenRange() - { + void shouldKeepRequestingWhenBetweenRange() { Connection connection = connectionMock(); - InOrder inOrder = Mockito.inOrder( connection ); + InOrder inOrder = Mockito.inOrder(connection); - //highwatermark=2, lowwatermark=1 - AutoPullResponseHandler handler = newHandler( new Query( "RETURN 1" ), connection, 4 ); + // highwatermark=2, lowwatermark=1 + AutoPullResponseHandler handler = newHandler(new Query("RETURN 1"), connection, 4); - Map metaData = new HashMap<>( 1 ); - metaData.put( "has_more", BooleanValue.TRUE ); + Map metaData = new HashMap<>(1); + metaData.put("has_more", BooleanValue.TRUE); - inOrder.verify( connection ).writeAndFlush( any( PullMessage.class ), any() ); + inOrder.verify(connection).writeAndFlush(any(PullMessage.class), any()); - handler.onRecord( values( 1 ) ); - handler.onRecord( values( 2 ) ); - handler.onSuccess( metaData ); //2 in the record queue + handler.onRecord(values(1)); + handler.onRecord(values(2)); + handler.onSuccess(metaData); // 2 in the record queue - //should send another pulln request since maxValue not met - inOrder.verify( connection ).writeAndFlush( any(), any() ); + // should send another pulln request since maxValue not met + inOrder.verify(connection).writeAndFlush(any(), any()); } @Test - void shouldStopRequestingWhenOverMaxWatermark() - { + void shouldStopRequestingWhenOverMaxWatermark() { Connection connection = connectionMock(); - InOrder inOrder = Mockito.inOrder( connection ); + InOrder inOrder = Mockito.inOrder(connection); - //highWatermark=2, lowWatermark=1 - AutoPullResponseHandler handler = newHandler( new Query( "RETURN 1" ), connection, 4 ); + // highWatermark=2, lowWatermark=1 + AutoPullResponseHandler handler = newHandler(new Query("RETURN 1"), connection, 4); - Map metaData = new HashMap<>( 1 ); - metaData.put( "has_more", BooleanValue.TRUE ); + Map metaData = new HashMap<>(1); + metaData.put("has_more", BooleanValue.TRUE); - inOrder.verify( connection ).writeAndFlush( any( PullMessage.class ), any() ); + inOrder.verify(connection).writeAndFlush(any(PullMessage.class), any()); - handler.onRecord( values( 1 ) ); - handler.onRecord( values( 2 ) ); - handler.onRecord( values( 3 ) ); - handler.onSuccess( metaData ); + handler.onRecord(values(1)); + handler.onRecord(values(2)); + handler.onRecord(values(3)); + handler.onSuccess(metaData); - //only initial writeAndFlush() - verify( connection, times( 1 ) ).writeAndFlush( any( PullMessage.class ), any() ); + // only initial writeAndFlush() + verify(connection, times(1)).writeAndFlush(any(PullMessage.class), any()); } @Test - void shouldRestartRequestingWhenMinimumWatermarkMet() - { + void shouldRestartRequestingWhenMinimumWatermarkMet() { Connection connection = connectionMock(); - InOrder inOrder = Mockito.inOrder( connection ); + InOrder inOrder = Mockito.inOrder(connection); - //highwatermark=4, lowwatermark=2 - AutoPullResponseHandler handler = newHandler( new Query( "RETURN 1" ), connection, 7 ); + // highwatermark=4, lowwatermark=2 + AutoPullResponseHandler handler = newHandler(new Query("RETURN 1"), connection, 7); - Map metaData = new HashMap<>( 1 ); - metaData.put( "has_more", BooleanValue.TRUE ); + Map metaData = new HashMap<>(1); + metaData.put("has_more", BooleanValue.TRUE); - inOrder.verify( connection ).writeAndFlush( any( PullMessage.class ), any() ); + inOrder.verify(connection).writeAndFlush(any(PullMessage.class), any()); - handler.onRecord( values( 1 ) ); - handler.onRecord( values( 2 ) ); - handler.onRecord( values( 3 ) ); - handler.onRecord( values( 4 ) ); - handler.onRecord( values( 5 ) ); - handler.onSuccess( metaData ); + handler.onRecord(values(1)); + handler.onRecord(values(2)); + handler.onRecord(values(3)); + handler.onRecord(values(4)); + handler.onRecord(values(5)); + handler.onSuccess(metaData); - verify( connection, times( 1 ) ).writeAndFlush( any( PullMessage.class ), any() ); + verify(connection, times(1)).writeAndFlush(any(PullMessage.class), any()); handler.nextAsync(); handler.nextAsync(); handler.nextAsync(); - inOrder.verify( connection ).writeAndFlush( any( PullMessage.class ), any() ); + inOrder.verify(connection).writeAndFlush(any(PullMessage.class), any()); } @Test - void shouldKeepRequestingMoreRecordsWhenPullAll() - { + void shouldKeepRequestingMoreRecordsWhenPullAll() { Connection connection = connectionMock(); - AutoPullResponseHandler handler = newHandler( new Query( "RETURN 1" ), connection, -1 ); + AutoPullResponseHandler handler = newHandler(new Query("RETURN 1"), connection, -1); - Map metaData = new HashMap<>( 1 ); - metaData.put( "has_more", BooleanValue.TRUE ); + Map metaData = new HashMap<>(1); + metaData.put("has_more", BooleanValue.TRUE); - handler.onRecord( values( 1 ) ); - handler.onSuccess( metaData ); + handler.onRecord(values(1)); + handler.onSuccess(metaData); - handler.onRecord( values( 2 ) ); - handler.onSuccess( metaData ); + handler.onRecord(values(2)); + handler.onSuccess(metaData); - handler.onRecord( values( 3 ) ); - handler.onSuccess( emptyMap() ); + handler.onRecord(values(3)); + handler.onSuccess(emptyMap()); - verify( connection, times( 3 ) ).writeAndFlush( any( PullMessage.class ), any() ); + verify(connection, times(3)).writeAndFlush(any(PullMessage.class), any()); } @Test - void shouldFunctionWhenHighAndLowWatermarksAreEqual() - { + void shouldFunctionWhenHighAndLowWatermarksAreEqual() { Connection connection = connectionMock(); - InOrder inOrder = Mockito.inOrder( connection ); + InOrder inOrder = Mockito.inOrder(connection); - //highwatermark=0, lowwatermark=0 - AutoPullResponseHandler handler = newHandler( new Query( "RETURN 1" ), connection, 1 ); + // highwatermark=0, lowwatermark=0 + AutoPullResponseHandler handler = newHandler(new Query("RETURN 1"), connection, 1); - Map metaData = new HashMap<>( 1 ); - metaData.put( "has_more", BooleanValue.TRUE ); + Map metaData = new HashMap<>(1); + metaData.put("has_more", BooleanValue.TRUE); - inOrder.verify( connection ).writeAndFlush( any( PullMessage.class ), any() ); + inOrder.verify(connection).writeAndFlush(any(PullMessage.class), any()); - handler.onRecord( values( 1 ) ); - handler.onSuccess( metaData ); + handler.onRecord(values(1)); + handler.onSuccess(metaData); - inOrder.verify( connection, never() ).writeAndFlush( any(), any() ); + inOrder.verify(connection, never()).writeAndFlush(any(), any()); handler.nextAsync(); - inOrder.verify( connection ).writeAndFlush( any( PullMessage.class ), any() ); + inOrder.verify(connection).writeAndFlush(any(PullMessage.class), any()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/BasicPullResponseHandlerTestBase.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/BasicPullResponseHandlerTestBase.java index eb8f68e699..d61394854d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/BasicPullResponseHandlerTestBase.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/BasicPullResponseHandlerTestBase.java @@ -18,14 +18,21 @@ */ package org.neo4j.driver.internal.handlers.pulln; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; import java.util.HashMap; import java.util.function.BiConsumer; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.neo4j.driver.Record; import org.neo4j.driver.Value; import org.neo4j.driver.internal.BoltServerAddress; @@ -37,240 +44,229 @@ import org.neo4j.driver.internal.value.BooleanValue; import org.neo4j.driver.summary.ResultSummary; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -abstract class BasicPullResponseHandlerTestBase -{ - protected abstract void shouldHandleSuccessWithSummary( BasicPullResponseHandler.State state ); +abstract class BasicPullResponseHandlerTestBase { + protected abstract void shouldHandleSuccessWithSummary(BasicPullResponseHandler.State state); - protected abstract void shouldHandleFailure( BasicPullResponseHandler.State state ); + protected abstract void shouldHandleFailure(BasicPullResponseHandler.State state); - protected abstract BasicPullResponseHandler newResponseHandlerWithStatus( Connection conn, BiConsumer recordConsumer, - BiConsumer summaryConsumer, - BasicPullResponseHandler.State state ); + protected abstract BasicPullResponseHandler newResponseHandlerWithStatus( + Connection conn, + BiConsumer recordConsumer, + BiConsumer summaryConsumer, + BasicPullResponseHandler.State state); // on success with summary @ParameterizedTest - @MethodSource( "allStatus" ) - void shouldSuccessWithSummary( BasicPullResponseHandler.State state ) throws Throwable - { - shouldHandleSuccessWithSummary( state ); + @MethodSource("allStatus") + void shouldSuccessWithSummary(BasicPullResponseHandler.State state) throws Throwable { + shouldHandleSuccessWithSummary(state); } // on success with has_more @Test - void shouldRequestMoreWithHasMore() throws Throwable - { + void shouldRequestMoreWithHasMore() throws Throwable { // Given a handler in streaming state Connection conn = mockConnection(); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, BasicPullResponseHandler.State.STREAMING_STATE ); + BasicPullResponseHandler handler = + newResponseHandlerWithStatus(conn, BasicPullResponseHandler.State.STREAMING_STATE); // When - handler.request( 100 ); // I append a request to ask for more + handler.request(100); // I append a request to ask for more - handler.onSuccess( metaWithHasMoreEqualsTrue() ); + handler.onSuccess(metaWithHasMoreEqualsTrue()); // Then - verify( conn ).writeAndFlush( any( PullMessage.class ), eq( handler ) ); - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.STREAMING_STATE ) ); + verify(conn).writeAndFlush(any(PullMessage.class), eq(handler)); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.STREAMING_STATE)); } @Test - void shouldInformSummaryConsumerSuccessWithHasMore() throws Throwable - { + void shouldInformSummaryConsumerSuccessWithHasMore() throws Throwable { // Given Connection conn = mockConnection(); - BiConsumer recordConsumer = mock( BiConsumer.class ); - BiConsumer summaryConsumer = mock( BiConsumer.class ); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, recordConsumer, summaryConsumer, BasicPullResponseHandler.State.STREAMING_STATE ); + BiConsumer recordConsumer = mock(BiConsumer.class); + BiConsumer summaryConsumer = mock(BiConsumer.class); + BasicPullResponseHandler handler = newResponseHandlerWithStatus( + conn, recordConsumer, summaryConsumer, BasicPullResponseHandler.State.STREAMING_STATE); // When - handler.onSuccess( metaWithHasMoreEqualsTrue() ); + handler.onSuccess(metaWithHasMoreEqualsTrue()); // Then - verifyNoMoreInteractions( conn ); - verifyNoMoreInteractions( recordConsumer ); - verify( summaryConsumer ).accept( null, null ); - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.READY_STATE ) ); + verifyNoMoreInteractions(conn); + verifyNoMoreInteractions(recordConsumer); + verify(summaryConsumer).accept(null, null); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.READY_STATE)); } @Test - void shouldDiscardIfStreamingIsCanceled() throws Throwable - { + void shouldDiscardIfStreamingIsCanceled() throws Throwable { // Given a handler in streaming state Connection conn = mockConnection(); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, BasicPullResponseHandler.State.CANCELLED_STATE ); - handler.onSuccess( metaWithHasMoreEqualsTrue() ); + BasicPullResponseHandler handler = + newResponseHandlerWithStatus(conn, BasicPullResponseHandler.State.CANCELLED_STATE); + handler.onSuccess(metaWithHasMoreEqualsTrue()); // Then - verify( conn ).writeAndFlush( any( DiscardMessage.class ), eq( handler ) ); - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.CANCELLED_STATE ) ); + verify(conn).writeAndFlush(any(DiscardMessage.class), eq(handler)); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.CANCELLED_STATE)); } // on failure @ParameterizedTest - @MethodSource( "allStatus" ) - void shouldErrorToRecordAndSummaryConsumer( BasicPullResponseHandler.State state ) throws Throwable - { - shouldHandleFailure( state ); + @MethodSource("allStatus") + void shouldErrorToRecordAndSummaryConsumer(BasicPullResponseHandler.State state) throws Throwable { + shouldHandleFailure(state); } // on record @Test - void shouldReportRecordInStreaming() throws Throwable - { + void shouldReportRecordInStreaming() throws Throwable { // Given a handler in streaming state Connection conn = mockConnection(); - BiConsumer recordConsumer = mock( BiConsumer.class ); - BiConsumer summaryConsumer = mock( BiConsumer.class ); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, recordConsumer, summaryConsumer, BasicPullResponseHandler.State.STREAMING_STATE ); + BiConsumer recordConsumer = mock(BiConsumer.class); + BiConsumer summaryConsumer = mock(BiConsumer.class); + BasicPullResponseHandler handler = newResponseHandlerWithStatus( + conn, recordConsumer, summaryConsumer, BasicPullResponseHandler.State.STREAMING_STATE); // When - handler.onRecord( new Value[0] ); + handler.onRecord(new Value[0]); // Then - verify( recordConsumer ).accept( any( Record.class ), eq( null ) ); - verifyNoMoreInteractions( summaryConsumer ); - verifyNoMoreInteractions( conn ); - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.STREAMING_STATE ) ); + verify(recordConsumer).accept(any(Record.class), eq(null)); + verifyNoMoreInteractions(summaryConsumer); + verifyNoMoreInteractions(conn); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.STREAMING_STATE)); } @ParameterizedTest - @MethodSource( "allStatusExceptStreaming" ) - void shouldNotReportRecordWhenNotStreaming( BasicPullResponseHandler.State state ) throws Throwable - { + @MethodSource("allStatusExceptStreaming") + void shouldNotReportRecordWhenNotStreaming(BasicPullResponseHandler.State state) throws Throwable { // Given a handler in streaming state Connection conn = mockConnection(); - BiConsumer recordConsumer = mock( BiConsumer.class ); - BiConsumer summaryConsumer = mock( BiConsumer.class ); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, recordConsumer, summaryConsumer, state ); + BiConsumer recordConsumer = mock(BiConsumer.class); + BiConsumer summaryConsumer = mock(BiConsumer.class); + BasicPullResponseHandler handler = newResponseHandlerWithStatus(conn, recordConsumer, summaryConsumer, state); // When - handler.onRecord( new Value[0] ); + handler.onRecord(new Value[0]); // Then - verifyNoMoreInteractions( recordConsumer ); - verifyNoMoreInteractions( summaryConsumer ); - assertThat( handler.state(), equalTo( state ) ); + verifyNoMoreInteractions(recordConsumer); + verifyNoMoreInteractions(summaryConsumer); + assertThat(handler.state(), equalTo(state)); } // request @Test - void shouldStayInStreaming() throws Throwable - { + void shouldStayInStreaming() throws Throwable { // Given Connection conn = mockConnection(); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, BasicPullResponseHandler.State.STREAMING_STATE ); + BasicPullResponseHandler handler = + newResponseHandlerWithStatus(conn, BasicPullResponseHandler.State.STREAMING_STATE); // When - handler.request( 100 ); + handler.request(100); // Then - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.STREAMING_STATE ) ); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.STREAMING_STATE)); } @Test - void shouldPullAndSwitchStreamingInReady() throws Throwable - { + void shouldPullAndSwitchStreamingInReady() throws Throwable { // Given Connection conn = mockConnection(); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, BasicPullResponseHandler.State.READY_STATE ); + BasicPullResponseHandler handler = + newResponseHandlerWithStatus(conn, BasicPullResponseHandler.State.READY_STATE); // When - handler.request( 100 ); + handler.request(100); // Then - verify( conn ).writeAndFlush( any( PullMessage.class ), eq( handler ) ); - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.STREAMING_STATE ) ); + verify(conn).writeAndFlush(any(PullMessage.class), eq(handler)); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.STREAMING_STATE)); } // cancel @Test - void shouldStayInCancel() throws Throwable - { + void shouldStayInCancel() throws Throwable { // Given Connection conn = mockConnection(); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, BasicPullResponseHandler.State.CANCELLED_STATE ); + BasicPullResponseHandler handler = + newResponseHandlerWithStatus(conn, BasicPullResponseHandler.State.CANCELLED_STATE); // When handler.cancel(); // Then - verifyNoMoreInteractions( conn ); - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.CANCELLED_STATE ) ); + verifyNoMoreInteractions(conn); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.CANCELLED_STATE)); } @Test - void shouldSwitchFromStreamingToCancel() throws Throwable - { + void shouldSwitchFromStreamingToCancel() throws Throwable { // Given Connection conn = mockConnection(); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, BasicPullResponseHandler.State.STREAMING_STATE ); + BasicPullResponseHandler handler = + newResponseHandlerWithStatus(conn, BasicPullResponseHandler.State.STREAMING_STATE); // When handler.cancel(); // Then - verifyNoMoreInteractions( conn ); - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.CANCELLED_STATE ) ); + verifyNoMoreInteractions(conn); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.CANCELLED_STATE)); } @Test - void shouldSwitchFromReadyToCancel() throws Throwable - { + void shouldSwitchFromReadyToCancel() throws Throwable { // Given Connection conn = mockConnection(); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, BasicPullResponseHandler.State.READY_STATE ); + BasicPullResponseHandler handler = + newResponseHandlerWithStatus(conn, BasicPullResponseHandler.State.READY_STATE); // When handler.cancel(); // Then - verify( conn ).writeAndFlush( any( DiscardMessage.class ), eq( handler ) ); - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.CANCELLED_STATE ) ); + verify(conn).writeAndFlush(any(DiscardMessage.class), eq(handler)); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.CANCELLED_STATE)); } - static Connection mockConnection() - { - Connection conn = mock( Connection.class ); - when( conn.serverAddress() ).thenReturn( mock( BoltServerAddress.class ) ); - when( conn.serverVersion() ).thenReturn( mock( ServerVersion.class ) ); - when( conn.protocol() ).thenReturn( BoltProtocolV43.INSTANCE ); - when( conn.serverAgent() ).thenReturn( "Neo4j/4.2.5" ); + static Connection mockConnection() { + Connection conn = mock(Connection.class); + when(conn.serverAddress()).thenReturn(mock(BoltServerAddress.class)); + when(conn.serverVersion()).thenReturn(mock(ServerVersion.class)); + when(conn.protocol()).thenReturn(BoltProtocolV43.INSTANCE); + when(conn.serverAgent()).thenReturn("Neo4j/4.2.5"); return conn; } - private BasicPullResponseHandler newResponseHandlerWithStatus( Connection conn, BasicPullResponseHandler.State state ) - { - BiConsumer recordConsumer = mock( BiConsumer.class ); - BiConsumer summaryConsumer = mock( BiConsumer.class ); - return newResponseHandlerWithStatus( conn, recordConsumer, summaryConsumer, state ); + private BasicPullResponseHandler newResponseHandlerWithStatus( + Connection conn, BasicPullResponseHandler.State state) { + BiConsumer recordConsumer = mock(BiConsumer.class); + BiConsumer summaryConsumer = mock(BiConsumer.class); + return newResponseHandlerWithStatus(conn, recordConsumer, summaryConsumer, state); } - private static HashMap metaWithHasMoreEqualsTrue() - { - HashMap meta = new HashMap<>( 1 ); - meta.put( "has_more", BooleanValue.TRUE ); + private static HashMap metaWithHasMoreEqualsTrue() { + HashMap meta = new HashMap<>(1); + meta.put("has_more", BooleanValue.TRUE); return meta; } - private static Stream allStatusExceptStreaming() - { - return Stream.of( BasicPullResponseHandler.State.SUCCEEDED_STATE, BasicPullResponseHandler.State.FAILURE_STATE, - BasicPullResponseHandler.State.CANCELLED_STATE, BasicPullResponseHandler.State.READY_STATE ); + private static Stream allStatusExceptStreaming() { + return Stream.of( + BasicPullResponseHandler.State.SUCCEEDED_STATE, BasicPullResponseHandler.State.FAILURE_STATE, + BasicPullResponseHandler.State.CANCELLED_STATE, BasicPullResponseHandler.State.READY_STATE); } - private static Stream allStatus() - { - return Stream.of( BasicPullResponseHandler.State.SUCCEEDED_STATE, BasicPullResponseHandler.State.FAILURE_STATE, - BasicPullResponseHandler.State.CANCELLED_STATE, BasicPullResponseHandler.State.READY_STATE, - BasicPullResponseHandler.State.STREAMING_STATE ); + private static Stream allStatus() { + return Stream.of( + BasicPullResponseHandler.State.SUCCEEDED_STATE, + BasicPullResponseHandler.State.FAILURE_STATE, + BasicPullResponseHandler.State.CANCELLED_STATE, + BasicPullResponseHandler.State.READY_STATE, + BasicPullResponseHandler.State.STREAMING_STATE); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/SessionPullResponseCompletionListenerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/SessionPullResponseCompletionListenerTest.java index 3c9cc0ddb6..59c1960b57 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/SessionPullResponseCompletionListenerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/SessionPullResponseCompletionListenerTest.java @@ -18,11 +18,17 @@ */ package org.neo4j.driver.internal.handlers.pulln; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + import java.util.Collections; import java.util.function.BiConsumer; - -import org.neo4j.driver.Record; import org.neo4j.driver.Query; +import org.neo4j.driver.Record; import org.neo4j.driver.internal.BookmarkHolder; import org.neo4j.driver.internal.handlers.RunResponseHandler; import org.neo4j.driver.internal.handlers.SessionPullResponseCompletionListener; @@ -30,76 +36,72 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.summary.ResultSummary; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -class SessionPullResponseCompletionListenerTest extends BasicPullResponseHandlerTestBase -{ - protected void shouldHandleSuccessWithSummary( BasicPullResponseHandler.State state ) - { +class SessionPullResponseCompletionListenerTest extends BasicPullResponseHandlerTestBase { + protected void shouldHandleSuccessWithSummary(BasicPullResponseHandler.State state) { // Given Connection conn = mockConnection(); - BiConsumer recordConsumer = mock( BiConsumer.class ); - BiConsumer summaryConsumer = mock( BiConsumer.class ); - BookmarkHolder bookmarkHolder = mock( BookmarkHolder.class ); - PullResponseHandler handler = newSessionResponseHandler( conn, recordConsumer, summaryConsumer, bookmarkHolder, state ); + BiConsumer recordConsumer = mock(BiConsumer.class); + BiConsumer summaryConsumer = mock(BiConsumer.class); + BookmarkHolder bookmarkHolder = mock(BookmarkHolder.class); + PullResponseHandler handler = + newSessionResponseHandler(conn, recordConsumer, summaryConsumer, bookmarkHolder, state); // When - handler.onSuccess( Collections.emptyMap() ); + handler.onSuccess(Collections.emptyMap()); // Then -// assertThat( handler.status(), equalTo( SUCCEEDED ) ); - verify( conn ).release(); - verify( bookmarkHolder ).setBookmark( any() ); - verify( recordConsumer ).accept( null, null ); - verify( summaryConsumer ).accept( any( ResultSummary.class ), eq( null ) ); + // assertThat( handler.status(), equalTo( SUCCEEDED ) ); + verify(conn).release(); + verify(bookmarkHolder).setBookmark(any()); + verify(recordConsumer).accept(null, null); + verify(summaryConsumer).accept(any(ResultSummary.class), eq(null)); } @Override - protected void shouldHandleFailure( BasicPullResponseHandler.State state ) - { + protected void shouldHandleFailure(BasicPullResponseHandler.State state) { // Given Connection conn = mockConnection(); - BiConsumer recordConsumer = mock( BiConsumer.class ); - BiConsumer summaryConsumer = mock( BiConsumer.class ); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, recordConsumer, summaryConsumer, state ); + BiConsumer recordConsumer = mock(BiConsumer.class); + BiConsumer summaryConsumer = mock(BiConsumer.class); + BasicPullResponseHandler handler = newResponseHandlerWithStatus(conn, recordConsumer, summaryConsumer, state); // When - RuntimeException error = new RuntimeException( "I am an error" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("I am an error"); + handler.onFailure(error); // Then - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.FAILURE_STATE ) ); - verify( conn ).release(); - verify( recordConsumer ).accept( null, error ); - verify( summaryConsumer ).accept( any( ResultSummary.class ), eq( error ) ); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.FAILURE_STATE)); + verify(conn).release(); + verify(recordConsumer).accept(null, error); + verify(summaryConsumer).accept(any(ResultSummary.class), eq(error)); } @Override - protected BasicPullResponseHandler newResponseHandlerWithStatus( Connection conn, BiConsumer recordConsumer, - BiConsumer summaryConsumer, BasicPullResponseHandler.State state ) - { + protected BasicPullResponseHandler newResponseHandlerWithStatus( + Connection conn, + BiConsumer recordConsumer, + BiConsumer summaryConsumer, + BasicPullResponseHandler.State state) { BookmarkHolder bookmarkHolder = BookmarkHolder.NO_OP; - return newSessionResponseHandler( conn, recordConsumer, summaryConsumer, bookmarkHolder, state ); + return newSessionResponseHandler(conn, recordConsumer, summaryConsumer, bookmarkHolder, state); } - private static BasicPullResponseHandler newSessionResponseHandler( Connection conn, BiConsumer recordConsumer, - BiConsumer summaryConsumer, BookmarkHolder bookmarkHolder, - BasicPullResponseHandler.State state ) - { - RunResponseHandler runHandler = mock( RunResponseHandler.class ); - SessionPullResponseCompletionListener listener = new SessionPullResponseCompletionListener( conn, bookmarkHolder ); - BasicPullResponseHandler handler = - new BasicPullResponseHandler( mock( Query.class ), runHandler, conn, BoltProtocolV4.METADATA_EXTRACTOR, listener ); + private static BasicPullResponseHandler newSessionResponseHandler( + Connection conn, + BiConsumer recordConsumer, + BiConsumer summaryConsumer, + BookmarkHolder bookmarkHolder, + BasicPullResponseHandler.State state) { + RunResponseHandler runHandler = mock(RunResponseHandler.class); + SessionPullResponseCompletionListener listener = + new SessionPullResponseCompletionListener(conn, bookmarkHolder); + BasicPullResponseHandler handler = new BasicPullResponseHandler( + mock(Query.class), runHandler, conn, BoltProtocolV4.METADATA_EXTRACTOR, listener); - handler.installRecordConsumer( recordConsumer ); - handler.installSummaryConsumer( summaryConsumer ); + handler.installRecordConsumer(recordConsumer); + handler.installSummaryConsumer(summaryConsumer); - handler.state( state ); + handler.state(state); return handler; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/TransactionPullResponseCompletionListenerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/TransactionPullResponseCompletionListenerTest.java index 688e910929..fdc6fcccc1 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/TransactionPullResponseCompletionListenerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/pulln/TransactionPullResponseCompletionListenerTest.java @@ -18,9 +18,16 @@ */ package org.neo4j.driver.internal.handlers.pulln; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import java.util.Collections; import java.util.function.BiConsumer; - import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.internal.async.UnmanagedTransaction; @@ -30,77 +37,70 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.summary.ResultSummary; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class TransactionPullResponseCompletionListenerTest extends BasicPullResponseHandlerTestBase -{ +public class TransactionPullResponseCompletionListenerTest extends BasicPullResponseHandlerTestBase { @Override - protected void shouldHandleSuccessWithSummary( BasicPullResponseHandler.State state ) - { + protected void shouldHandleSuccessWithSummary(BasicPullResponseHandler.State state) { // Given Connection conn = mockConnection(); - BiConsumer recordConsumer = mock( BiConsumer.class ); - BiConsumer summaryConsumer = mock( BiConsumer.class ); - BasicPullResponseHandler handler = newResponseHandlerWithStatus( conn, recordConsumer, summaryConsumer, state ); + BiConsumer recordConsumer = mock(BiConsumer.class); + BiConsumer summaryConsumer = mock(BiConsumer.class); + BasicPullResponseHandler handler = newResponseHandlerWithStatus(conn, recordConsumer, summaryConsumer, state); // When - handler.onSuccess( Collections.emptyMap() ); + handler.onSuccess(Collections.emptyMap()); // Then - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.SUCCEEDED_STATE )); - verify( recordConsumer ).accept( null, null ); - verify( summaryConsumer ).accept( any( ResultSummary.class ), eq( null ) ); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.SUCCEEDED_STATE)); + verify(recordConsumer).accept(null, null); + verify(summaryConsumer).accept(any(ResultSummary.class), eq(null)); } @Override - protected void shouldHandleFailure( BasicPullResponseHandler.State state ) - { + protected void shouldHandleFailure(BasicPullResponseHandler.State state) { // Given Connection conn = mockConnection(); - BiConsumer recordConsumer = mock( BiConsumer.class ); - BiConsumer summaryConsumer = mock( BiConsumer.class ); - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.isOpen() ).thenReturn( true ); - BasicPullResponseHandler handler = newTxResponseHandler( conn, recordConsumer, summaryConsumer, tx, state ); + BiConsumer recordConsumer = mock(BiConsumer.class); + BiConsumer summaryConsumer = mock(BiConsumer.class); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.isOpen()).thenReturn(true); + BasicPullResponseHandler handler = newTxResponseHandler(conn, recordConsumer, summaryConsumer, tx, state); // When - RuntimeException error = new RuntimeException( "I am an error" ); - handler.onFailure( error ); + RuntimeException error = new RuntimeException("I am an error"); + handler.onFailure(error); // Then - assertThat( handler.state(), equalTo( BasicPullResponseHandler.State.FAILURE_STATE ) ); - verify( tx ).markTerminated( error ); - verify( recordConsumer ).accept( null, error ); - verify( summaryConsumer ).accept( any( ResultSummary.class ), eq( error ) ); + assertThat(handler.state(), equalTo(BasicPullResponseHandler.State.FAILURE_STATE)); + verify(tx).markTerminated(error); + verify(recordConsumer).accept(null, error); + verify(summaryConsumer).accept(any(ResultSummary.class), eq(error)); } @Override - protected BasicPullResponseHandler newResponseHandlerWithStatus( Connection conn, BiConsumer recordConsumer, - BiConsumer summaryConsumer, BasicPullResponseHandler.State state ) - { - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - return newTxResponseHandler( conn, recordConsumer, summaryConsumer, tx, state ); + protected BasicPullResponseHandler newResponseHandlerWithStatus( + Connection conn, + BiConsumer recordConsumer, + BiConsumer summaryConsumer, + BasicPullResponseHandler.State state) { + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + return newTxResponseHandler(conn, recordConsumer, summaryConsumer, tx, state); } - private static BasicPullResponseHandler newTxResponseHandler( Connection conn, BiConsumer recordConsumer, - BiConsumer summaryConsumer, UnmanagedTransaction tx, - BasicPullResponseHandler.State state ) - { - RunResponseHandler runHandler = mock( RunResponseHandler.class ); - TransactionPullResponseCompletionListener listener = new TransactionPullResponseCompletionListener( tx ); - BasicPullResponseHandler handler = - new BasicPullResponseHandler( mock( Query.class ), runHandler, conn, BoltProtocolV4.METADATA_EXTRACTOR, listener ); + private static BasicPullResponseHandler newTxResponseHandler( + Connection conn, + BiConsumer recordConsumer, + BiConsumer summaryConsumer, + UnmanagedTransaction tx, + BasicPullResponseHandler.State state) { + RunResponseHandler runHandler = mock(RunResponseHandler.class); + TransactionPullResponseCompletionListener listener = new TransactionPullResponseCompletionListener(tx); + BasicPullResponseHandler handler = new BasicPullResponseHandler( + mock(Query.class), runHandler, conn, BoltProtocolV4.METADATA_EXTRACTOR, listener); - handler.installRecordConsumer( recordConsumer ); - handler.installSummaryConsumer( summaryConsumer ); + handler.installRecordConsumer(recordConsumer); + handler.installSummaryConsumer(summaryConsumer); - handler.state( state ); + handler.state(state); return handler; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/logging/ChannelActivityLoggerTest.java b/driver/src/test/java/org/neo4j/driver/internal/logging/ChannelActivityLoggerTest.java index 7fa7effd3c..0f8c06208c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/logging/ChannelActivityLoggerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/logging/ChannelActivityLoggerTest.java @@ -18,59 +18,53 @@ */ package org.neo4j.driver.internal.logging; +import static org.junit.jupiter.api.Assertions.assertEquals; + import io.netty.channel.embedded.EmbeddedChannel; import org.junit.jupiter.api.Test; - +import org.neo4j.driver.Logging; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.connection.ChannelAttributes; -import org.neo4j.driver.Logging; - -import static org.junit.jupiter.api.Assertions.assertEquals; -class ChannelActivityLoggerTest -{ +class ChannelActivityLoggerTest { @Test - void shouldReformatWhenChannelIsNull() - { - ChannelActivityLogger activityLogger = new ChannelActivityLogger( null, Logging.none(), getClass() ); + void shouldReformatWhenChannelIsNull() { + ChannelActivityLogger activityLogger = new ChannelActivityLogger(null, Logging.none(), getClass()); - String reformatted = activityLogger.reformat( "Hello!" ); + String reformatted = activityLogger.reformat("Hello!"); - assertEquals( "Hello!", reformatted ); + assertEquals("Hello!", reformatted); } @Test - void shouldReformatWithChannelId() - { + void shouldReformatWithChannelId() { EmbeddedChannel channel = new EmbeddedChannel(); - ChannelActivityLogger activityLogger = new ChannelActivityLogger( channel, Logging.none(), getClass() ); + ChannelActivityLogger activityLogger = new ChannelActivityLogger(channel, Logging.none(), getClass()); - String reformatted = activityLogger.reformat( "Hello!" ); + String reformatted = activityLogger.reformat("Hello!"); - assertEquals( "[0x" + channel.id() + "][][] Hello!", reformatted ); + assertEquals("[0x" + channel.id() + "][][] Hello!", reformatted); } @Test - void shouldReformatWithChannelIdAndServerAddress() - { + void shouldReformatWithChannelIdAndServerAddress() { EmbeddedChannel channel = new EmbeddedChannel(); - ChannelAttributes.setServerAddress( channel, new BoltServerAddress( "somewhere", 1234 ) ); - ChannelActivityLogger activityLogger = new ChannelActivityLogger( channel, Logging.none(), getClass() ); + ChannelAttributes.setServerAddress(channel, new BoltServerAddress("somewhere", 1234)); + ChannelActivityLogger activityLogger = new ChannelActivityLogger(channel, Logging.none(), getClass()); - String reformatted = activityLogger.reformat( "Hello!" ); + String reformatted = activityLogger.reformat("Hello!"); - assertEquals( "[0x" + channel.id() + "][somewhere:1234][] Hello!", reformatted ); + assertEquals("[0x" + channel.id() + "][somewhere:1234][] Hello!", reformatted); } @Test - void shouldReformatWithChannelIdAndConnectionId() - { + void shouldReformatWithChannelIdAndConnectionId() { EmbeddedChannel channel = new EmbeddedChannel(); - ChannelAttributes.setConnectionId( channel, "bolt-12345" ); - ChannelActivityLogger activityLogger = new ChannelActivityLogger( channel, Logging.none(), getClass() ); + ChannelAttributes.setConnectionId(channel, "bolt-12345"); + ChannelActivityLogger activityLogger = new ChannelActivityLogger(channel, Logging.none(), getClass()); - String reformatted = activityLogger.reformat( "Hello!" ); + String reformatted = activityLogger.reformat("Hello!"); - assertEquals( "[0x" + channel.id() + "][][bolt-12345] Hello!", reformatted ); + assertEquals("[0x" + channel.id() + "][][bolt-12345] Hello!", reformatted); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/logging/ConsoleLoggingTest.java b/driver/src/test/java/org/neo4j/driver/internal/logging/ConsoleLoggingTest.java index 12b7f77cc7..4010e93607 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/logging/ConsoleLoggingTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/logging/ConsoleLoggingTest.java @@ -18,84 +18,76 @@ */ package org.neo4j.driver.internal.logging; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.Scanner; import java.util.logging.Level; - -import org.neo4j.driver.internal.logging.ConsoleLogging.ConsoleLogger; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.neo4j.driver.Logger; +import org.neo4j.driver.internal.logging.ConsoleLogging.ConsoleLogger; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class ConsoleLoggingTest -{ +class ConsoleLoggingTest { private static ByteArrayOutputStream out = new ByteArrayOutputStream(); private static PrintStream sysErr; @BeforeAll - static void saveSysOut() - { + static void saveSysOut() { sysErr = System.err; - System.setErr( new PrintStream( out ) ); + System.setErr(new PrintStream(out)); } @AfterAll - static void restoreSysOut() - { - System.setErr( sysErr ); + static void restoreSysOut() { + System.setErr(sysErr); } @BeforeEach - void setup() - { + void setup() { out.reset(); } @Test - void shouldOnlyRecordMessageOnce() - { + void shouldOnlyRecordMessageOnce() { // Given - ConsoleLogging logging = new ConsoleLogging( Level.ALL ); - Logger catLogger = logging.getLog( "Cat" ); - Logger dogLogger = logging.getLog( "Dog" ); + ConsoleLogging logging = new ConsoleLogging(Level.ALL); + Logger catLogger = logging.getLog("Cat"); + Logger dogLogger = logging.getLog("Dog"); - catLogger.debug( "Meow" ); - dogLogger.debug( "Wow" ); + catLogger.debug("Meow"); + dogLogger.debug("Wow"); - Scanner scanner = new Scanner( new ByteArrayInputStream( out.toByteArray() ) ); - assertTrue( scanner.hasNextLine() ); - assertTrue( scanner.nextLine().contains( "Meow" ) ); - assertTrue( scanner.hasNextLine() ); - assertTrue( scanner.nextLine().contains( "Wow" ) ); - assertFalse( scanner.hasNextLine() ); + Scanner scanner = new Scanner(new ByteArrayInputStream(out.toByteArray())); + assertTrue(scanner.hasNextLine()); + assertTrue(scanner.nextLine().contains("Meow")); + assertTrue(scanner.hasNextLine()); + assertTrue(scanner.nextLine().contains("Wow")); + assertFalse(scanner.hasNextLine()); } @Test - void shouldResetLoggerLevel() - { + void shouldResetLoggerLevel() { // Given String logName = ConsoleLogging.class.getName(); - java.util.logging.Logger logger = java.util.logging.Logger.getLogger( logName ); + java.util.logging.Logger logger = java.util.logging.Logger.getLogger(logName); // Then & When - new ConsoleLogger( logName, Level.ALL ).debug( "Meow" ); - assertEquals( Level.ALL, logger.getLevel() ); + new ConsoleLogger(logName, Level.ALL).debug("Meow"); + assertEquals(Level.ALL, logger.getLevel()); - new ConsoleLogger( logName, Level.SEVERE ).debug( "Wow" ); - assertEquals( Level.SEVERE, logger.getLevel() ); + new ConsoleLogger(logName, Level.SEVERE).debug("Wow"); + assertEquals(Level.SEVERE, logger.getLevel()); - Scanner scanner = new Scanner( new ByteArrayInputStream( out.toByteArray() ) ); - assertTrue( scanner.hasNextLine() ); - assertTrue( scanner.nextLine().contains( "Meow" ) ); - assertFalse( scanner.hasNextLine() ); + Scanner scanner = new Scanner(new ByteArrayInputStream(out.toByteArray())); + assertTrue(scanner.hasNextLine()); + assertTrue(scanner.nextLine().contains("Meow")); + assertFalse(scanner.hasNextLine()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/logging/PrefixedLoggerTest.java b/driver/src/test/java/org/neo4j/driver/internal/logging/PrefixedLoggerTest.java index b6d31d540f..9a2dad123a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/logging/PrefixedLoggerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/logging/PrefixedLoggerTest.java @@ -18,10 +18,6 @@ */ package org.neo4j.driver.internal.logging; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.Logger; - import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -32,223 +28,204 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -class PrefixedLoggerTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Logger; + +class PrefixedLoggerTest { private static final String PREFIX = "Output"; private static final String MESSAGE = "Hello World!"; private static final Exception ERROR = new Exception(); @Test - void shouldThrowWhenDelegateIsNull() - { - assertThrows( NullPointerException.class, () -> new PrefixedLogger( null ) ); + void shouldThrowWhenDelegateIsNull() { + assertThrows(NullPointerException.class, () -> new PrefixedLogger(null)); } @Test - void shouldAllowNullPrefix() - { - assertNotNull( new PrefixedLogger( null, newLoggerMock() ) ); + void shouldAllowNullPrefix() { + assertNotNull(new PrefixedLogger(null, newLoggerMock())); } @Test - void shouldDelegateIsDebugEnabled() - { - Logger delegate = newLoggerMock( true, false ); + void shouldDelegateIsDebugEnabled() { + Logger delegate = newLoggerMock(true, false); - PrefixedLogger logger = new PrefixedLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger(delegate); - assertTrue( logger.isDebugEnabled() ); - verify( delegate ).isDebugEnabled(); + assertTrue(logger.isDebugEnabled()); + verify(delegate).isDebugEnabled(); } @Test - void shouldDelegateIsTraceEnabled() - { - Logger delegate = newLoggerMock( false, true ); + void shouldDelegateIsTraceEnabled() { + Logger delegate = newLoggerMock(false, true); - PrefixedLogger logger = new PrefixedLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger(delegate); - assertTrue( logger.isTraceEnabled() ); - verify( delegate ).isTraceEnabled(); + assertTrue(logger.isTraceEnabled()); + verify(delegate).isTraceEnabled(); } @Test - void shouldNotDelegateDebugLogWhenDebugDisabled() - { + void shouldNotDelegateDebugLogWhenDebugDisabled() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( delegate ); - logger.debug( MESSAGE ); + PrefixedLogger logger = new PrefixedLogger(delegate); + logger.debug(MESSAGE); - verify( delegate, never() ).debug( anyString(), any( Object[].class ) ); + verify(delegate, never()).debug(anyString(), any(Object[].class)); } @Test - void shouldNotDelegateDebugLogWithThrowableWhenDebugDisabled() - { + void shouldNotDelegateDebugLogWithThrowableWhenDebugDisabled() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( delegate ); - logger.debug( MESSAGE, mock( Throwable.class ) ); + PrefixedLogger logger = new PrefixedLogger(delegate); + logger.debug(MESSAGE, mock(Throwable.class)); - verify( delegate, never() ).debug( anyString(), any( Throwable.class ) ); + verify(delegate, never()).debug(anyString(), any(Throwable.class)); } @Test - void shouldNotDelegateTraceLogWhenTraceDisabled() - { + void shouldNotDelegateTraceLogWhenTraceDisabled() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( delegate ); - logger.trace( MESSAGE ); + PrefixedLogger logger = new PrefixedLogger(delegate); + logger.trace(MESSAGE); - verify( delegate, never() ).trace( anyString(), any() ); + verify(delegate, never()).trace(anyString(), any()); } @Test - void shouldDelegateErrorMessageWhenNoPrefix() - { + void shouldDelegateErrorMessageWhenNoPrefix() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger(delegate); - logger.error( MESSAGE, ERROR ); + logger.error(MESSAGE, ERROR); - verify( delegate ).error( MESSAGE, ERROR ); + verify(delegate).error(MESSAGE, ERROR); } @Test - void shouldDelegateInfoMessageWhenNoPrefix() - { + void shouldDelegateInfoMessageWhenNoPrefix() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger(delegate); - logger.info( MESSAGE ); + logger.info(MESSAGE); - verify( delegate ).info( MESSAGE ); + verify(delegate).info(MESSAGE); } @Test - void shouldDelegateWarnMessageWhenNoPrefix() - { + void shouldDelegateWarnMessageWhenNoPrefix() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger(delegate); - logger.warn( MESSAGE ); + logger.warn(MESSAGE); - verify( delegate ).warn( MESSAGE ); + verify(delegate).warn(MESSAGE); } @Test - void shouldDelegateWarnMessageWithoutErrorWhenNoPrefix() - { + void shouldDelegateWarnMessageWithoutErrorWhenNoPrefix() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger(delegate); Exception cause = new Exception(); - logger.warn( MESSAGE, cause ); + logger.warn(MESSAGE, cause); - verify( delegate ).warn( MESSAGE, cause ); + verify(delegate).warn(MESSAGE, cause); } @Test - void shouldDelegateDebugMessageWhenNoPrefix() - { - Logger delegate = newLoggerMock( true, false ); - PrefixedLogger logger = new PrefixedLogger( delegate ); + void shouldDelegateDebugMessageWhenNoPrefix() { + Logger delegate = newLoggerMock(true, false); + PrefixedLogger logger = new PrefixedLogger(delegate); - logger.debug( MESSAGE ); + logger.debug(MESSAGE); - verify( delegate ).debug( MESSAGE ); + verify(delegate).debug(MESSAGE); } @Test - void shouldDelegateTraceMessageWhenNoPrefix() - { - Logger delegate = newLoggerMock( false, true ); - PrefixedLogger logger = new PrefixedLogger( delegate ); + void shouldDelegateTraceMessageWhenNoPrefix() { + Logger delegate = newLoggerMock(false, true); + PrefixedLogger logger = new PrefixedLogger(delegate); - logger.trace( MESSAGE ); + logger.trace(MESSAGE); - verify( delegate ).trace( MESSAGE ); + verify(delegate).trace(MESSAGE); } @Test - void shouldDelegateErrorMessageWithPrefix() - { + void shouldDelegateErrorMessageWithPrefix() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); + PrefixedLogger logger = new PrefixedLogger(PREFIX, delegate); - logger.error( MESSAGE, ERROR ); + logger.error(MESSAGE, ERROR); - verify( delegate ).error( "Output Hello World!", ERROR ); + verify(delegate).error("Output Hello World!", ERROR); } @Test - void shouldDelegateInfoMessageWithPrefix() - { + void shouldDelegateInfoMessageWithPrefix() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); + PrefixedLogger logger = new PrefixedLogger(PREFIX, delegate); - logger.info( MESSAGE ); + logger.info(MESSAGE); - verify( delegate ).info( "Output Hello World!" ); + verify(delegate).info("Output Hello World!"); } @Test - void shouldDelegateWarnMessageWithPrefix() - { + void shouldDelegateWarnMessageWithPrefix() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); + PrefixedLogger logger = new PrefixedLogger(PREFIX, delegate); - logger.warn( MESSAGE ); + logger.warn(MESSAGE); - verify( delegate ).warn( "Output Hello World!" ); + verify(delegate).warn("Output Hello World!"); } @Test - void shouldDelegateWarnMessageWithErrorWithPrefix() - { + void shouldDelegateWarnMessageWithErrorWithPrefix() { Logger delegate = newLoggerMock(); - PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); + PrefixedLogger logger = new PrefixedLogger(PREFIX, delegate); Exception cause = new Exception(); - logger.warn( MESSAGE, cause ); + logger.warn(MESSAGE, cause); - verify( delegate ).warn( "Output Hello World!", cause ); + verify(delegate).warn("Output Hello World!", cause); } @Test - void shouldDelegateDebugMessageWithPrefix() - { - Logger delegate = newLoggerMock( true, false ); - PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); + void shouldDelegateDebugMessageWithPrefix() { + Logger delegate = newLoggerMock(true, false); + PrefixedLogger logger = new PrefixedLogger(PREFIX, delegate); - logger.debug( MESSAGE ); + logger.debug(MESSAGE); - verify( delegate ).debug( "Output Hello World!" ); + verify(delegate).debug("Output Hello World!"); } @Test - void shouldDelegateTraceMessageWithPrefix() - { - Logger delegate = newLoggerMock( false, true ); - PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); + void shouldDelegateTraceMessageWithPrefix() { + Logger delegate = newLoggerMock(false, true); + PrefixedLogger logger = new PrefixedLogger(PREFIX, delegate); - logger.trace( MESSAGE ); + logger.trace(MESSAGE); - verify( delegate ).trace( "Output Hello World!" ); + verify(delegate).trace("Output Hello World!"); } - private static Logger newLoggerMock() - { - return newLoggerMock( false, false ); + private static Logger newLoggerMock() { + return newLoggerMock(false, false); } - private static Logger newLoggerMock( boolean debugEnabled, boolean traceEnabled ) - { - Logger logger = mock( Logger.class ); - when( logger.isDebugEnabled() ).thenReturn( debugEnabled ); - when( logger.isTraceEnabled() ).thenReturn( traceEnabled ); + private static Logger newLoggerMock(boolean debugEnabled, boolean traceEnabled) { + Logger logger = mock(Logger.class); + when(logger.isDebugEnabled()).thenReturn(debugEnabled); + when(logger.isTraceEnabled()).thenReturn(traceEnabled); return logger; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/logging/Slf4jLoggerTest.java b/driver/src/test/java/org/neo4j/driver/internal/logging/Slf4jLoggerTest.java index fce70b5832..d64637c9a0 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/logging/Slf4jLoggerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/logging/Slf4jLoggerTest.java @@ -18,109 +18,100 @@ */ package org.neo4j.driver.internal.logging; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; - import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -class Slf4jLoggerTest -{ - private final Logger logger = mock( Logger.class ); - private final Slf4jLogger slf4jLogger = new Slf4jLogger( logger ); +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; + +class Slf4jLoggerTest { + private final Logger logger = mock(Logger.class); + private final Slf4jLogger slf4jLogger = new Slf4jLogger(logger); @Test - void shouldLogErrorWithMessageAndThrowable() - { - when( logger.isErrorEnabled() ).thenReturn( true ); + void shouldLogErrorWithMessageAndThrowable() { + when(logger.isErrorEnabled()).thenReturn(true); String message = "Hello"; - IllegalArgumentException error = new IllegalArgumentException( "World" ); + IllegalArgumentException error = new IllegalArgumentException("World"); - slf4jLogger.error( message, error ); + slf4jLogger.error(message, error); - verify( logger ).error( message, error ); + verify(logger).error(message, error); } @Test - void shouldLogInfoWithMessageAndParams() - { - when( logger.isInfoEnabled() ).thenReturn( true ); + void shouldLogInfoWithMessageAndParams() { + when(logger.isInfoEnabled()).thenReturn(true); String message = "One %s, two %s, three %s"; Object[] params = {"111", "222", "333"}; - slf4jLogger.info( message, params ); + slf4jLogger.info(message, params); - verify( logger ).info( "One 111, two 222, three 333" ); + verify(logger).info("One 111, two 222, three 333"); } @Test - void shouldLogWarnWithMessageAndParams() - { - when( logger.isWarnEnabled() ).thenReturn( true ); + void shouldLogWarnWithMessageAndParams() { + when(logger.isWarnEnabled()).thenReturn(true); String message = "C for %s, d for %s"; Object[] params = {"cat", "dog"}; - slf4jLogger.warn( message, params ); + slf4jLogger.warn(message, params); - verify( logger ).warn( "C for cat, d for dog" ); + verify(logger).warn("C for cat, d for dog"); } @Test - void shouldLogWarnWithMessageAndThrowable() - { - when( logger.isWarnEnabled() ).thenReturn( true ); + void shouldLogWarnWithMessageAndThrowable() { + when(logger.isWarnEnabled()).thenReturn(true); String message = "Hello"; - RuntimeException error = new RuntimeException( "World" ); + RuntimeException error = new RuntimeException("World"); - slf4jLogger.warn( message, error ); + slf4jLogger.warn(message, error); - verify( logger ).warn( message, error ); + verify(logger).warn(message, error); } @Test - void shouldLogDebugWithMessageAndParams() - { - when( logger.isDebugEnabled() ).thenReturn( true ); + void shouldLogDebugWithMessageAndParams() { + when(logger.isDebugEnabled()).thenReturn(true); String message = "Hello%s%s!"; Object[] params = {" ", "World"}; - slf4jLogger.debug( message, params ); + slf4jLogger.debug(message, params); - verify( logger ).debug( "Hello World!" ); + verify(logger).debug("Hello World!"); } @Test - void shouldLogTraceWithMessageAndParams() - { - when( logger.isTraceEnabled() ).thenReturn( true ); + void shouldLogTraceWithMessageAndParams() { + when(logger.isTraceEnabled()).thenReturn(true); String message = "I'll be %s!"; Object[] params = {"back"}; - slf4jLogger.trace( message, params ); + slf4jLogger.trace(message, params); - verify( logger ).trace( "I'll be back!" ); + verify(logger).trace("I'll be back!"); } @Test - void shouldCheckIfDebugIsEnabled() - { - when( logger.isDebugEnabled() ).thenReturn( false ); - assertFalse( slf4jLogger.isDebugEnabled() ); + void shouldCheckIfDebugIsEnabled() { + when(logger.isDebugEnabled()).thenReturn(false); + assertFalse(slf4jLogger.isDebugEnabled()); - when( logger.isDebugEnabled() ).thenReturn( true ); - assertTrue( slf4jLogger.isDebugEnabled() ); + when(logger.isDebugEnabled()).thenReturn(true); + assertTrue(slf4jLogger.isDebugEnabled()); } @Test - void shouldCheckIfTraceIsEnabled() - { - when( logger.isTraceEnabled() ).thenReturn( false ); - assertFalse( slf4jLogger.isTraceEnabled() ); + void shouldCheckIfTraceIsEnabled() { + when(logger.isTraceEnabled()).thenReturn(false); + assertFalse(slf4jLogger.isTraceEnabled()); - when( logger.isTraceEnabled() ).thenReturn( true ); - assertTrue( slf4jLogger.isTraceEnabled() ); + when(logger.isTraceEnabled()).thenReturn(true); + assertTrue(slf4jLogger.isTraceEnabled()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/logging/Slf4jLoggingTest.java b/driver/src/test/java/org/neo4j/driver/internal/logging/Slf4jLoggingTest.java index 0d8c916585..e8cca1ca14 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/logging/Slf4jLoggingTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/logging/Slf4jLoggingTest.java @@ -18,29 +18,25 @@ */ package org.neo4j.driver.internal.logging; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.Logger; - import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertNull; -class Slf4jLoggingTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Logger; + +class Slf4jLoggingTest { @Test - void shouldCreateLoggers() - { + void shouldCreateLoggers() { Slf4jLogging logging = new Slf4jLogging(); - Logger logger = logging.getLog( "My Log" ); + Logger logger = logging.getLog("My Log"); - assertThat( logger, instanceOf( Slf4jLogger.class ) ); + assertThat(logger, instanceOf(Slf4jLogger.class)); } @Test - void shouldCheckIfAvailable() - { - assertNull( Slf4jLogging.checkAvailability() ); + void shouldCheckIfAvailable() { + assertNull(Slf4jLogging.checkAvailability()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolTest.java index 4cd2fd127e..453f85c494 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolTest.java @@ -18,9 +18,14 @@ */ package org.neo4j.driver.internal.messaging; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setProtocolVersion; + import io.netty.channel.embedded.EmbeddedChannel; import org.junit.jupiter.api.Test; - import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; @@ -28,42 +33,33 @@ import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42; import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setProtocolVersion; - -class BoltProtocolTest -{ +class BoltProtocolTest { @Test - void shouldCreateProtocolForKnownVersions() - { + void shouldCreateProtocolForKnownVersions() { assertAll( - () -> assertThat( BoltProtocol.forVersion( BoltProtocolV3.VERSION ), instanceOf( BoltProtocolV3.class ) ), - () -> assertThat( BoltProtocol.forVersion( BoltProtocolV4.VERSION ), instanceOf( BoltProtocolV4.class ) ), - () -> assertThat( BoltProtocol.forVersion( BoltProtocolV41.VERSION ), instanceOf( BoltProtocolV41.class ) ), - () -> assertThat( BoltProtocol.forVersion( BoltProtocolV42.VERSION ), instanceOf( BoltProtocolV42.class ) ), - () -> assertThat( BoltProtocol.forVersion( BoltProtocolV43.VERSION ), instanceOf( BoltProtocolV43.class ) ) - ); + () -> assertThat(BoltProtocol.forVersion(BoltProtocolV3.VERSION), instanceOf(BoltProtocolV3.class)), + () -> assertThat(BoltProtocol.forVersion(BoltProtocolV4.VERSION), instanceOf(BoltProtocolV4.class)), + () -> assertThat(BoltProtocol.forVersion(BoltProtocolV41.VERSION), instanceOf(BoltProtocolV41.class)), + () -> assertThat(BoltProtocol.forVersion(BoltProtocolV42.VERSION), instanceOf(BoltProtocolV42.class)), + () -> assertThat(BoltProtocol.forVersion(BoltProtocolV43.VERSION), instanceOf(BoltProtocolV43.class))); } @Test - void shouldThrowForUnknownVersion() - { + void shouldThrowForUnknownVersion() { assertAll( - () -> assertThrows( ClientException.class, () -> BoltProtocol.forVersion( new BoltProtocolVersion( 42, 0 ) ) ), - () -> assertThrows( ClientException.class, () -> BoltProtocol.forVersion( new BoltProtocolVersion( 142, 0 ) ) ), - () -> assertThrows( ClientException.class, () -> BoltProtocol.forVersion( new BoltProtocolVersion( -1, 0 ) ) ) - ); + () -> assertThrows( + ClientException.class, () -> BoltProtocol.forVersion(new BoltProtocolVersion(42, 0))), + () -> assertThrows( + ClientException.class, () -> BoltProtocol.forVersion(new BoltProtocolVersion(142, 0))), + () -> assertThrows( + ClientException.class, () -> BoltProtocol.forVersion(new BoltProtocolVersion(-1, 0)))); } @Test - void shouldThrowForChannelWithUnknownProtocolVersion() - { + void shouldThrowForChannelWithUnknownProtocolVersion() { EmbeddedChannel channel = new EmbeddedChannel(); - setProtocolVersion( channel, new BoltProtocolVersion( 42, 0 ) ); + setProtocolVersion(channel, new BoltProtocolVersion(42, 0)); - assertThrows( ClientException.class, () -> BoltProtocol.forChannel( channel ) ); + assertThrows(ClientException.class, () -> BoltProtocol.forChannel(channel)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolVersionTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolVersionTest.java index cdf4caf475..aa374e699a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolVersionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolVersionTest.java @@ -18,93 +18,76 @@ */ package org.neo4j.driver.internal.messaging; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class BoltProtocolVersionTest -{ +class BoltProtocolVersionTest { - @ParameterizedTest( name = "V{0}.{1}" ) - @CsvSource( {"3, 0", "4, 0", "4, 1", "4, 2", "100, 100", "255, 255", "0, 0"} ) - void shouldParseVersion( int major, int minor ) - { - BoltProtocolVersion protocolVersion = new BoltProtocolVersion( major, minor ); + @ParameterizedTest(name = "V{0}.{1}") + @CsvSource({"3, 0", "4, 0", "4, 1", "4, 2", "100, 100", "255, 255", "0, 0"}) + void shouldParseVersion(int major, int minor) { + BoltProtocolVersion protocolVersion = new BoltProtocolVersion(major, minor); - BoltProtocolVersion testVersion = BoltProtocolVersion.fromRawBytes( protocolVersion.toInt() ); + BoltProtocolVersion testVersion = BoltProtocolVersion.fromRawBytes(protocolVersion.toInt()); - assertEquals( major, testVersion.getMajorVersion() ); - assertEquals( minor, testVersion.getMinorVersion() ); + assertEquals(major, testVersion.getMajorVersion()); + assertEquals(minor, testVersion.getMinorVersion()); } - @ParameterizedTest( name = "V{0}.{1} comparedTo V{2}.{3}" ) - @CsvSource( {"1, 3, 25, 21, -1", "4, 0, 4, 0, 0", "4, 1, 4, 0, 1", "0, 1, 0, 2, -1"} ) - void shouldCompareTo(int majorA, int minorA, int majorB, int minorB, int expectedResult) - { - BoltProtocolVersion versionA = new BoltProtocolVersion( majorA, minorA ); - BoltProtocolVersion versionB = new BoltProtocolVersion( majorB, minorB ); - - assertEquals( expectedResult, versionA.compareTo( versionB ) ); + @ParameterizedTest(name = "V{0}.{1} comparedTo V{2}.{3}") + @CsvSource({"1, 3, 25, 21, -1", "4, 0, 4, 0, 0", "4, 1, 4, 0, 1", "0, 1, 0, 2, -1"}) + void shouldCompareTo(int majorA, int minorA, int majorB, int minorB, int expectedResult) { + BoltProtocolVersion versionA = new BoltProtocolVersion(majorA, minorA); + BoltProtocolVersion versionB = new BoltProtocolVersion(majorB, minorB); + assertEquals(expectedResult, versionA.compareTo(versionB)); } - @ParameterizedTest( name = "V{0}.{1} toIntRange V{2}.{3}") + @ParameterizedTest(name = "V{0}.{1} toIntRange V{2}.{3}") @CsvSource({ - "1, 0, 1, 0, 0x000001", - "4, 3, 4, 2, 0x010304", - "4, 3, 4, 1, 0x020304", - "4, 3, 4, 0, 0x030304", - "100, 100, 100, 0, 0x646464", - "255, 255, 255, 0, 0xFFFFFF" - } ) - void shouldOutputCorrectIntRange(int majorA, int minorA, int majorB, int minorB, int expectedResult) - { - BoltProtocolVersion versionA = new BoltProtocolVersion( majorA, minorA ); - BoltProtocolVersion versionB = new BoltProtocolVersion( majorB, minorB ); - - assertEquals( expectedResult, versionA.toIntRange( versionB ) ); + "1, 0, 1, 0, 0x000001", + "4, 3, 4, 2, 0x010304", + "4, 3, 4, 1, 0x020304", + "4, 3, 4, 0, 0x030304", + "100, 100, 100, 0, 0x646464", + "255, 255, 255, 0, 0xFFFFFF" + }) + void shouldOutputCorrectIntRange(int majorA, int minorA, int majorB, int minorB, int expectedResult) { + BoltProtocolVersion versionA = new BoltProtocolVersion(majorA, minorA); + BoltProtocolVersion versionB = new BoltProtocolVersion(majorB, minorB); + + assertEquals(expectedResult, versionA.toIntRange(versionB)); } - @ParameterizedTest( name = "V{0}.{1} toIntRange V{2}.{3}") - @CsvSource({ - "1, 0, 2, 0", - "2, 0, 1, 0", - "4, 3, 4, 5", - "4, 6, 3, 7", - "3, 7, 4, 6", - "255, 255, 100, 0" - } ) - void shouldThrowsIllegalArgumentExceptionForIncorrectIntRange(int majorA, int minorA, int majorB, int minorB) - { - BoltProtocolVersion versionA = new BoltProtocolVersion( majorA, minorA ); - BoltProtocolVersion versionB = new BoltProtocolVersion( majorB, minorB ); - - assertThrows( IllegalArgumentException.class, () -> versionA.toIntRange( versionB )); + @ParameterizedTest(name = "V{0}.{1} toIntRange V{2}.{3}") + @CsvSource({"1, 0, 2, 0", "2, 0, 1, 0", "4, 3, 4, 5", "4, 6, 3, 7", "3, 7, 4, 6", "255, 255, 100, 0"}) + void shouldThrowsIllegalArgumentExceptionForIncorrectIntRange(int majorA, int minorA, int majorB, int minorB) { + BoltProtocolVersion versionA = new BoltProtocolVersion(majorA, minorA); + BoltProtocolVersion versionB = new BoltProtocolVersion(majorB, minorB); + + assertThrows(IllegalArgumentException.class, () -> versionA.toIntRange(versionB)); } @Test - void shouldOutputCorrectLongFormatForMajorVersionOnly() - { - BoltProtocolVersion version = new BoltProtocolVersion( 4, 0 ); - assertEquals( 4L, version.toInt() ); + void shouldOutputCorrectLongFormatForMajorVersionOnly() { + BoltProtocolVersion version = new BoltProtocolVersion(4, 0); + assertEquals(4L, version.toInt()); } @Test - void shouldOutputCorrectLongFormatForMajorAndMinorVersion() - { - BoltProtocolVersion version = new BoltProtocolVersion( 4, 1 ); - assertEquals( 260L, version.toInt() ); + void shouldOutputCorrectLongFormatForMajorAndMinorVersion() { + BoltProtocolVersion version = new BoltProtocolVersion(4, 1); + assertEquals(260L, version.toInt()); } @Test - void shouldOutputFormattedString() - { - BoltProtocolVersion version = new BoltProtocolVersion( 4, 1 ); + void shouldOutputFormattedString() { + BoltProtocolVersion version = new BoltProtocolVersion(4, 1); - assertEquals( "4.1", version.toString() ); + assertEquals("4.1", version.toString()); } - -} \ No newline at end of file +} diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/MessageFormatTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/MessageFormatTest.java index 109045f867..45c216e97a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/MessageFormatTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/MessageFormatTest.java @@ -18,15 +18,31 @@ */ package org.neo4j.driver.internal.messaging; +import static java.util.Arrays.asList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; +import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; + import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.embedded.EmbeddedChannel; -import org.junit.jupiter.api.Test; - import java.io.IOException; import java.util.HashMap; import java.util.List; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Value; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.async.connection.BoltProtocolUtil; @@ -43,161 +59,125 @@ import org.neo4j.driver.internal.util.messaging.KnowledgeableMessageFormat; import org.neo4j.driver.internal.util.messaging.MemorizingInboundMessageDispatcher; -import static java.util.Arrays.asList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.startsWith; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.messageDispatcher; -import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; - -class MessageFormatTest -{ +class MessageFormatTest { public MessageFormat format = new MessageFormatV3(); @Test - void shouldUnpackAllResponses() throws Throwable - { - assertSerializes( new FailureMessage( "Hello", "World!" ) ); - assertSerializes( IgnoredMessage.IGNORED ); - assertSerializes( new RecordMessage( new Value[]{value( 1337L )} ) ); - assertSerializes( new SuccessMessage( new HashMap<>() ) ); + void shouldUnpackAllResponses() throws Throwable { + assertSerializes(new FailureMessage("Hello", "World!")); + assertSerializes(IgnoredMessage.IGNORED); + assertSerializes(new RecordMessage(new Value[] {value(1337L)})); + assertSerializes(new SuccessMessage(new HashMap<>())); } @Test - void shouldPackUnpackValidValues() throws Throwable - { - assertSerializesValue( value( parameters( "cat", null, "dog", null ) ) ); - assertSerializesValue( value( parameters( "k", 12, "a", "banana" ) ) ); - assertSerializesValue( value( asList( "k", 12, "a", "banana" ) ) ); + void shouldPackUnpackValidValues() throws Throwable { + assertSerializesValue(value(parameters("cat", null, "dog", null))); + assertSerializesValue(value(parameters("k", 12, "a", "banana"))); + assertSerializesValue(value(asList("k", 12, "a", "banana"))); } @Test - void shouldUnpackNodeRelationshipAndPath() throws Throwable - { + void shouldUnpackNodeRelationshipAndPath() throws Throwable { // Given - assertOnlyDeserializesValue( emptyNodeValue() ); - assertOnlyDeserializesValue( filledNodeValue() ); - assertOnlyDeserializesValue( emptyRelationshipValue() ); - assertOnlyDeserializesValue( filledRelationshipValue() ); - assertOnlyDeserializesValue( emptyPathValue() ); - assertOnlyDeserializesValue( filledPathValue() ); + assertOnlyDeserializesValue(emptyNodeValue()); + assertOnlyDeserializesValue(filledNodeValue()); + assertOnlyDeserializesValue(emptyRelationshipValue()); + assertOnlyDeserializesValue(filledRelationshipValue()); + assertOnlyDeserializesValue(emptyPathValue()); + assertOnlyDeserializesValue(filledPathValue()); } - @Test - void shouldGiveHelpfulErrorOnMalformedNodeStruct() throws Throwable - { + void shouldGiveHelpfulErrorOnMalformedNodeStruct() throws Throwable { // Given ChunkAwareByteBufOutput output = new ChunkAwareByteBufOutput(); ByteBuf buf = Unpooled.buffer(); - output.start( buf ); - PackStream.Packer packer = new PackStream.Packer( output ); + output.start(buf); + PackStream.Packer packer = new PackStream.Packer(output); - packer.packStructHeader( 1, RecordMessage.SIGNATURE ); - packer.packListHeader( 1 ); - packer.packStructHeader( 0, CommonValueUnpacker.NODE ); + packer.packStructHeader(1, RecordMessage.SIGNATURE); + packer.packListHeader(1); + packer.packStructHeader(0, CommonValueUnpacker.NODE); output.stop(); - BoltProtocolUtil.writeMessageBoundary( buf ); + BoltProtocolUtil.writeMessageBoundary(buf); // Expect - ClientException error = assertThrows( ClientException.class, () -> unpack( buf, newEmbeddedChannel() ) ); - assertThat( error.getMessage(), startsWith( - "Invalid message received, serialized NODE structures should have 3 fields, " + - "received NODE structure has 0 fields." ) ); + ClientException error = assertThrows(ClientException.class, () -> unpack(buf, newEmbeddedChannel())); + assertThat( + error.getMessage(), + startsWith("Invalid message received, serialized NODE structures should have 3 fields, " + + "received NODE structure has 0 fields.")); } - private void assertSerializesValue( Value value ) throws Throwable - { - assertSerializes( new RecordMessage( new Value[]{value} ) ); + private void assertSerializesValue(Value value) throws Throwable { + assertSerializes(new RecordMessage(new Value[] {value})); } - private void assertSerializes( Message message ) throws Throwable - { - EmbeddedChannel channel = newEmbeddedChannel( new KnowledgeableMessageFormat() ); + private void assertSerializes(Message message) throws Throwable { + EmbeddedChannel channel = newEmbeddedChannel(new KnowledgeableMessageFormat()); - ByteBuf packed = pack( message, channel ); - Message unpackedMessage = unpack( packed, channel ); + ByteBuf packed = pack(message, channel); + Message unpackedMessage = unpack(packed, channel); - assertEquals( message, unpackedMessage ); + assertEquals(message, unpackedMessage); } - private EmbeddedChannel newEmbeddedChannel() - { - return newEmbeddedChannel( format ); + private EmbeddedChannel newEmbeddedChannel() { + return newEmbeddedChannel(format); } - private EmbeddedChannel newEmbeddedChannel( MessageFormat format ) - { + private EmbeddedChannel newEmbeddedChannel(MessageFormat format) { EmbeddedChannel channel = new EmbeddedChannel(); - setMessageDispatcher( channel, new MemorizingInboundMessageDispatcher( channel, DEV_NULL_LOGGING ) ); - new ChannelPipelineBuilderImpl().build( format, channel.pipeline(), DEV_NULL_LOGGING ); + setMessageDispatcher(channel, new MemorizingInboundMessageDispatcher(channel, DEV_NULL_LOGGING)); + new ChannelPipelineBuilderImpl().build(format, channel.pipeline(), DEV_NULL_LOGGING); return channel; } - private ByteBuf pack( Message message, EmbeddedChannel channel ) - { - assertTrue( channel.writeOutbound( message ) ); + private ByteBuf pack(Message message, EmbeddedChannel channel) { + assertTrue(channel.writeOutbound(message)); - ByteBuf[] packedMessages = channel.outboundMessages() - .stream() - .map( msg -> (ByteBuf) msg ) - .toArray( ByteBuf[]::new ); + ByteBuf[] packedMessages = + channel.outboundMessages().stream().map(msg -> (ByteBuf) msg).toArray(ByteBuf[]::new); - return Unpooled.wrappedBuffer( packedMessages ); + return Unpooled.wrappedBuffer(packedMessages); } - private Message unpack( ByteBuf packed, EmbeddedChannel channel ) throws Throwable - { - channel.writeInbound( packed ); + private Message unpack(ByteBuf packed, EmbeddedChannel channel) throws Throwable { + channel.writeInbound(packed); - InboundMessageDispatcher dispatcher = messageDispatcher( channel ); + InboundMessageDispatcher dispatcher = messageDispatcher(channel); MemorizingInboundMessageDispatcher memorizingDispatcher = ((MemorizingInboundMessageDispatcher) dispatcher); Throwable error = memorizingDispatcher.currentError(); - if ( error != null ) - { + if (error != null) { throw error; } List unpackedMessages = memorizingDispatcher.messages(); - assertEquals( 1, unpackedMessages.size() ); - return unpackedMessages.get( 0 ); + assertEquals(1, unpackedMessages.size()); + return unpackedMessages.get(0); } - private void assertOnlyDeserializesValue( Value value ) throws Throwable - { - RecordMessage message = new RecordMessage( new Value[]{value} ); - ByteBuf packed = knowledgeablePack( message ); + private void assertOnlyDeserializesValue(Value value) throws Throwable { + RecordMessage message = new RecordMessage(new Value[] {value}); + ByteBuf packed = knowledgeablePack(message); EmbeddedChannel channel = newEmbeddedChannel(); - Message unpackedMessage = unpack( packed, channel ); + Message unpackedMessage = unpack(packed, channel); - assertEquals( message, unpackedMessage ); + assertEquals(message, unpackedMessage); } - private ByteBuf knowledgeablePack( Message message ) throws IOException - { - EmbeddedChannel channel = newEmbeddedChannel( new KnowledgeableMessageFormat() ); - assertTrue( channel.writeOutbound( message ) ); + private ByteBuf knowledgeablePack(Message message) throws IOException { + EmbeddedChannel channel = newEmbeddedChannel(new KnowledgeableMessageFormat()); + assertTrue(channel.writeOutbound(message)); - ByteBuf[] packedMessages = channel.outboundMessages() - .stream() - .map( msg -> (ByteBuf) msg ) - .toArray( ByteBuf[]::new ); + ByteBuf[] packedMessages = + channel.outboundMessages().stream().map(msg -> (ByteBuf) msg).toArray(ByteBuf[]::new); - return Unpooled.wrappedBuffer( packedMessages ); + return Unpooled.wrappedBuffer(packedMessages); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoderTest.java index f2c6355412..a8ba63f028 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/BeginMessageEncoderTest.java @@ -18,18 +18,24 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InOrder; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; import java.time.Duration; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InOrder; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Value; @@ -37,61 +43,48 @@ import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.BeginMessage; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; - -class BeginMessageEncoderTest -{ +class BeginMessageEncoderTest { private final BeginMessageEncoder encoder = new BeginMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @ParameterizedTest - @MethodSource( "arguments" ) - void shouldEncodeBeginMessage( AccessMode mode, String impersonatedUser ) throws Exception - { - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx42" ); + @MethodSource("arguments") + void shouldEncodeBeginMessage(AccessMode mode, String impersonatedUser) throws Exception { + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx42"); - Map txMetadata = new HashMap<>(); - txMetadata.put( "hello", value( "world" ) ); - txMetadata.put( "answer", value( 42 ) ); + Map txMetadata = new HashMap<>(); + txMetadata.put("hello", value("world")); + txMetadata.put("answer", value(42)); - Duration txTimeout = Duration.ofSeconds( 1 ); + Duration txTimeout = Duration.ofSeconds(1); - encoder.encode( new BeginMessage( bookmark, txTimeout, txMetadata, mode, defaultDatabase(), impersonatedUser ), packer ); + encoder.encode( + new BeginMessage(bookmark, txTimeout, txMetadata, mode, defaultDatabase(), impersonatedUser), packer); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, BeginMessage.SIGNATURE ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, BeginMessage.SIGNATURE); - Map expectedMetadata = new HashMap<>(); - expectedMetadata.put( "bookmarks", value( bookmark.values() ) ); - expectedMetadata.put( "tx_timeout", value( 1000 ) ); - expectedMetadata.put( "tx_metadata", value( txMetadata ) ); - if ( mode == READ ) - { - expectedMetadata.put( "mode", value( "r" ) ); + Map expectedMetadata = new HashMap<>(); + expectedMetadata.put("bookmarks", value(bookmark.values())); + expectedMetadata.put("tx_timeout", value(1000)); + expectedMetadata.put("tx_metadata", value(txMetadata)); + if (mode == READ) { + expectedMetadata.put("mode", value("r")); } - if ( impersonatedUser != null ) - { - expectedMetadata.put( "imp_user", value( impersonatedUser ) ); + if (impersonatedUser != null) { + expectedMetadata.put("imp_user", value(impersonatedUser)); } - order.verify( packer ).pack( expectedMetadata ); + order.verify(packer).pack(expectedMetadata); } - private static Stream arguments() - { - return Arrays.stream( AccessMode.values() ) - .flatMap( accessMode -> Stream.of( Arguments.of( accessMode, "user" ), Arguments.of( accessMode, null ) ) ); + private static Stream arguments() { + return Arrays.stream(AccessMode.values()) + .flatMap(accessMode -> Stream.of(Arguments.of(accessMode, "user"), Arguments.of(accessMode, null))); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( RESET, packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(RESET, packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/CommitMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/CommitMessageEncoderTest.java index 7307edd677..9155a7020c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/CommitMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/CommitMessageEncoderTest.java @@ -18,33 +18,29 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.messaging.ValuePacker; -import org.neo4j.driver.internal.messaging.request.CommitMessage; - import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; -class CommitMessageEncoderTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.messaging.ValuePacker; +import org.neo4j.driver.internal.messaging.request.CommitMessage; + +class CommitMessageEncoderTest { private final CommitMessageEncoder encoder = new CommitMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldEncodeCommitMessage() throws Exception - { - encoder.encode( COMMIT, packer ); + void shouldEncodeCommitMessage() throws Exception { + encoder.encode(COMMIT, packer); - verify( packer ).packStructHeader( 0, CommitMessage.SIGNATURE ); + verify(packer).packStructHeader(0, CommitMessage.SIGNATURE); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( DISCARD_ALL, packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(DISCARD_ALL, packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/DiscardAllMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/DiscardAllMessageEncoderTest.java index 3cfba65f8e..f0b5fe3576 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/DiscardAllMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/DiscardAllMessageEncoderTest.java @@ -18,32 +18,28 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.DiscardAllMessage; import org.neo4j.driver.internal.messaging.request.DiscardMessage; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -class DiscardAllMessageEncoderTest -{ +class DiscardAllMessageEncoderTest { private final DiscardAllMessageEncoder encoder = new DiscardAllMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldEncodeDiscardAllMessage() throws Exception - { - encoder.encode( DiscardAllMessage.DISCARD_ALL, packer ); + void shouldEncodeDiscardAllMessage() throws Exception { + encoder.encode(DiscardAllMessage.DISCARD_ALL, packer); - verify( packer ).packStructHeader( 0, DiscardAllMessage.SIGNATURE ); + verify(packer).packStructHeader(0, DiscardAllMessage.SIGNATURE); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( new DiscardMessage( 100, 200 ), packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(new DiscardMessage(100, 200), packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/DiscardMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/DiscardMessageEncoderTest.java index 9c1025133b..4162d81945 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/DiscardMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/DiscardMessageEncoderTest.java @@ -18,71 +18,64 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.messaging.request.DiscardMessage.newDiscardAllMessage; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.mockito.InOrder; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.DiscardAllMessage; import org.neo4j.driver.internal.messaging.request.DiscardMessage; -import org.neo4j.driver.Value; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.messaging.request.DiscardMessage.newDiscardAllMessage; -class DiscardMessageEncoderTest -{ +class DiscardMessageEncoderTest { private final DiscardMessageEncoder encoder = new DiscardMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldDiscardAllCorrectly() throws Throwable - { - encoder.encode( newDiscardAllMessage( -1 ), packer ); + void shouldDiscardAllCorrectly() throws Throwable { + encoder.encode(newDiscardAllMessage(-1), packer); - Map meta = new HashMap<>(); - meta.put( "n", value( -1 ) ); + Map meta = new HashMap<>(); + meta.put("n", value(-1)); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, DiscardMessage.SIGNATURE ); - order.verify( packer ).pack( meta ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, DiscardMessage.SIGNATURE); + order.verify(packer).pack(meta); } @Test - void shouldEncodeDiscardMessage() throws Exception - { - encoder.encode( new DiscardMessage( 100, 200 ), packer ); + void shouldEncodeDiscardMessage() throws Exception { + encoder.encode(new DiscardMessage(100, 200), packer); - Map meta = new HashMap<>(); - meta.put( "n", value( 100 ) ); - meta.put( "qid", value( 200 ) ); + Map meta = new HashMap<>(); + meta.put("n", value(100)); + meta.put("qid", value(200)); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, DiscardMessage.SIGNATURE ); - order.verify( packer ).pack( meta ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, DiscardMessage.SIGNATURE); + order.verify(packer).pack(meta); } @Test - void shouldAvoidQueryId() throws Throwable - { - encoder.encode( new DiscardMessage( 100, -1 ), packer ); + void shouldAvoidQueryId() throws Throwable { + encoder.encode(new DiscardMessage(100, -1), packer); - Map meta = new HashMap<>(); - meta.put( "n", value( 100 ) ); + Map meta = new HashMap<>(); + meta.put("n", value(100)); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, DiscardMessage.SIGNATURE ); - order.verify( packer ).pack( meta ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, DiscardMessage.SIGNATURE); + order.verify(packer).pack(meta); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( DiscardAllMessage.DISCARD_ALL, packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(DiscardAllMessage.DISCARD_ALL, packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/GoodbyeMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/GoodbyeMessageEncoderTest.java index 83c532b2ee..d9c0db29e3 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/GoodbyeMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/GoodbyeMessageEncoderTest.java @@ -18,33 +18,29 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.messaging.ValuePacker; -import org.neo4j.driver.internal.messaging.request.GoodbyeMessage; - import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; -class GoodbyeMessageEncoderTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.messaging.ValuePacker; +import org.neo4j.driver.internal.messaging.request.GoodbyeMessage; + +class GoodbyeMessageEncoderTest { private final GoodbyeMessageEncoder encoder = new GoodbyeMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldEncodeGoodbyeMessage() throws Exception - { - encoder.encode( GOODBYE, packer ); + void shouldEncodeGoodbyeMessage() throws Exception { + encoder.encode(GOODBYE, packer); - verify( packer ).packStructHeader( 0, GoodbyeMessage.SIGNATURE ); + verify(packer).packStructHeader(0, GoodbyeMessage.SIGNATURE); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( DISCARD_ALL, packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(DISCARD_ALL, packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoderTest.java index ae3a62e52b..1577c593a3 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/HelloMessageEncoderTest.java @@ -18,68 +18,62 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.mockito.InOrder; import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.HelloMessage; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; - -class HelloMessageEncoderTest -{ +class HelloMessageEncoderTest { private final HelloMessageEncoder encoder = new HelloMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldEncodeHelloMessage() throws Exception - { - Map authToken = new HashMap<>(); - authToken.put( "username", value( "bob" ) ); - authToken.put( "password", value( "secret" ) ); + void shouldEncodeHelloMessage() throws Exception { + Map authToken = new HashMap<>(); + authToken.put("username", value("bob")); + authToken.put("password", value("secret")); - encoder.encode( new HelloMessage( "MyDriver", authToken, null ), packer ); + encoder.encode(new HelloMessage("MyDriver", authToken, null), packer); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, HelloMessage.SIGNATURE ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, HelloMessage.SIGNATURE); - Map expectedMetadata = new HashMap<>( authToken ); - expectedMetadata.put( "user_agent", value( "MyDriver" ) ); - order.verify( packer ).pack( expectedMetadata ); + Map expectedMetadata = new HashMap<>(authToken); + expectedMetadata.put("user_agent", value("MyDriver")); + order.verify(packer).pack(expectedMetadata); } @Test - void shouldEncodeHelloMessageWithRoutingContext() throws Exception - { - Map authToken = new HashMap<>(); - authToken.put( "username", value( "bob" ) ); - authToken.put( "password", value( "secret" ) ); + void shouldEncodeHelloMessageWithRoutingContext() throws Exception { + Map authToken = new HashMap<>(); + authToken.put("username", value("bob")); + authToken.put("password", value("secret")); - Map routingContext = new HashMap<>(); - routingContext.put( "policy", "eu-fast" ); + Map routingContext = new HashMap<>(); + routingContext.put("policy", "eu-fast"); - encoder.encode( new HelloMessage( "MyDriver", authToken, routingContext ), packer ); + encoder.encode(new HelloMessage("MyDriver", authToken, routingContext), packer); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, HelloMessage.SIGNATURE ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, HelloMessage.SIGNATURE); - Map expectedMetadata = new HashMap<>( authToken ); - expectedMetadata.put( "user_agent", value( "MyDriver" ) ); - expectedMetadata.put( "routing", value( routingContext ) ); - order.verify( packer ).pack( expectedMetadata ); + Map expectedMetadata = new HashMap<>(authToken); + expectedMetadata.put("user_agent", value("MyDriver")); + expectedMetadata.put("routing", value(routingContext)); + order.verify(packer).pack(expectedMetadata); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( PULL_ALL, packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(PULL_ALL, packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/PullAllMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/PullAllMessageEncoderTest.java index 6f46ec490b..74c095305d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/PullAllMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/PullAllMessageEncoderTest.java @@ -18,32 +18,28 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.PullAllMessage; import org.neo4j.driver.internal.messaging.request.PullMessage; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -class PullAllMessageEncoderTest -{ +class PullAllMessageEncoderTest { private final PullAllMessageEncoder encoder = new PullAllMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldEncodePullAllMessage() throws Exception - { - encoder.encode( PullAllMessage.PULL_ALL, packer ); + void shouldEncodePullAllMessage() throws Exception { + encoder.encode(PullAllMessage.PULL_ALL, packer); - verify( packer ).packStructHeader( 0, PullAllMessage.SIGNATURE ); + verify(packer).packStructHeader(0, PullAllMessage.SIGNATURE); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( new PullMessage( 100, 200 ), packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(new PullMessage(100, 200), packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/PullMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/PullMessageEncoderTest.java index 51b1624989..c5355795a7 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/PullMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/PullMessageEncoderTest.java @@ -18,70 +18,63 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.Values.value; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.mockito.InOrder; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.PullAllMessage; import org.neo4j.driver.internal.messaging.request.PullMessage; -import org.neo4j.driver.Value; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.Values.value; -class PullMessageEncoderTest -{ +class PullMessageEncoderTest { private final PullMessageEncoder encoder = new PullMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldSendPullAllCorrectly() throws Throwable - { - encoder.encode( PullMessage.PULL_ALL, packer ); + void shouldSendPullAllCorrectly() throws Throwable { + encoder.encode(PullMessage.PULL_ALL, packer); - Map meta = new HashMap<>(); - meta.put( "n", value( -1 ) ); + Map meta = new HashMap<>(); + meta.put("n", value(-1)); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, PullMessage.SIGNATURE ); - order.verify( packer ).pack( meta ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, PullMessage.SIGNATURE); + order.verify(packer).pack(meta); } @Test - void shouldEncodePullMessage() throws Exception - { - encoder.encode( new PullMessage( 100, 200 ), packer ); + void shouldEncodePullMessage() throws Exception { + encoder.encode(new PullMessage(100, 200), packer); - Map meta = new HashMap<>(); - meta.put( "n", value( 100 ) ); - meta.put( "qid", value( 200 ) ); + Map meta = new HashMap<>(); + meta.put("n", value(100)); + meta.put("qid", value(200)); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, PullMessage.SIGNATURE ); - order.verify( packer ).pack( meta ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, PullMessage.SIGNATURE); + order.verify(packer).pack(meta); } @Test - void shouldAvoidQueryId() throws Exception - { - encoder.encode( new PullMessage( 100, -1 ), packer ); + void shouldAvoidQueryId() throws Exception { + encoder.encode(new PullMessage(100, -1), packer); - Map meta = new HashMap<>(); - meta.put( "n", value( 100 ) ); + Map meta = new HashMap<>(); + meta.put("n", value(100)); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 1, PullMessage.SIGNATURE ); - order.verify( packer ).pack( meta ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(1, PullMessage.SIGNATURE); + order.verify(packer).pack(meta); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( PullAllMessage.PULL_ALL, packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(PullAllMessage.PULL_ALL, packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/ResetMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/ResetMessageEncoderTest.java index 685e4122cc..8ed8a289e5 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/ResetMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/ResetMessageEncoderTest.java @@ -18,33 +18,31 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import org.junit.jupiter.api.Test; import org.neo4j.driver.Query; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.ResetMessage; import org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -class ResetMessageEncoderTest -{ +class ResetMessageEncoderTest { private final ResetMessageEncoder encoder = new ResetMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldEncodeResetMessage() throws Exception - { - encoder.encode( ResetMessage.RESET, packer ); + void shouldEncodeResetMessage() throws Exception { + encoder.encode(ResetMessage.RESET, packer); - verify( packer ).packStructHeader( 0, ResetMessage.SIGNATURE ); + verify(packer).packStructHeader(0, ResetMessage.SIGNATURE); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( RunWithMetadataMessage.unmanagedTxRunMessage( new Query( "RETURN 2" ) ), packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows( + IllegalArgumentException.class, + () -> encoder.encode(RunWithMetadataMessage.unmanagedTxRunMessage(new Query("RETURN 2")), packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RollbackMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RollbackMessageEncoderTest.java index 4dac463a8b..9724b24b49 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RollbackMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RollbackMessageEncoderTest.java @@ -18,33 +18,29 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.messaging.ValuePacker; -import org.neo4j.driver.internal.messaging.request.RollbackMessage; - import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; -class RollbackMessageEncoderTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.messaging.ValuePacker; +import org.neo4j.driver.internal.messaging.request.RollbackMessage; + +class RollbackMessageEncoderTest { private final RollbackMessageEncoder encoder = new RollbackMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @Test - void shouldEncodeRollbackMessage() throws Exception - { - encoder.encode( ROLLBACK, packer ); + void shouldEncodeRollbackMessage() throws Exception { + encoder.encode(ROLLBACK, packer); - verify( packer ).packStructHeader( 0, RollbackMessage.SIGNATURE ); + verify(packer).packStructHeader(0, RollbackMessage.SIGNATURE); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( RESET, packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(RESET, packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoderTest.java index 76aa007700..b6eceee9c0 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoderTest.java @@ -18,16 +18,20 @@ */ package org.neo4j.driver.internal.messaging.encode; +import static java.util.Collections.emptyList; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.Values.value; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.NullSource; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.InOrder; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalBookmark; @@ -35,64 +39,53 @@ import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.RouteMessage; -import static java.util.Collections.emptyList; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.Values.value; - -class RouteMessageEncoderTest -{ - private final ValuePacker packer = mock( ValuePacker.class ); +class RouteMessageEncoderTest { + private final ValuePacker packer = mock(ValuePacker.class); private final RouteMessageEncoder encoder = new RouteMessageEncoder(); - @ParameterizedTest - @ValueSource(strings = { "neo4j"}) + @ValueSource(strings = {"neo4j"}) @NullSource - void shouldEncodeRouteMessage(String databaseName) throws IOException - { + void shouldEncodeRouteMessage(String databaseName) throws IOException { Map routingContext = getRoutingContext(); - encoder.encode( new RouteMessage( getRoutingContext(), null, databaseName, null ), packer ); + encoder.encode(new RouteMessage(getRoutingContext(), null, databaseName, null), packer); - InOrder inOrder = inOrder( packer ); + InOrder inOrder = inOrder(packer); - inOrder.verify( packer ).packStructHeader( 3, (byte) 0x66 ); - inOrder.verify( packer ).pack( routingContext ); - inOrder.verify( packer ).pack( value( emptyList() ) ); - inOrder.verify( packer ).pack( databaseName ); + inOrder.verify(packer).packStructHeader(3, (byte) 0x66); + inOrder.verify(packer).pack(routingContext); + inOrder.verify(packer).pack(value(emptyList())); + inOrder.verify(packer).pack(databaseName); } @ParameterizedTest - @ValueSource(strings = { "neo4j"}) + @ValueSource(strings = {"neo4j"}) @NullSource - void shouldEncodeRouteMessageWithBookmark(String databaseName) throws IOException - { + void shouldEncodeRouteMessageWithBookmark(String databaseName) throws IOException { Map routingContext = getRoutingContext(); - Bookmark bookmark = InternalBookmark.parse( "somebookmark" ); + Bookmark bookmark = InternalBookmark.parse("somebookmark"); - encoder.encode( new RouteMessage( getRoutingContext(), bookmark, databaseName, null ), packer ); + encoder.encode(new RouteMessage(getRoutingContext(), bookmark, databaseName, null), packer); - InOrder inOrder = inOrder( packer ); + InOrder inOrder = inOrder(packer); - inOrder.verify( packer ).packStructHeader( 3, (byte) 0x66 ); - inOrder.verify( packer ).pack( routingContext ); - inOrder.verify( packer ).pack( value( bookmark.values() ) ); - inOrder.verify( packer ).pack( databaseName ); + inOrder.verify(packer).packStructHeader(3, (byte) 0x66); + inOrder.verify(packer).pack(routingContext); + inOrder.verify(packer).pack(value(bookmark.values())); + inOrder.verify(packer).pack(databaseName); } @Test - void shouldThrowIllegalArgumentIfMessageIsNotRouteMessage() - { - Message message = mock( Message.class ); + void shouldThrowIllegalArgumentIfMessageIsNotRouteMessage() { + Message message = mock(Message.class); - assertThrows(IllegalArgumentException.class, () -> encoder.encode( message, packer )); + assertThrows(IllegalArgumentException.class, () -> encoder.encode(message, packer)); } - private Map getRoutingContext() { + private Map getRoutingContext() { Map routingContext = new HashMap<>(); - routingContext.put( "ip", value( "127.0.0.1" ) ); + routingContext.put("ip", value("127.0.0.1")); return routingContext; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoderTest.java index f90da33e62..4ce1dbe1ae 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RunWithMetadataMessageEncoderTest.java @@ -18,15 +18,23 @@ */ package org.neo4j.driver.internal.messaging.encode; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.mockito.InOrder; +import static java.util.Collections.singletonMap; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; import java.time.Duration; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockito.InOrder; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; @@ -35,59 +43,46 @@ import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage; -import static java.util.Collections.singletonMap; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; - -class RunWithMetadataMessageEncoderTest -{ +class RunWithMetadataMessageEncoderTest { private final RunWithMetadataMessageEncoder encoder = new RunWithMetadataMessageEncoder(); - private final ValuePacker packer = mock( ValuePacker.class ); + private final ValuePacker packer = mock(ValuePacker.class); @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldEncodeRunWithMetadataMessage( AccessMode mode ) throws Exception - { - Map params = singletonMap( "answer", value( 42 ) ); + @EnumSource(AccessMode.class) + void shouldEncodeRunWithMetadataMessage(AccessMode mode) throws Exception { + Map params = singletonMap("answer", value(42)); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx999" ); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx999"); - Map txMetadata = new HashMap<>(); - txMetadata.put( "key1", value( "value1" ) ); - txMetadata.put( "key2", value( 1, 2, 3, 4, 5 ) ); - txMetadata.put( "key3", value( true ) ); + Map txMetadata = new HashMap<>(); + txMetadata.put("key1", value("value1")); + txMetadata.put("key2", value(1, 2, 3, 4, 5)); + txMetadata.put("key3", value(true)); - Duration txTimeout = Duration.ofMillis( 42 ); + Duration txTimeout = Duration.ofMillis(42); - Query query = new Query( "RETURN $answer", value( params ) ); - encoder.encode( autoCommitTxRunMessage( query, txTimeout, txMetadata, defaultDatabase(), mode, bookmark, null ), packer ); + Query query = new Query("RETURN $answer", value(params)); + encoder.encode( + autoCommitTxRunMessage(query, txTimeout, txMetadata, defaultDatabase(), mode, bookmark, null), packer); - InOrder order = inOrder( packer ); - order.verify( packer ).packStructHeader( 3, RunWithMetadataMessage.SIGNATURE ); - order.verify( packer ).pack( "RETURN $answer" ); - order.verify( packer ).pack( params ); + InOrder order = inOrder(packer); + order.verify(packer).packStructHeader(3, RunWithMetadataMessage.SIGNATURE); + order.verify(packer).pack("RETURN $answer"); + order.verify(packer).pack(params); - Map expectedMetadata = new HashMap<>(); - expectedMetadata.put( "bookmarks", value( bookmark.values() ) ); - expectedMetadata.put( "tx_timeout", value( 42 ) ); - expectedMetadata.put( "tx_metadata", value( txMetadata ) ); - if ( mode == READ ) - { - expectedMetadata.put( "mode", value( "r" ) ); + Map expectedMetadata = new HashMap<>(); + expectedMetadata.put("bookmarks", value(bookmark.values())); + expectedMetadata.put("tx_timeout", value(42)); + expectedMetadata.put("tx_metadata", value(txMetadata)); + if (mode == READ) { + expectedMetadata.put("mode", value("r")); } - order.verify( packer ).pack( expectedMetadata ); + order.verify(packer).pack(expectedMetadata); } @Test - void shouldFailToEncodeWrongMessage() - { - assertThrows( IllegalArgumentException.class, () -> encoder.encode( DISCARD_ALL, packer ) ); + void shouldFailToEncodeWrongMessage() { + assertThrows(IllegalArgumentException.class, () -> encoder.encode(DISCARD_ALL, packer)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/request/HelloMessageTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/request/HelloMessageTest.java index d7573137ab..3c65657e2e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/request/HelloMessageTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/request/HelloMessageTest.java @@ -18,69 +18,61 @@ */ package org.neo4j.driver.internal.messaging.request; -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.neo4j.driver.Value; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.neo4j.driver.Values.NULL; +import static org.neo4j.driver.Values.value; import static org.neo4j.driver.internal.security.InternalAuthToken.CREDENTIALS_KEY; import static org.neo4j.driver.internal.security.InternalAuthToken.PRINCIPAL_KEY; -import static org.neo4j.driver.Values.value; -class HelloMessageTest -{ +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; + +class HelloMessageTest { @Test - void shouldHaveCorrectMetadata() - { - Map authToken = new HashMap<>(); - authToken.put( "user", value( "Alice" ) ); - authToken.put( "credentials", value( "SecretPassword" ) ); + void shouldHaveCorrectMetadata() { + Map authToken = new HashMap<>(); + authToken.put("user", value("Alice")); + authToken.put("credentials", value("SecretPassword")); - HelloMessage message = new HelloMessage( "MyDriver/1.0.2", authToken, Collections.emptyMap() ); + HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, Collections.emptyMap()); - Map expectedMetadata = new HashMap<>( authToken ); - expectedMetadata.put( "user_agent", value( "MyDriver/1.0.2" ) ); - expectedMetadata.put( "routing", value ( Collections.emptyMap() ) ); - assertEquals( expectedMetadata, message.metadata() ); + Map expectedMetadata = new HashMap<>(authToken); + expectedMetadata.put("user_agent", value("MyDriver/1.0.2")); + expectedMetadata.put("routing", value(Collections.emptyMap())); + assertEquals(expectedMetadata, message.metadata()); } @Test - void shouldHaveCorrectRoutingContext() - { - Map authToken = new HashMap<>(); - authToken.put( "user", value( "Alice" ) ); - authToken.put( "credentials", value( "SecretPassword" ) ); + void shouldHaveCorrectRoutingContext() { + Map authToken = new HashMap<>(); + authToken.put("user", value("Alice")); + authToken.put("credentials", value("SecretPassword")); - Map routingContext = new HashMap<>(); - routingContext.put( "region", "China" ); - routingContext.put( "speed", "Slow" ); + Map routingContext = new HashMap<>(); + routingContext.put("region", "China"); + routingContext.put("speed", "Slow"); - HelloMessage message = new HelloMessage( "MyDriver/1.0.2", authToken, routingContext ); + HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, routingContext); - Map expectedMetadata = new HashMap<>( authToken ); - expectedMetadata.put( "user_agent", value( "MyDriver/1.0.2" ) ); - expectedMetadata.put( "routing", value( routingContext ) ); - assertEquals( expectedMetadata, message.metadata() ); + Map expectedMetadata = new HashMap<>(authToken); + expectedMetadata.put("user_agent", value("MyDriver/1.0.2")); + expectedMetadata.put("routing", value(routingContext)); + assertEquals(expectedMetadata, message.metadata()); } - @Test - void shouldNotExposeCredentialsInToString() - { - Map authToken = new HashMap<>(); - authToken.put( PRINCIPAL_KEY, value( "Alice" ) ); - authToken.put( CREDENTIALS_KEY, value( "SecretPassword" ) ); + void shouldNotExposeCredentialsInToString() { + Map authToken = new HashMap<>(); + authToken.put(PRINCIPAL_KEY, value("Alice")); + authToken.put(CREDENTIALS_KEY, value("SecretPassword")); - HelloMessage message = new HelloMessage( "MyDriver/1.0.2", authToken, Collections.emptyMap() ); + HelloMessage message = new HelloMessage("MyDriver/1.0.2", authToken, Collections.emptyMap()); - assertThat( message.toString(), not( containsString( "SecretPassword" ) ) ); + assertThat(message.toString(), not(containsString("SecretPassword"))); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilderTest.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilderTest.java index e9dae116ca..98352b8e30 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/request/TransactionMetadataBuilderTest.java @@ -18,89 +18,85 @@ */ package org.neo4j.driver.internal.messaging.request; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.ValueSource; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.messaging.request.TransactionMetadataBuilder.buildMetadata; import java.time.Duration; import java.time.LocalDateTime; import java.util.HashMap; import java.util.HashSet; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.ValueSource; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalBookmark; -import static java.util.Arrays.asList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.messaging.request.TransactionMetadataBuilder.buildMetadata; - -public class TransactionMetadataBuilderTest -{ +public class TransactionMetadataBuilderTest { @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldHaveCorrectMetadata( AccessMode mode ) - { - Bookmark bookmark = InternalBookmark.parse( new HashSet<>( asList( "neo4j:bookmark:v1:tx11", "neo4j:bookmark:v1:tx52" ) ) ); - - Map txMetadata = new HashMap<>(); - txMetadata.put( "foo", value( "bar" ) ); - txMetadata.put( "baz", value( 111 ) ); - txMetadata.put( "time", value( LocalDateTime.now() ) ); - - Duration txTimeout = Duration.ofSeconds( 7 ); - - Map metadata = buildMetadata( txTimeout, txMetadata, defaultDatabase(), mode, bookmark, null ); - - Map expectedMetadata = new HashMap<>(); - expectedMetadata.put( "bookmarks", value( bookmark.values() ) ); - expectedMetadata.put( "tx_timeout", value( 7000 ) ); - expectedMetadata.put( "tx_metadata", value( txMetadata ) ); - if ( mode == READ ) - { - expectedMetadata.put( "mode", value( "r" ) ); + @EnumSource(AccessMode.class) + void shouldHaveCorrectMetadata(AccessMode mode) { + Bookmark bookmark = + InternalBookmark.parse(new HashSet<>(asList("neo4j:bookmark:v1:tx11", "neo4j:bookmark:v1:tx52"))); + + Map txMetadata = new HashMap<>(); + txMetadata.put("foo", value("bar")); + txMetadata.put("baz", value(111)); + txMetadata.put("time", value(LocalDateTime.now())); + + Duration txTimeout = Duration.ofSeconds(7); + + Map metadata = buildMetadata(txTimeout, txMetadata, defaultDatabase(), mode, bookmark, null); + + Map expectedMetadata = new HashMap<>(); + expectedMetadata.put("bookmarks", value(bookmark.values())); + expectedMetadata.put("tx_timeout", value(7000)); + expectedMetadata.put("tx_metadata", value(txMetadata)); + if (mode == READ) { + expectedMetadata.put("mode", value("r")); } - assertEquals( expectedMetadata, metadata ); + assertEquals(expectedMetadata, metadata); } @ParameterizedTest - @ValueSource( strings = {"", "foo", "data"} ) - void shouldHaveCorrectMetadataForDatabaseName( String databaseName ) - { - Bookmark bookmark = InternalBookmark.parse( new HashSet<>( asList( "neo4j:bookmark:v1:tx11", "neo4j:bookmark:v1:tx52" ) ) ); + @ValueSource(strings = {"", "foo", "data"}) + void shouldHaveCorrectMetadataForDatabaseName(String databaseName) { + Bookmark bookmark = + InternalBookmark.parse(new HashSet<>(asList("neo4j:bookmark:v1:tx11", "neo4j:bookmark:v1:tx52"))); - Map txMetadata = new HashMap<>(); - txMetadata.put( "foo", value( "bar" ) ); - txMetadata.put( "baz", value( 111 ) ); - txMetadata.put( "time", value( LocalDateTime.now() ) ); + Map txMetadata = new HashMap<>(); + txMetadata.put("foo", value("bar")); + txMetadata.put("baz", value(111)); + txMetadata.put("time", value(LocalDateTime.now())); - Duration txTimeout = Duration.ofSeconds( 7 ); + Duration txTimeout = Duration.ofSeconds(7); - Map metadata = buildMetadata( txTimeout, txMetadata, database( databaseName ), WRITE, bookmark, null ); + Map metadata = + buildMetadata(txTimeout, txMetadata, database(databaseName), WRITE, bookmark, null); - Map expectedMetadata = new HashMap<>(); - expectedMetadata.put( "bookmarks", value( bookmark.values() ) ); - expectedMetadata.put( "tx_timeout", value( 7000 ) ); - expectedMetadata.put( "tx_metadata", value( txMetadata ) ); - expectedMetadata.put( "db", value( databaseName ) ); + Map expectedMetadata = new HashMap<>(); + expectedMetadata.put("bookmarks", value(bookmark.values())); + expectedMetadata.put("tx_timeout", value(7000)); + expectedMetadata.put("tx_metadata", value(txMetadata)); + expectedMetadata.put("db", value(databaseName)); - assertEquals( expectedMetadata, metadata ); + assertEquals(expectedMetadata, metadata); } @Test - void shouldNotHaveMetadataForDatabaseNameWhenIsNull() - { - Map metadata = buildMetadata( null, null, defaultDatabase(), WRITE, null, null ); - assertTrue( metadata.isEmpty() ); + void shouldNotHaveMetadataForDatabaseNameWhenIsNull() { + Map metadata = buildMetadata(null, null, defaultDatabase(), WRITE, null, null); + assertTrue(metadata.isEmpty()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3Test.java index 14f6d3bcb2..08e30ea1fe 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/BoltProtocolV3Test.java @@ -18,20 +18,46 @@ */ package org.neo4j.driver.internal.messaging.v3; +import static java.time.Duration.ofSeconds; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.startsWith; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; +import static org.neo4j.driver.util.TestUtil.await; +import static org.neo4j.driver.util.TestUtil.connectionMock; + import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.mockito.ArgumentCaptor; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Bookmark; @@ -66,464 +92,426 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.time.Duration.ofSeconds; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; -import static org.neo4j.driver.util.TestUtil.await; -import static org.neo4j.driver.util.TestUtil.connectionMock; - -public class BoltProtocolV3Test -{ +public class BoltProtocolV3Test { protected static final String QUERY_TEXT = "RETURN $x"; - protected static final Map PARAMS = singletonMap( "x", value( 42 ) ); - protected static final Query QUERY = new Query( QUERY_TEXT, value( PARAMS ) ); + protected static final Map PARAMS = singletonMap("x", value(42)); + protected static final Query QUERY = new Query(QUERY_TEXT, value(PARAMS)); protected final BoltProtocol protocol = createProtocol(); private final EmbeddedChannel channel = new EmbeddedChannel(); - private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher( channel, Logging.none() ); + private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher(channel, Logging.none()); private final TransactionConfig txConfig = TransactionConfig.builder() - .withTimeout( ofSeconds( 12 ) ) - .withMetadata( singletonMap( "key", value( 42 ) ) ) - .build(); + .withTimeout(ofSeconds(12)) + .withMetadata(singletonMap("key", value(42))) + .build(); @BeforeEach - void beforeEach() - { - ChannelAttributes.setMessageDispatcher( channel, messageDispatcher ); + void beforeEach() { + ChannelAttributes.setMessageDispatcher(channel, messageDispatcher); } @AfterEach - void afterEach() - { + void afterEach() { channel.finishAndReleaseAll(); } - protected BoltProtocol createProtocol() - { + protected BoltProtocol createProtocol() { return BoltProtocolV3.INSTANCE; } - protected Class expectedMessageFormatType() - { + protected Class expectedMessageFormatType() { return MessageFormatV3.class; } @Test - void shouldCreateMessageFormat() - { - assertThat( protocol.createMessageFormat(), instanceOf( expectedMessageFormatType() ) ); + void shouldCreateMessageFormat() { + assertThat(protocol.createMessageFormat(), instanceOf(expectedMessageFormatType())); } @Test - void shouldInitializeChannel() - { + void shouldInitializeChannel() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - Map metadata = new HashMap<>(); - metadata.put( "server", value( anyServerVersion().toString() ) ); - metadata.put( "connection_id", value( "bolt-42" ) ); + Map metadata = new HashMap<>(); + metadata.put("server", value(anyServerVersion().toString())); + metadata.put("connection_id", value("bolt-42")); - messageDispatcher.handleSuccessMessage( metadata ); + messageDispatcher.handleSuccessMessage(metadata); - assertTrue( promise.isDone() ); - assertTrue( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertTrue(promise.isSuccess()); } @Test - void shouldPrepareToCloseChannel() - { - protocol.prepareToCloseChannel( channel ); + void shouldPrepareToCloseChannel() { + protocol.prepareToCloseChannel(channel); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( GoodbyeMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(GoodbyeMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); } @Test - void shouldFailToInitializeChannelWhenErrorIsReceived() - { + void shouldFailToInitializeChannelWhenErrorIsReceived() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - messageDispatcher.handleFailureMessage( "Neo.TransientError.General.DatabaseUnavailable", "Error!" ); + messageDispatcher.handleFailureMessage("Neo.TransientError.General.DatabaseUnavailable", "Error!"); - assertTrue( promise.isDone() ); - assertFalse( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertFalse(promise.isSuccess()); } @Test - void shouldBeginTransactionWithoutBookmark() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithoutBookmark() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); + CompletionStage stage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); - verify( connection ).writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage( + InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarks() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx100" ); + void shouldBeginTransactionWithBookmarks() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx100"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, TransactionConfig.empty() ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithConfig() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithConfig() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, InternalBookmark.empty(), txConfig); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarksAndConfig() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx4242" ); + void shouldBeginTransactionWithBookmarksAndConfig() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx4242"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, txConfig); - verify( connection ).writeAndFlush( eq( new BeginMessage( bookmark, txConfig, defaultDatabase(), WRITE, null ) ), any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldCommitTransaction() - { + void shouldCommitTransaction() { String bookmarkString = "neo4j:bookmark:v1:tx4242"; - Connection connection = connectionMock( protocol ); - when( connection.protocol() ).thenReturn( protocol ); - doAnswer( invocation -> - { - ResponseHandler commitHandler = invocation.getArgument( 1 ); - commitHandler.onSuccess( singletonMap( "bookmark", value( bookmarkString ) ) ); - return null; - } ).when( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any() ); + Connection connection = connectionMock(protocol); + when(connection.protocol()).thenReturn(protocol); + doAnswer(invocation -> { + ResponseHandler commitHandler = invocation.getArgument(1); + commitHandler.onSuccess(singletonMap("bookmark", value(bookmarkString))); + return null; + }) + .when(connection) + .writeAndFlush(eq(CommitMessage.COMMIT), any()); - CompletionStage stage = protocol.commitTransaction( connection ); + CompletionStage stage = protocol.commitTransaction(connection); - verify( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any( CommitTxResponseHandler.class ) ); - assertEquals( InternalBookmark.parse( bookmarkString ), await( stage ) ); + verify(connection).writeAndFlush(eq(CommitMessage.COMMIT), any(CommitTxResponseHandler.class)); + assertEquals(InternalBookmark.parse(bookmarkString), await(stage)); } @Test - void shouldRollbackTransaction() - { - Connection connection = connectionMock( protocol ); + void shouldRollbackTransaction() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.rollbackTransaction( connection ); + CompletionStage stage = protocol.rollbackTransaction(connection); - verify( connection ).writeAndFlush( eq( RollbackMessage.ROLLBACK ), any( RollbackTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection).writeAndFlush(eq(RollbackMessage.ROLLBACK), any(RollbackTxResponseHandler.class)); + assertNull(await(stage)); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx65" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse(AccessMode mode) + throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx65"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse(InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx163" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse(AccessMode mode) + throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx163"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( false, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(false, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( true, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(true, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( false, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(false, mode); } @Test - void databaseNameInBeginTransaction() - { - testDatabaseNameSupport( false ); + void databaseNameInBeginTransaction() { + testDatabaseNameSupport(false); } @Test - void databaseNameForAutoCommitTransactions() - { - testDatabaseNameSupport( true ); + void databaseNameForAutoCommitTransactions() { + testDatabaseNameSupport(true); } @Test - void shouldNotSupportDatabaseNameInBeginTransaction() - { - CompletionStage txStage = protocol.beginTransaction( connectionMock( "foo", protocol ), InternalBookmark.empty(), TransactionConfig.empty() ); + void shouldNotSupportDatabaseNameInBeginTransaction() { + CompletionStage txStage = protocol.beginTransaction( + connectionMock("foo", protocol), InternalBookmark.empty(), TransactionConfig.empty()); - ClientException e = assertThrows( ClientException.class, () -> await( txStage ) ); - assertThat( e.getMessage(), startsWith( "Database name parameter for selecting database is not supported" ) ); + ClientException e = assertThrows(ClientException.class, () -> await(txStage)); + assertThat(e.getMessage(), startsWith("Database name parameter for selecting database is not supported")); } @Test - void shouldNotSupportDatabaseNameForAutoCommitTransactions() - { - ClientException e = assertThrows( ClientException.class, - () -> protocol.runInAutoCommitTransaction( connectionMock( "foo", protocol ), - new Query( "RETURN 1" ), BookmarkHolder.NO_OP, TransactionConfig.empty(), - UNLIMITED_FETCH_SIZE ) ); - assertThat( e.getMessage(), startsWith( "Database name parameter for selecting database is not supported" ) ); - } - - protected void testDatabaseNameSupport( boolean autoCommitTx ) - { + void shouldNotSupportDatabaseNameForAutoCommitTransactions() { + ClientException e = assertThrows( + ClientException.class, + () -> protocol.runInAutoCommitTransaction( + connectionMock("foo", protocol), + new Query("RETURN 1"), + BookmarkHolder.NO_OP, + TransactionConfig.empty(), + UNLIMITED_FETCH_SIZE)); + assertThat(e.getMessage(), startsWith("Database name parameter for selecting database is not supported")); + } + + protected void testDatabaseNameSupport(boolean autoCommitTx) { ClientException e; - if ( autoCommitTx ) - { - e = assertThrows( ClientException.class, - () -> protocol.runInAutoCommitTransaction( connectionMock( "foo", protocol ), new Query( "RETURN 1" ), BookmarkHolder.NO_OP, - TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ) ); - } - else - { - CompletionStage txStage = protocol.beginTransaction( connectionMock( "foo", protocol ), InternalBookmark.empty(), TransactionConfig.empty() ); - e = assertThrows( ClientException.class, () -> await( txStage ) ); + if (autoCommitTx) { + e = assertThrows( + ClientException.class, + () -> protocol.runInAutoCommitTransaction( + connectionMock("foo", protocol), + new Query("RETURN 1"), + BookmarkHolder.NO_OP, + TransactionConfig.empty(), + UNLIMITED_FETCH_SIZE)); + } else { + CompletionStage txStage = protocol.beginTransaction( + connectionMock("foo", protocol), InternalBookmark.empty(), TransactionConfig.empty()); + e = assertThrows(ClientException.class, () -> await(txStage)); } - assertThat( e.getMessage(), startsWith( "Database name parameter for selecting database is not supported" ) ); + assertThat(e.getMessage(), startsWith("Database name parameter for selecting database is not supported")); } - protected void testRunInUnmanagedTransactionAndWaitForRunResponse( boolean success, AccessMode mode ) throws Exception - { + protected void testRunInUnmanagedTransactionAndWaitForRunResponse(boolean success, AccessMode mode) + throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); + Connection connection = connectionMock(mode, protocol); - CompletableFuture cursorFuture = - protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ).asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runResponseHandler = verifyRunInvoked( connection, false, InternalBookmark.empty(), TransactionConfig.empty(), mode ).runHandler; - assertFalse( cursorFuture.isDone() ); + ResponseHandler runResponseHandler = verifyRunInvoked( + connection, false, InternalBookmark.empty(), TransactionConfig.empty(), mode) + .runHandler; + assertFalse(cursorFuture.isDone()); Throwable error = new RuntimeException(); - if ( success ) - { - runResponseHandler.onSuccess( emptyMap() ); - } - else - { + if (success) { + runResponseHandler.onSuccess(emptyMap()); + } else { // When responded with a failure - runResponseHandler.onFailure( error ); + runResponseHandler.onFailure(error); } // Then - assertTrue( cursorFuture.isDone() ); - if ( success ) - { - assertNotNull( await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - } - else - { - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertTrue(cursorFuture.isDone()); + if (success) { + assertNotNull(await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + } else { + Throwable actual = assertThrows( + error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } } - protected void testRunAndWaitForRunResponse( boolean autoCommitTx, TransactionConfig config, AccessMode mode ) throws Exception - { - Connection connection = connectionMock( mode, protocol ); - Bookmark initialBookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx987" ); + protected void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfig config, AccessMode mode) + throws Exception { + Connection connection = connectionMock(mode, protocol); + Bookmark initialBookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx987"); CompletionStage cursorStage; - if ( autoCommitTx ) - { - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( initialBookmark ); - cursorStage = protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ).asyncResult(); - } - else - { - cursorStage = protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ).asyncResult(); + if (autoCommitTx) { + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(initialBookmark); + cursorStage = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult(); + } else { + cursorStage = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult(); } CompletableFuture cursorFuture = cursorStage.toCompletableFuture(); - assertFalse( cursorFuture.isDone() ); + assertFalse(cursorFuture.isDone()); Bookmark bookmark = autoCommitTx ? initialBookmark : InternalBookmark.empty(); - ResponseHandler runResponseHandler = verifyRunInvoked( connection, autoCommitTx, bookmark, config, mode ).runHandler; - runResponseHandler.onSuccess( emptyMap() ); + ResponseHandler runResponseHandler = + verifyRunInvoked(connection, autoCommitTx, bookmark, config, mode).runHandler; + runResponseHandler.onSuccess(emptyMap()); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - protected void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + protected void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); - assertFalse( cursorFuture.isDone() ); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); + assertFalse(cursorFuture.isDone()); - ResponseHandlers handlers = verifyRunInvoked( connection, true, bookmark, config, mode ); + ResponseHandlers handlers = verifyRunInvoked(connection, true, bookmark, config, mode); String newBookmarkValue = "neo4j:bookmark:v1:tx98765"; - handlers.runHandler.onSuccess( emptyMap() ); - handlers.pullAllHandler.onSuccess( singletonMap( "bookmark", value( newBookmarkValue ) ) ); - assertEquals( InternalBookmark.parse( newBookmarkValue ), bookmarkHolder.getBookmark() ); + handlers.runHandler.onSuccess(emptyMap()); + handlers.pullAllHandler.onSuccess(singletonMap("bookmark", value(newBookmarkValue))); + assertEquals(InternalBookmark.parse(newBookmarkValue), bookmarkHolder.getBookmark()); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - protected void testFailedRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + protected void testFailedRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); - assertFalse( cursorFuture.isDone() ); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); + assertFalse(cursorFuture.isDone()); - ResponseHandler runResponseHandler = verifyRunInvoked( connection, true, bookmark, config, mode ).runHandler; + ResponseHandler runResponseHandler = verifyRunInvoked(connection, true, bookmark, config, mode).runHandler; Throwable error = new RuntimeException(); - runResponseHandler.onFailure( error ); - assertEquals( bookmark, bookmarkHolder.getBookmark() ); + runResponseHandler.onFailure(error); + assertEquals(bookmark, bookmarkHolder.getBookmark()); - assertTrue( cursorFuture.isDone() ); - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertTrue(cursorFuture.isDone()); + Throwable actual = + assertThrows(error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } - private static InternalAuthToken dummyAuthToken() - { - return (InternalAuthToken) AuthTokens.basic( "hello", "world" ); + private static InternalAuthToken dummyAuthToken() { + return (InternalAuthToken) AuthTokens.basic("hello", "world"); } - private static ResponseHandlers verifyRunInvoked( Connection connection, boolean session, Bookmark bookmark, TransactionConfig config, AccessMode mode ) - { - ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - ArgumentCaptor pullAllHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); + private static ResponseHandlers verifyRunInvoked( + Connection connection, boolean session, Bookmark bookmark, TransactionConfig config, AccessMode mode) { + ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + ArgumentCaptor pullAllHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); RunWithMetadataMessage expectedMessage; - if ( session ) - { - expectedMessage = RunWithMetadataMessage.autoCommitTxRunMessage( QUERY, config, defaultDatabase(), mode, bookmark, null ); - } - else - { - expectedMessage = RunWithMetadataMessage.unmanagedTxRunMessage( QUERY ); + if (session) { + expectedMessage = RunWithMetadataMessage.autoCommitTxRunMessage( + QUERY, config, defaultDatabase(), mode, bookmark, null); + } else { + expectedMessage = RunWithMetadataMessage.unmanagedTxRunMessage(QUERY); } - verify( connection ).write( eq( expectedMessage ), runHandlerCaptor.capture() ); - verify( connection ).writeAndFlush( eq( PullAllMessage.PULL_ALL ), pullAllHandlerCaptor.capture() ); + verify(connection).write(eq(expectedMessage), runHandlerCaptor.capture()); + verify(connection).writeAndFlush(eq(PullAllMessage.PULL_ALL), pullAllHandlerCaptor.capture()); - assertThat( runHandlerCaptor.getValue(), instanceOf( RunResponseHandler.class ) ); - assertThat( pullAllHandlerCaptor.getValue(), instanceOf( PullAllResponseHandler.class ) ); + assertThat(runHandlerCaptor.getValue(), instanceOf(RunResponseHandler.class)); + assertThat(pullAllHandlerCaptor.getValue(), instanceOf(PullAllResponseHandler.class)); - return new ResponseHandlers( runHandlerCaptor.getValue(), pullAllHandlerCaptor.getValue() ); + return new ResponseHandlers(runHandlerCaptor.getValue(), pullAllHandlerCaptor.getValue()); } - private static class ResponseHandlers - { + private static class ResponseHandlers { final ResponseHandler runHandler; final ResponseHandler pullAllHandler; - ResponseHandlers( ResponseHandler runHandler, ResponseHandler pullAllHandler ) - { + ResponseHandlers(ResponseHandler runHandler, ResponseHandler pullAllHandler) { this.runHandler = runHandler; this.pullAllHandler = pullAllHandler; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageFormatV3Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageFormatV3Test.java index 0ded6cb1b2..2a423c3b30 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageFormatV3Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageFormatV3Test.java @@ -18,39 +18,35 @@ */ package org.neo4j.driver.internal.messaging.v3; -import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.common.CommonMessageReader; import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.mockito.Mockito.mock; - /** * The MessageFormat under tests is the one provided by the {@link BoltProtocolV3} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageFormatV3Test -{ +class MessageFormatV3Test { private static MessageFormat messageFormat = BoltProtocolV3.INSTANCE.createMessageFormat(); @Test - void shouldCreateCorrectWriter() - { - MessageFormat.Writer writer = messageFormat.newWriter( mock( PackOutput.class ) ); + void shouldCreateCorrectWriter() { + MessageFormat.Writer writer = messageFormat.newWriter(mock(PackOutput.class)); - assertThat( writer, instanceOf( MessageWriterV3.class ) ); + assertThat(writer, instanceOf(MessageWriterV3.class)); } @Test - void shouldCreateCorrectReader() - { - MessageFormat.Reader reader = messageFormat.newReader( mock( PackInput.class ) ); + void shouldCreateCorrectReader() { + MessageFormat.Reader reader = messageFormat.newReader(mock(PackInput.class)); - assertThat( reader, instanceOf( CommonMessageReader.class ) ); + assertThat(reader, instanceOf(CommonMessageReader.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageReaderV3Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageReaderV3Test.java index 9e2ec0f276..0980a67982 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageReaderV3Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageReaderV3Test.java @@ -18,6 +18,18 @@ */ package org.neo4j.driver.internal.messaging.v3; +import static java.util.Arrays.asList; +import static java.util.Calendar.APRIL; +import static java.util.Calendar.AUGUST; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +39,6 @@ import java.time.ZonedDateTime; import java.util.HashMap; import java.util.stream.Stream; - import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.InternalPoint2D; @@ -42,77 +53,60 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.util.messaging.AbstractMessageReaderTestBase; -import static java.util.Arrays.asList; -import static java.util.Calendar.APRIL; -import static java.util.Calendar.AUGUST; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; - /** * The MessageReader under tests is the one provided by the {@link BoltProtocolV3} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -public class MessageReaderV3Test extends AbstractMessageReaderTestBase -{ +public class MessageReaderV3Test extends AbstractMessageReaderTestBase { @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // V2 Record types - record( value( new InternalPoint2D( 42, 120.65, -99.2 ) ) ), - record( value( new InternalPoint3D( 42, 85.391, 98.8, 11.1 ) ) ), - record( value( LocalDate.of( 2012, AUGUST, 3 ) ) ), - record( value( OffsetTime.of( 23, 59, 59, 999, ZoneOffset.MAX ) ) ), - record( value( LocalTime.of( 12, 25 ) ) ), - record( value( LocalDateTime.of( 1999, APRIL, 3, 19, 5, 5, 100_200_300 ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes( -7, -15 ) ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of( "Europe/Stockholm" ) ) ) ), - record( value( Values.isoDuration( Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1 ).asIsoDuration() ) ), - record( value( Values.isoDuration( 17, 22, 99, 15 ).asIsoDuration() ) ), + record(value(new InternalPoint2D(42, 120.65, -99.2))), + record(value(new InternalPoint3D(42, 85.391, 98.8, 11.1))), + record(value(LocalDate.of(2012, AUGUST, 3))), + record(value(OffsetTime.of(23, 59, 59, 999, ZoneOffset.MAX))), + record(value(LocalTime.of(12, 25))), + record(value(LocalDateTime.of(1999, APRIL, 3, 19, 5, 5, 100_200_300))), + record(value( + ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes(-7, -15)))), + record(value(ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of("Europe/Stockholm")))), + record(value(Values.isoDuration( + Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1) + .asIsoDuration())), + record(value(Values.isoDuration(17, 22, 99, 15).asIsoDuration())), // Bolt previous versions valid messages - new FailureMessage( "Hello", "World!" ), + new FailureMessage("Hello", "World!"), IgnoredMessage.IGNORED, - new SuccessMessage( new HashMap<>() ), - record( value( 1337L ) ), - record( value( parameters( "cat", null, "dog", null ) ) ), - record( value( parameters( "k", 12, "a", "banana" ) ) ), - record( value( asList( "k", 12, "a", "banana" ) ) ), + new SuccessMessage(new HashMap<>()), + record(value(1337L)), + record(value(parameters("cat", null, "dog", null))), + record(value(parameters("k", 12, "a", "banana"))), + record(value(asList("k", 12, "a", "banana"))), // V3 Record Types - record( emptyNodeValue() ), - record( filledNodeValue() ), - record( emptyRelationshipValue() ), - record( filledRelationshipValue() ), - record( filledPathValue() ), - record( emptyPathValue() ) - ); + record(emptyNodeValue()), + record(filledNodeValue()), + record(emptyRelationshipValue()), + record(filledRelationshipValue()), + record(filledPathValue()), + record(emptyPathValue())); } @Override - protected Stream unsupportedMessages() - { - return Stream.of( - DiscardAllMessage.DISCARD_ALL - ); + protected Stream unsupportedMessages() { + return Stream.of(DiscardAllMessage.DISCARD_ALL); } @Override - protected MessageFormat.Reader newReader( PackInput input ) - { - return BoltProtocolV3.INSTANCE.createMessageFormat().newReader( input ); + protected MessageFormat.Reader newReader(PackInput input) { + return BoltProtocolV3.INSTANCE.createMessageFormat().newReader(input); } - private Message record( Value value ) - { - return new RecordMessage( new Value[]{value} ); + private Message record(Value value) { + return new RecordMessage(new Value[] {value}); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3Test.java index 1b399ba610..e673f9bd07 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v3/MessageWriterV3Test.java @@ -18,26 +18,6 @@ */ package org.neo4j.driver.internal.messaging.v3; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetTime; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.util.Collections; -import java.util.stream.Stream; - -import org.neo4j.driver.Query; -import org.neo4j.driver.internal.InternalBookmark; -import org.neo4j.driver.internal.messaging.Message; -import org.neo4j.driver.internal.messaging.MessageFormat; -import org.neo4j.driver.internal.messaging.request.BeginMessage; -import org.neo4j.driver.internal.messaging.request.HelloMessage; -import org.neo4j.driver.internal.packstream.PackOutput; -import org.neo4j.driver.internal.security.InternalAuthToken; -import org.neo4j.driver.internal.util.messaging.AbstractMessageWriterTestBase; - import static java.time.Duration.ofSeconds; import static java.util.Calendar.DECEMBER; import static java.util.Collections.emptyMap; @@ -57,66 +37,129 @@ import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.stream.Stream; +import org.neo4j.driver.Query; +import org.neo4j.driver.internal.InternalBookmark; +import org.neo4j.driver.internal.messaging.Message; +import org.neo4j.driver.internal.messaging.MessageFormat; +import org.neo4j.driver.internal.messaging.request.BeginMessage; +import org.neo4j.driver.internal.messaging.request.HelloMessage; +import org.neo4j.driver.internal.packstream.PackOutput; +import org.neo4j.driver.internal.security.InternalAuthToken; +import org.neo4j.driver.internal.util.messaging.AbstractMessageWriterTestBase; + /** * The MessageWriter under tests is the one provided by the {@link BoltProtocolV3} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageWriterV3Test extends AbstractMessageWriterTestBase -{ +class MessageWriterV3Test extends AbstractMessageWriterTestBase { @Override - protected MessageFormat.Writer newWriter( PackOutput output ) - { - return BoltProtocolV3.INSTANCE.createMessageFormat().newWriter( output ); + protected MessageFormat.Writer newWriter(PackOutput output) { + return BoltProtocolV3.INSTANCE.createMessageFormat().newWriter(output); } @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // Bolt V2 Data Types - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 12.99, -180.0 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 0.51, 2.99, 100.123 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $date", singletonMap( "date", value( LocalDate.ofEpochDay( 2147483650L ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( OffsetTime.of( 4, 16, 20, 999, ZoneOffset.MIN ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( LocalTime.of( 12, 9, 18, 999_888 ) ) ) ) ), + unmanagedTxRunMessage(new Query("RETURN $point", singletonMap("point", point(42, 12.99, -180.0)))), + unmanagedTxRunMessage( + new Query("RETURN $point", singletonMap("point", point(42, 0.51, 2.99, 100.123)))), + unmanagedTxRunMessage( + new Query("RETURN $date", singletonMap("date", value(LocalDate.ofEpochDay(2147483650L))))), + unmanagedTxRunMessage(new Query( + "RETURN $time", singletonMap("time", value(OffsetTime.of(4, 16, 20, 999, ZoneOffset.MIN))))), unmanagedTxRunMessage( - new Query( "RETURN $dateTime", singletonMap( "dateTime", value( LocalDateTime.of( 2049, DECEMBER, 12, 17, 25, 49, 199 ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneOffset - .ofHoursMinutes( 9, 30 ) ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneId.of( - "Europe/Stockholm" ) ) ) ) ) ), + new Query("RETURN $time", singletonMap("time", value(LocalTime.of(12, 9, 18, 999_888))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap("dateTime", value(LocalDateTime.of(2049, DECEMBER, 12, 17, 25, 49, 199))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of( + 2000, 1, 10, 12, 2, 49, 300, ZoneOffset.ofHoursMinutes(9, 30)))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of(2000, 1, 10, 12, 2, 49, 300, ZoneId.of("Europe/Stockholm")))))), // Bolt V3 messages - new HelloMessage( "MyDriver/1.2.3", ((InternalAuthToken) basic( "neo4j", "neo4j" )).toMap(), Collections.emptyMap() ), + new HelloMessage( + "MyDriver/1.2.3", + ((InternalAuthToken) basic("neo4j", "neo4j")).toMap(), + Collections.emptyMap()), GOODBYE, - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), READ, - defaultDatabase(), null ), - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), WRITE, - defaultDatabase(), null ), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + READ, + defaultDatabase(), + null), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + WRITE, + defaultDatabase(), + null), COMMIT, ROLLBACK, - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), defaultDatabase(), READ, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), defaultDatabase(), WRITE, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - unmanagedTxRunMessage( new Query( "RETURN 1" ) ), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + defaultDatabase(), + READ, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + defaultDatabase(), + WRITE, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + unmanagedTxRunMessage(new Query("RETURN 1")), PULL_ALL, DISCARD_ALL, RESET, // Bolt V3 messages with struct values - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - defaultDatabase(), READ, InternalBookmark.empty(), null ), - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - defaultDatabase(), WRITE, InternalBookmark.empty(), null ), - unmanagedTxRunMessage( new Query( "RETURN $x", singletonMap( "x", point( 42, 1, 2, 3 ) ) ) ) - ); + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + defaultDatabase(), + READ, + InternalBookmark.empty(), + null), + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + defaultDatabase(), + WRITE, + InternalBookmark.empty(), + null), + unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3))))); } @Override - protected Stream unsupportedMessages() - { + protected Stream unsupportedMessages() { return Stream.empty(); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4Test.java index ac26d0a2f0..06fef26fd0 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/BoltProtocolV4Test.java @@ -18,20 +18,47 @@ */ package org.neo4j.driver.internal.messaging.v4; +import static java.time.Duration.ofSeconds; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; +import static org.neo4j.driver.util.TestUtil.await; +import static org.neo4j.driver.util.TestUtil.connectionMock; + import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.mockito.ArgumentCaptor; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Bookmark; @@ -67,476 +94,436 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.time.Duration.ofSeconds; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; -import static org.neo4j.driver.util.TestUtil.await; -import static org.neo4j.driver.util.TestUtil.connectionMock; - -public final class BoltProtocolV4Test -{ +public final class BoltProtocolV4Test { protected static final String QUERY_TEXT = "RETURN $x"; - protected static final Map PARAMS = singletonMap( "x", value( 42 ) ); - protected static final Query QUERY = new Query( QUERY_TEXT, value( PARAMS ) ); + protected static final Map PARAMS = singletonMap("x", value(42)); + protected static final Query QUERY = new Query(QUERY_TEXT, value(PARAMS)); protected final BoltProtocol protocol = createProtocol(); private final EmbeddedChannel channel = new EmbeddedChannel(); - private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher( channel, Logging.none() ); + private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher(channel, Logging.none()); private final TransactionConfig txConfig = TransactionConfig.builder() - .withTimeout( ofSeconds( 12 ) ) - .withMetadata( singletonMap( "key", value( 42 ) ) ) - .build(); + .withTimeout(ofSeconds(12)) + .withMetadata(singletonMap("key", value(42))) + .build(); @BeforeEach - void beforeEach() - { - ChannelAttributes.setMessageDispatcher( channel, messageDispatcher ); + void beforeEach() { + ChannelAttributes.setMessageDispatcher(channel, messageDispatcher); } @AfterEach - void afterEach() - { + void afterEach() { channel.finishAndReleaseAll(); } @Test - void shouldCreateMessageFormat() - { - assertThat( protocol.createMessageFormat(), instanceOf( expectedMessageFormatType() ) ); + void shouldCreateMessageFormat() { + assertThat(protocol.createMessageFormat(), instanceOf(expectedMessageFormatType())); } @Test - void shouldInitializeChannel() - { + void shouldInitializeChannel() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - Map metadata = new HashMap<>(); - metadata.put( "server", value( anyServerVersion().toString() ) ); - metadata.put( "connection_id", value( "bolt-42" ) ); + Map metadata = new HashMap<>(); + metadata.put("server", value(anyServerVersion().toString())); + metadata.put("connection_id", value("bolt-42")); - messageDispatcher.handleSuccessMessage( metadata ); + messageDispatcher.handleSuccessMessage(metadata); - assertTrue( promise.isDone() ); - assertTrue( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertTrue(promise.isSuccess()); } @Test - void shouldPrepareToCloseChannel() - { - protocol.prepareToCloseChannel( channel ); + void shouldPrepareToCloseChannel() { + protocol.prepareToCloseChannel(channel); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( GoodbyeMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(GoodbyeMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); } @Test - void shouldFailToInitializeChannelWhenErrorIsReceived() - { + void shouldFailToInitializeChannelWhenErrorIsReceived() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - messageDispatcher.handleFailureMessage( "Neo.TransientError.General.DatabaseUnavailable", "Error!" ); + messageDispatcher.handleFailureMessage("Neo.TransientError.General.DatabaseUnavailable", "Error!"); - assertTrue( promise.isDone() ); - assertFalse( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertFalse(promise.isSuccess()); } @Test - void shouldBeginTransactionWithoutBookmark() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithoutBookmark() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); + CompletionStage stage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage( + InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarks() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx100" ); + void shouldBeginTransactionWithBookmarks() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx100"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, TransactionConfig.empty() ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithConfig() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithConfig() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, InternalBookmark.empty(), txConfig); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarksAndConfig() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx4242" ); + void shouldBeginTransactionWithBookmarksAndConfig() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx4242"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, txConfig); - verify( connection ).writeAndFlush( eq( new BeginMessage( bookmark, txConfig, defaultDatabase(), WRITE, null ) ), any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldCommitTransaction() - { + void shouldCommitTransaction() { String bookmarkString = "neo4j:bookmark:v1:tx4242"; - Connection connection = connectionMock( protocol ); - when( connection.protocol() ).thenReturn( protocol ); - doAnswer( invocation -> - { - ResponseHandler commitHandler = invocation.getArgument( 1 ); - commitHandler.onSuccess( singletonMap( "bookmark", value( bookmarkString ) ) ); - return null; - } ).when( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any() ); + Connection connection = connectionMock(protocol); + when(connection.protocol()).thenReturn(protocol); + doAnswer(invocation -> { + ResponseHandler commitHandler = invocation.getArgument(1); + commitHandler.onSuccess(singletonMap("bookmark", value(bookmarkString))); + return null; + }) + .when(connection) + .writeAndFlush(eq(CommitMessage.COMMIT), any()); - CompletionStage stage = protocol.commitTransaction( connection ); + CompletionStage stage = protocol.commitTransaction(connection); - verify( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any( CommitTxResponseHandler.class ) ); - assertEquals( InternalBookmark.parse( bookmarkString ), await( stage ) ); + verify(connection).writeAndFlush(eq(CommitMessage.COMMIT), any(CommitTxResponseHandler.class)); + assertEquals(InternalBookmark.parse(bookmarkString), await(stage)); } @Test - void shouldRollbackTransaction() - { - Connection connection = connectionMock( protocol ); + void shouldRollbackTransaction() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.rollbackTransaction( connection ); + CompletionStage stage = protocol.rollbackTransaction(connection); - verify( connection ).writeAndFlush( eq( RollbackMessage.ROLLBACK ), any( RollbackTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection).writeAndFlush(eq(RollbackMessage.ROLLBACK), any(RollbackTxResponseHandler.class)); + assertNull(await(stage)); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx65" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse(AccessMode mode) + throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx65"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse(InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx163" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse(AccessMode mode) + throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx163"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( false, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(false, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( true, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(true, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( false, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(false, mode); } @Test - void databaseNameInBeginTransaction() - { - testDatabaseNameSupport( false ); + void databaseNameInBeginTransaction() { + testDatabaseNameSupport(false); } @Test - void databaseNameForAutoCommitTransactions() - { - testDatabaseNameSupport( true ); + void databaseNameForAutoCommitTransactions() { + testDatabaseNameSupport(true); } @Test - void shouldSupportDatabaseNameInBeginTransaction() - { - CompletionStage txStage = protocol.beginTransaction( connectionMock( "foo", protocol ), InternalBookmark.empty(), TransactionConfig.empty() ); + void shouldSupportDatabaseNameInBeginTransaction() { + CompletionStage txStage = protocol.beginTransaction( + connectionMock("foo", protocol), InternalBookmark.empty(), TransactionConfig.empty()); - assertDoesNotThrow( () -> await( txStage ) ); + assertDoesNotThrow(() -> await(txStage)); } @Test - void shouldNotSupportDatabaseNameForAutoCommitTransactions() - { - assertDoesNotThrow( - () -> protocol.runInAutoCommitTransaction( connectionMock( "foo", protocol ), - new Query( "RETURN 1" ), BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ) ); + void shouldNotSupportDatabaseNameForAutoCommitTransactions() { + assertDoesNotThrow(() -> protocol.runInAutoCommitTransaction( + connectionMock("foo", protocol), + new Query("RETURN 1"), + BookmarkHolder.NO_OP, + TransactionConfig.empty(), + UNLIMITED_FETCH_SIZE)); } - private BoltProtocol createProtocol() - { + private BoltProtocol createProtocol() { return BoltProtocolV4.INSTANCE; } - private Class expectedMessageFormatType() - { + private Class expectedMessageFormatType() { return MessageFormatV4.class; } - private static InternalAuthToken dummyAuthToken() - { - return (InternalAuthToken) AuthTokens.basic( "hello", "world" ); + private static InternalAuthToken dummyAuthToken() { + return (InternalAuthToken) AuthTokens.basic("hello", "world"); } - protected void testFailedRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + protected void testFailedRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to Run message with a failure Throwable error = new RuntimeException(); - runHandler.onFailure( error ); + runHandler.onFailure(error); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + Throwable actual = + assertThrows(error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } - protected void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + protected void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to the run message - runHandler.onSuccess( emptyMap() ); + runHandler.onSuccess(emptyMap()); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - protected void testRunInUnmanagedTransactionAndWaitForRunResponse( boolean success, AccessMode mode ) throws Exception - { + protected void testRunInUnmanagedTransactionAndWaitForRunResponse(boolean success, AccessMode mode) + throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); + Connection connection = connectionMock(mode, protocol); - CompletableFuture cursorFuture = - protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifyTxRunInvoked( connection ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifyTxRunInvoked(connection); + assertFalse(cursorFuture.isDone()); Throwable error = new RuntimeException(); - if ( success ) - { - runHandler.onSuccess( emptyMap() ); - } - else - { + if (success) { + runHandler.onSuccess(emptyMap()); + } else { // When responded with a failure - runHandler.onFailure( error ); + runHandler.onFailure(error); } // Then - assertTrue( cursorFuture.isDone() ); - if ( success ) - { - assertNotNull( await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - } - else - { - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertTrue(cursorFuture.isDone()); + if (success) { + assertNotNull(await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + } else { + Throwable actual = assertThrows( + error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } } - protected void testRunAndWaitForRunResponse( boolean autoCommitTx, TransactionConfig config, AccessMode mode ) throws Exception - { + protected void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfig config, AccessMode mode) + throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - Bookmark initialBookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx987" ); + Connection connection = connectionMock(mode, protocol); + Bookmark initialBookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx987"); CompletionStage cursorStage; - if ( autoCommitTx ) - { - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( initialBookmark ); - cursorStage = protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult(); - } - else - { - cursorStage = protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult(); + if (autoCommitTx) { + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(initialBookmark); + cursorStage = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult(); + } else { + cursorStage = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult(); } // When & Then CompletableFuture cursorFuture = cursorStage.toCompletableFuture(); - assertFalse( cursorFuture.isDone() ); + assertFalse(cursorFuture.isDone()); - ResponseHandler runResponseHandler = - autoCommitTx ? verifySessionRunInvoked( connection, initialBookmark, config, mode, defaultDatabase() ) : verifyTxRunInvoked( connection ); - runResponseHandler.onSuccess( emptyMap() ); + ResponseHandler runResponseHandler = autoCommitTx + ? verifySessionRunInvoked(connection, initialBookmark, config, mode, defaultDatabase()) + : verifyTxRunInvoked(connection); + runResponseHandler.onSuccess(emptyMap()); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - protected void testDatabaseNameSupport( boolean autoCommitTx ) - { - Connection connection = connectionMock( "foo", protocol ); - if ( autoCommitTx ) - { - ResultCursorFactory factory = - protocol.runInAutoCommitTransaction( connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ); + protected void testDatabaseNameSupport(boolean autoCommitTx) { + Connection connection = connectionMock("foo", protocol); + if (autoCommitTx) { + ResultCursorFactory factory = protocol.runInAutoCommitTransaction( + connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE); CompletionStage resultStage = factory.asyncResult(); - ResponseHandler runHandler = - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - runHandler.onSuccess( emptyMap() ); - await( resultStage ); - } - else - { - CompletionStage txStage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); - await( txStage ); - verifyBeginInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); + ResponseHandler runHandler = verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + runHandler.onSuccess(emptyMap()); + await(resultStage); + } else { + CompletionStage txStage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); + await(txStage); + verifyBeginInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); } } - private ResponseHandler verifyTxRunInvoked( Connection connection ) - { - return verifyRunInvoked( connection, RunWithMetadataMessage.unmanagedTxRunMessage( QUERY ) ); + private ResponseHandler verifyTxRunInvoked(Connection connection) { + return verifyRunInvoked(connection, RunWithMetadataMessage.unmanagedTxRunMessage(QUERY)); } - private ResponseHandler verifySessionRunInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, - DatabaseName databaseName ) - { - RunWithMetadataMessage runMessage = RunWithMetadataMessage.autoCommitTxRunMessage( QUERY, config, databaseName, mode, bookmark, null ); - return verifyRunInvoked( connection, runMessage ); + private ResponseHandler verifySessionRunInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + RunWithMetadataMessage runMessage = + RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmark, null); + return verifyRunInvoked(connection, runMessage); } - private ResponseHandler verifyRunInvoked( Connection connection, RunWithMetadataMessage runMessage ) - { - ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); + private ResponseHandler verifyRunInvoked(Connection connection, RunWithMetadataMessage runMessage) { + ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); - verify( connection ).write( eq( runMessage ), runHandlerCaptor.capture() ); - verify( connection ).writeAndFlush( any( PullMessage.class ), pullHandlerCaptor.capture() ); + verify(connection).write(eq(runMessage), runHandlerCaptor.capture()); + verify(connection).writeAndFlush(any(PullMessage.class), pullHandlerCaptor.capture()); - assertThat( runHandlerCaptor.getValue(), instanceOf( RunResponseHandler.class ) ); - assertThat( pullHandlerCaptor.getValue(), instanceOf( PullAllResponseHandler.class ) ); + assertThat(runHandlerCaptor.getValue(), instanceOf(RunResponseHandler.class)); + assertThat(pullHandlerCaptor.getValue(), instanceOf(PullAllResponseHandler.class)); return runHandlerCaptor.getValue(); } - private void verifyBeginInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, DatabaseName databaseName ) - { - ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - BeginMessage beginMessage = new BeginMessage( bookmark, config, databaseName, mode, null ); - verify( connection ).writeAndFlush( eq( beginMessage ), beginHandlerCaptor.capture() ); - assertThat( beginHandlerCaptor.getValue(), instanceOf( BeginTxResponseHandler.class ) ); + private void verifyBeginInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + BeginMessage beginMessage = new BeginMessage(bookmark, config, databaseName, mode, null); + verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture()); + assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageFormatV4Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageFormatV4Test.java index e63ad0ef5c..701b0808df 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageFormatV4Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageFormatV4Test.java @@ -18,39 +18,35 @@ */ package org.neo4j.driver.internal.messaging.v4; -import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.common.CommonMessageReader; import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.mockito.Mockito.mock; - /** * The MessageFormat under tests is the one provided by the {@link BoltProtocolV4} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageFormatV4Test -{ +class MessageFormatV4Test { private static final MessageFormat format = BoltProtocolV4.INSTANCE.createMessageFormat(); @Test - void shouldCreateCorrectWriter() - { - MessageFormat.Writer writer = format.newWriter( mock( PackOutput.class ) ); + void shouldCreateCorrectWriter() { + MessageFormat.Writer writer = format.newWriter(mock(PackOutput.class)); - assertThat( writer, instanceOf( MessageWriterV4.class ) ); + assertThat(writer, instanceOf(MessageWriterV4.class)); } @Test - void shouldCreateCorrectReader() - { - MessageFormat.Reader reader = format.newReader( mock( PackInput.class ) ); + void shouldCreateCorrectReader() { + MessageFormat.Reader reader = format.newReader(mock(PackInput.class)); - assertThat( reader, instanceOf( CommonMessageReader.class ) ); + assertThat(reader, instanceOf(CommonMessageReader.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageReaderV4Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageReaderV4Test.java index 3ce6af0a7c..1c456f488b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageReaderV4Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageReaderV4Test.java @@ -18,6 +18,18 @@ */ package org.neo4j.driver.internal.messaging.v4; +import static java.util.Arrays.asList; +import static java.util.Calendar.APRIL; +import static java.util.Calendar.AUGUST; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +39,6 @@ import java.time.ZonedDateTime; import java.util.HashMap; import java.util.stream.Stream; - import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.InternalPoint2D; @@ -42,77 +53,60 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.util.messaging.AbstractMessageReaderTestBase; -import static java.util.Arrays.asList; -import static java.util.Calendar.APRIL; -import static java.util.Calendar.AUGUST; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; - /** * The MessageReader under tests is the one provided by the {@link BoltProtocolV4} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -public class MessageReaderV4Test extends AbstractMessageReaderTestBase -{ +public class MessageReaderV4Test extends AbstractMessageReaderTestBase { @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // V2 Record types - record( value( new InternalPoint2D( 42, 120.65, -99.2 ) ) ), - record( value( new InternalPoint3D( 42, 85.391, 98.8, 11.1 ) ) ), - record( value( LocalDate.of( 2012, AUGUST, 3 ) ) ), - record( value( OffsetTime.of( 23, 59, 59, 999, ZoneOffset.MAX ) ) ), - record( value( LocalTime.of( 12, 25 ) ) ), - record( value( LocalDateTime.of( 1999, APRIL, 3, 19, 5, 5, 100_200_300 ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes( -7, -15 ) ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of( "Europe/Stockholm" ) ) ) ), - record( value( Values.isoDuration( Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1 ).asIsoDuration() ) ), - record( value( Values.isoDuration( 17, 22, 99, 15 ).asIsoDuration() ) ), + record(value(new InternalPoint2D(42, 120.65, -99.2))), + record(value(new InternalPoint3D(42, 85.391, 98.8, 11.1))), + record(value(LocalDate.of(2012, AUGUST, 3))), + record(value(OffsetTime.of(23, 59, 59, 999, ZoneOffset.MAX))), + record(value(LocalTime.of(12, 25))), + record(value(LocalDateTime.of(1999, APRIL, 3, 19, 5, 5, 100_200_300))), + record(value( + ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes(-7, -15)))), + record(value(ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of("Europe/Stockholm")))), + record(value(Values.isoDuration( + Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1) + .asIsoDuration())), + record(value(Values.isoDuration(17, 22, 99, 15).asIsoDuration())), // Bolt previous versions valid messages - new FailureMessage( "Hello", "World!" ), + new FailureMessage("Hello", "World!"), IgnoredMessage.IGNORED, - new SuccessMessage( new HashMap<>() ), - record( value( 1337L ) ), - record( value( parameters( "cat", null, "dog", null ) ) ), - record( value( parameters( "k", 12, "a", "banana" ) ) ), - record( value( asList( "k", 12, "a", "banana" ) ) ), + new SuccessMessage(new HashMap<>()), + record(value(1337L)), + record(value(parameters("cat", null, "dog", null))), + record(value(parameters("k", 12, "a", "banana"))), + record(value(asList("k", 12, "a", "banana"))), // V3 Record Types - record( emptyNodeValue() ), - record( filledNodeValue() ), - record( emptyRelationshipValue() ), - record( filledRelationshipValue() ), - record( filledPathValue() ), - record( emptyPathValue() ) - ); + record(emptyNodeValue()), + record(filledNodeValue()), + record(emptyRelationshipValue()), + record(filledRelationshipValue()), + record(filledPathValue()), + record(emptyPathValue())); } @Override - protected Stream unsupportedMessages() - { - return Stream.of( - DiscardAllMessage.DISCARD_ALL - ); + protected Stream unsupportedMessages() { + return Stream.of(DiscardAllMessage.DISCARD_ALL); } @Override - protected MessageFormat.Reader newReader( PackInput input ) - { - return BoltProtocolV4.INSTANCE.createMessageFormat().newReader( input ); + protected MessageFormat.Reader newReader(PackInput input) { + return BoltProtocolV4.INSTANCE.createMessageFormat().newReader(input); } - private Message record( Value value ) - { - return new RecordMessage( new Value[]{value} ); + private Message record(Value value) { + return new RecordMessage(new Value[] {value}); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4Test.java index fe7decacd5..4886fb2a5f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v4/MessageWriterV4Test.java @@ -18,6 +18,26 @@ */ package org.neo4j.driver.internal.messaging.v4; +import static java.time.Duration.ofSeconds; +import static java.util.Calendar.DECEMBER; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.AuthTokens.basic; +import static org.neo4j.driver.Values.point; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; +import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; +import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; +import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; +import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +47,6 @@ import java.time.ZonedDateTime; import java.util.Collections; import java.util.stream.Stream; - import org.neo4j.driver.Query; import org.neo4j.driver.internal.InternalBookmark; import org.neo4j.driver.internal.messaging.Message; @@ -41,94 +60,114 @@ import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.util.messaging.AbstractMessageWriterTestBase; -import static java.time.Duration.ofSeconds; -import static java.util.Calendar.DECEMBER; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.AuthTokens.basic; -import static org.neo4j.driver.Values.point; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; -import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; -import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; -import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; -import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; - /** * The MessageWriter under tests is the one provided by the {@link BoltProtocolV3} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageWriterV4Test extends AbstractMessageWriterTestBase -{ +class MessageWriterV4Test extends AbstractMessageWriterTestBase { @Override - protected MessageFormat.Writer newWriter( PackOutput output ) - { - return BoltProtocolV4.INSTANCE.createMessageFormat().newWriter( output ); + protected MessageFormat.Writer newWriter(PackOutput output) { + return BoltProtocolV4.INSTANCE.createMessageFormat().newWriter(output); } @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // Bolt V2 Data Types - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 12.99, -180.0 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 0.51, 2.99, 100.123 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $date", singletonMap( "date", value( LocalDate.ofEpochDay( 2147483650L ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( OffsetTime.of( 4, 16, 20, 999, ZoneOffset.MIN ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( LocalTime.of( 12, 9, 18, 999_888 ) ) ) ) ), + unmanagedTxRunMessage(new Query("RETURN $point", singletonMap("point", point(42, 12.99, -180.0)))), + unmanagedTxRunMessage( + new Query("RETURN $point", singletonMap("point", point(42, 0.51, 2.99, 100.123)))), unmanagedTxRunMessage( - new Query( "RETURN $dateTime", singletonMap( "dateTime", value( LocalDateTime.of( 2049, DECEMBER, 12, 17, 25, 49, 199 ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneOffset - .ofHoursMinutes( 9, 30 ) ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneId.of( - "Europe/Stockholm" ) ) ) ) ) ), + new Query("RETURN $date", singletonMap("date", value(LocalDate.ofEpochDay(2147483650L))))), + unmanagedTxRunMessage(new Query( + "RETURN $time", singletonMap("time", value(OffsetTime.of(4, 16, 20, 999, ZoneOffset.MIN))))), + unmanagedTxRunMessage( + new Query("RETURN $time", singletonMap("time", value(LocalTime.of(12, 9, 18, 999_888))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap("dateTime", value(LocalDateTime.of(2049, DECEMBER, 12, 17, 25, 49, 199))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of( + 2000, 1, 10, 12, 2, 49, 300, ZoneOffset.ofHoursMinutes(9, 30)))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of(2000, 1, 10, 12, 2, 49, 300, ZoneId.of("Europe/Stockholm")))))), // New Bolt V4 messages - new PullMessage( 100, 200 ), - new DiscardMessage( 300, 400 ), + new PullMessage(100, 200), + new DiscardMessage(300, 400), // Bolt V3 messages - new HelloMessage( "MyDriver/1.2.3", ((InternalAuthToken) basic( "neo4j", "neo4j" )).toMap(), Collections.emptyMap() ), + new HelloMessage( + "MyDriver/1.2.3", + ((InternalAuthToken) basic("neo4j", "neo4j")).toMap(), + Collections.emptyMap()), GOODBYE, - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), READ, - defaultDatabase(), null ), - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), WRITE, - database( "foo" ), null ), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + READ, + defaultDatabase(), + null), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + WRITE, + database("foo"), + null), COMMIT, ROLLBACK, - RESET, - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), defaultDatabase(), READ, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), database( "foo" ), WRITE, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - unmanagedTxRunMessage( new Query( "RETURN 1" ) ), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + defaultDatabase(), + READ, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + database("foo"), + WRITE, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + unmanagedTxRunMessage(new Query("RETURN 1")), // Bolt V3 messages with struct values - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - defaultDatabase(), READ, InternalBookmark.empty(), null ), - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - database( "foo" ), - WRITE, InternalBookmark.empty(), null ), - unmanagedTxRunMessage( new Query( "RETURN $x", singletonMap( "x", point( 42, 1, 2, 3 ) ) ) ) - ); + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + defaultDatabase(), + READ, + InternalBookmark.empty(), + null), + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + database("foo"), + WRITE, + InternalBookmark.empty(), + null), + unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3))))); } @Override - protected Stream unsupportedMessages() - { + protected Stream unsupportedMessages() { return Stream.of( // Bolt V1, V2 and V3 messages - PULL_ALL, - DISCARD_ALL - ); + PULL_ALL, DISCARD_ALL); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41Test.java index f722df6b78..6607a3a388 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/BoltProtocolV41Test.java @@ -18,20 +18,47 @@ */ package org.neo4j.driver.internal.messaging.v41; +import static java.time.Duration.ofSeconds; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; +import static org.neo4j.driver.util.TestUtil.await; +import static org.neo4j.driver.util.TestUtil.connectionMock; + import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.mockito.ArgumentCaptor; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Bookmark; @@ -68,475 +95,434 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.time.Duration.ofSeconds; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; -import static org.neo4j.driver.util.TestUtil.await; -import static org.neo4j.driver.util.TestUtil.connectionMock; - -public final class BoltProtocolV41Test -{ +public final class BoltProtocolV41Test { protected static final String QUERY_TEXT = "RETURN $x"; - protected static final Map PARAMS = singletonMap( "x", value( 42 ) ); - protected static final Query QUERY = new Query( QUERY_TEXT, value( PARAMS ) ); + protected static final Map PARAMS = singletonMap("x", value(42)); + protected static final Query QUERY = new Query(QUERY_TEXT, value(PARAMS)); protected final BoltProtocol protocol = createProtocol(); private final EmbeddedChannel channel = new EmbeddedChannel(); - private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher( channel, Logging.none() ); + private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher(channel, Logging.none()); private final TransactionConfig txConfig = TransactionConfig.builder() - .withTimeout( ofSeconds( 12 ) ) - .withMetadata( singletonMap( "key", value( 42 ) ) ) - .build(); + .withTimeout(ofSeconds(12)) + .withMetadata(singletonMap("key", value(42))) + .build(); - private BoltProtocol createProtocol() - { + private BoltProtocol createProtocol() { return BoltProtocolV41.INSTANCE; } @BeforeEach - void beforeEach() - { - ChannelAttributes.setMessageDispatcher( channel, messageDispatcher ); + void beforeEach() { + ChannelAttributes.setMessageDispatcher(channel, messageDispatcher); } @AfterEach - void afterEach() - { + void afterEach() { channel.finishAndReleaseAll(); } @Test - void shouldCreateMessageFormat() - { - assertThat( protocol.createMessageFormat(), instanceOf( expectedMessageFormatType() ) ); + void shouldCreateMessageFormat() { + assertThat(protocol.createMessageFormat(), instanceOf(expectedMessageFormatType())); } @Test - void shouldInitializeChannel() - { + void shouldInitializeChannel() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - Map metadata = new HashMap<>(); - metadata.put( "server", value( anyServerVersion().toString() ) ); - metadata.put( "connection_id", value( "bolt-42" ) ); + Map metadata = new HashMap<>(); + metadata.put("server", value(anyServerVersion().toString())); + metadata.put("connection_id", value("bolt-42")); - messageDispatcher.handleSuccessMessage( metadata ); + messageDispatcher.handleSuccessMessage(metadata); - assertTrue( promise.isDone() ); - assertTrue( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertTrue(promise.isSuccess()); } @Test - void shouldPrepareToCloseChannel() - { - protocol.prepareToCloseChannel( channel ); + void shouldPrepareToCloseChannel() { + protocol.prepareToCloseChannel(channel); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( GoodbyeMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(GoodbyeMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); } @Test - void shouldFailToInitializeChannelWhenErrorIsReceived() - { + void shouldFailToInitializeChannelWhenErrorIsReceived() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - messageDispatcher.handleFailureMessage( "Neo.TransientError.General.DatabaseUnavailable", "Error!" ); + messageDispatcher.handleFailureMessage("Neo.TransientError.General.DatabaseUnavailable", "Error!"); - assertTrue( promise.isDone() ); - assertFalse( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertFalse(promise.isSuccess()); } @Test - void shouldBeginTransactionWithoutBookmark() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithoutBookmark() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); + CompletionStage stage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage( + InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarks() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx100" ); + void shouldBeginTransactionWithBookmarks() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx100"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, TransactionConfig.empty() ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithConfig() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithConfig() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, InternalBookmark.empty(), txConfig); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarksAndConfig() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx4242" ); + void shouldBeginTransactionWithBookmarksAndConfig() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx4242"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, txConfig); - verify( connection ).writeAndFlush( eq( new BeginMessage( bookmark, txConfig, defaultDatabase(), WRITE, null ) ), any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldCommitTransaction() - { + void shouldCommitTransaction() { String bookmarkString = "neo4j:bookmark:v1:tx4242"; - Connection connection = connectionMock( protocol ); - when( connection.protocol() ).thenReturn( protocol ); - doAnswer( invocation -> - { - ResponseHandler commitHandler = invocation.getArgument( 1 ); - commitHandler.onSuccess( singletonMap( "bookmark", value( bookmarkString ) ) ); - return null; - } ).when( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any() ); + Connection connection = connectionMock(protocol); + when(connection.protocol()).thenReturn(protocol); + doAnswer(invocation -> { + ResponseHandler commitHandler = invocation.getArgument(1); + commitHandler.onSuccess(singletonMap("bookmark", value(bookmarkString))); + return null; + }) + .when(connection) + .writeAndFlush(eq(CommitMessage.COMMIT), any()); - CompletionStage stage = protocol.commitTransaction( connection ); + CompletionStage stage = protocol.commitTransaction(connection); - verify( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any( CommitTxResponseHandler.class ) ); - assertEquals( InternalBookmark.parse( bookmarkString ), await( stage ) ); + verify(connection).writeAndFlush(eq(CommitMessage.COMMIT), any(CommitTxResponseHandler.class)); + assertEquals(InternalBookmark.parse(bookmarkString), await(stage)); } @Test - void shouldRollbackTransaction() - { - Connection connection = connectionMock( protocol ); + void shouldRollbackTransaction() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.rollbackTransaction( connection ); + CompletionStage stage = protocol.rollbackTransaction(connection); - verify( connection ).writeAndFlush( eq( RollbackMessage.ROLLBACK ), any( RollbackTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection).writeAndFlush(eq(RollbackMessage.ROLLBACK), any(RollbackTxResponseHandler.class)); + assertNull(await(stage)); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx65" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse(AccessMode mode) + throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx65"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse(InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx163" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse(AccessMode mode) + throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx163"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( false, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(false, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( true, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(true, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( false, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(false, mode); } @Test - void databaseNameInBeginTransaction() - { - testDatabaseNameSupport( false ); + void databaseNameInBeginTransaction() { + testDatabaseNameSupport(false); } @Test - void databaseNameForAutoCommitTransactions() - { - testDatabaseNameSupport( true ); + void databaseNameForAutoCommitTransactions() { + testDatabaseNameSupport(true); } @Test - void shouldSupportDatabaseNameInBeginTransaction() - { - CompletionStage txStage = protocol.beginTransaction( connectionMock( "foo", protocol ), InternalBookmark.empty(), TransactionConfig.empty() ); + void shouldSupportDatabaseNameInBeginTransaction() { + CompletionStage txStage = protocol.beginTransaction( + connectionMock("foo", protocol), InternalBookmark.empty(), TransactionConfig.empty()); - assertDoesNotThrow( () -> await( txStage ) ); + assertDoesNotThrow(() -> await(txStage)); } @Test - void shouldNotSupportDatabaseNameForAutoCommitTransactions() - { - assertDoesNotThrow( - () -> protocol.runInAutoCommitTransaction( connectionMock( "foo", protocol ), - new Query( "RETURN 1" ), BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ) ); + void shouldNotSupportDatabaseNameForAutoCommitTransactions() { + assertDoesNotThrow(() -> protocol.runInAutoCommitTransaction( + connectionMock("foo", protocol), + new Query("RETURN 1"), + BookmarkHolder.NO_OP, + TransactionConfig.empty(), + UNLIMITED_FETCH_SIZE)); } - private Class expectedMessageFormatType() - { + private Class expectedMessageFormatType() { return MessageFormatV4.class; } - private void testFailedRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testFailedRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to Run message with a failure Throwable error = new RuntimeException(); - runHandler.onFailure( error ); + runHandler.onFailure(error); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + Throwable actual = + assertThrows(error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } - private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to the run message - runHandler.onSuccess( emptyMap() ); + runHandler.onSuccess(emptyMap()); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - private void testRunInUnmanagedTransactionAndWaitForRunResponse( boolean success, AccessMode mode ) throws Exception - { + private void testRunInUnmanagedTransactionAndWaitForRunResponse(boolean success, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); + Connection connection = connectionMock(mode, protocol); - CompletableFuture cursorFuture = - protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifyTxRunInvoked( connection ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifyTxRunInvoked(connection); + assertFalse(cursorFuture.isDone()); Throwable error = new RuntimeException(); - if ( success ) - { - runHandler.onSuccess( emptyMap() ); - } - else - { + if (success) { + runHandler.onSuccess(emptyMap()); + } else { // When responded with a failure - runHandler.onFailure( error ); + runHandler.onFailure(error); } // Then - assertTrue( cursorFuture.isDone() ); - if ( success ) - { - assertNotNull( await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - } - else - { - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertTrue(cursorFuture.isDone()); + if (success) { + assertNotNull(await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + } else { + Throwable actual = assertThrows( + error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } } - private void testRunAndWaitForRunResponse( boolean autoCommitTx, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfig config, AccessMode mode) + throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - Bookmark initialBookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx987" ); + Connection connection = connectionMock(mode, protocol); + Bookmark initialBookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx987"); CompletionStage cursorStage; - if ( autoCommitTx ) - { - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( initialBookmark ); - cursorStage = protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult(); - } - else - { - cursorStage = protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult(); + if (autoCommitTx) { + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(initialBookmark); + cursorStage = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult(); + } else { + cursorStage = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult(); } // When & Then CompletableFuture cursorFuture = cursorStage.toCompletableFuture(); - assertFalse( cursorFuture.isDone() ); - ResponseHandler runResponseHandler = - autoCommitTx ? verifySessionRunInvoked( connection, initialBookmark, config, mode, defaultDatabase() ) : verifyTxRunInvoked( connection ); - runResponseHandler.onSuccess( emptyMap() ); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); - } - - private void testDatabaseNameSupport( boolean autoCommitTx ) - { - Connection connection = connectionMock( "foo", protocol ); - if ( autoCommitTx ) - { - ResultCursorFactory factory = - protocol.runInAutoCommitTransaction( connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ); + assertFalse(cursorFuture.isDone()); + ResponseHandler runResponseHandler = autoCommitTx + ? verifySessionRunInvoked(connection, initialBookmark, config, mode, defaultDatabase()) + : verifyTxRunInvoked(connection); + runResponseHandler.onSuccess(emptyMap()); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); + } + + private void testDatabaseNameSupport(boolean autoCommitTx) { + Connection connection = connectionMock("foo", protocol); + if (autoCommitTx) { + ResultCursorFactory factory = protocol.runInAutoCommitTransaction( + connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE); CompletionStage resultStage = factory.asyncResult(); - ResponseHandler runHandler = - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - runHandler.onSuccess( emptyMap() ); - await( resultStage ); - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - } - else - { - CompletionStage txStage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); - await( txStage ); - verifyBeginInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); + ResponseHandler runHandler = verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + runHandler.onSuccess(emptyMap()); + await(resultStage); + verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + } else { + CompletionStage txStage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); + await(txStage); + verifyBeginInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); } } - private ResponseHandler verifyTxRunInvoked( Connection connection ) - { - return verifyRunInvoked( connection, RunWithMetadataMessage.unmanagedTxRunMessage( QUERY ) ); + private ResponseHandler verifyTxRunInvoked(Connection connection) { + return verifyRunInvoked(connection, RunWithMetadataMessage.unmanagedTxRunMessage(QUERY)); } - private ResponseHandler verifySessionRunInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, - DatabaseName databaseName ) - { - RunWithMetadataMessage runMessage = RunWithMetadataMessage.autoCommitTxRunMessage( QUERY, config, databaseName, mode, bookmark, null ); - return verifyRunInvoked( connection, runMessage ); + private ResponseHandler verifySessionRunInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + RunWithMetadataMessage runMessage = + RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmark, null); + return verifyRunInvoked(connection, runMessage); } - private ResponseHandler verifyRunInvoked( Connection connection, RunWithMetadataMessage runMessage ) - { - ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); + private ResponseHandler verifyRunInvoked(Connection connection, RunWithMetadataMessage runMessage) { + ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); - verify( connection ).write( eq( runMessage ), runHandlerCaptor.capture() ); - verify( connection ).writeAndFlush( any( PullMessage.class ), pullHandlerCaptor.capture() ); + verify(connection).write(eq(runMessage), runHandlerCaptor.capture()); + verify(connection).writeAndFlush(any(PullMessage.class), pullHandlerCaptor.capture()); - assertThat( runHandlerCaptor.getValue(), instanceOf( RunResponseHandler.class ) ); - assertThat( pullHandlerCaptor.getValue(), instanceOf( PullAllResponseHandler.class ) ); + assertThat(runHandlerCaptor.getValue(), instanceOf(RunResponseHandler.class)); + assertThat(pullHandlerCaptor.getValue(), instanceOf(PullAllResponseHandler.class)); return runHandlerCaptor.getValue(); } - private void verifyBeginInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, DatabaseName databaseName ) - { - ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - BeginMessage beginMessage = new BeginMessage( bookmark, config, databaseName, mode, null ); - verify( connection ).writeAndFlush( eq( beginMessage ), beginHandlerCaptor.capture() ); - assertThat( beginHandlerCaptor.getValue(), instanceOf( BeginTxResponseHandler.class ) ); + private void verifyBeginInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + BeginMessage beginMessage = new BeginMessage(bookmark, config, databaseName, mode, null); + verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture()); + assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class)); } - private static InternalAuthToken dummyAuthToken() - { - return (InternalAuthToken) AuthTokens.basic( "hello", "world" ); + private static InternalAuthToken dummyAuthToken() { + return (InternalAuthToken) AuthTokens.basic("hello", "world"); } } - diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageFormatV41Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageFormatV41Test.java index 5d00fd1d6f..f9022534b4 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageFormatV41Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageFormatV41Test.java @@ -18,8 +18,11 @@ */ package org.neo4j.driver.internal.messaging.v41; -import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.common.CommonMessageReader; import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3; @@ -27,32 +30,25 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.mockito.Mockito.mock; - /** * The MessageFormat under tests is the one provided by the {@link BoltProtocolV3} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageFormatV41Test -{ +class MessageFormatV41Test { private static final MessageFormat format = BoltProtocolV41.INSTANCE.createMessageFormat(); @Test - void shouldCreateCorrectWriter() - { - MessageFormat.Writer writer = format.newWriter( mock( PackOutput.class ) ); + void shouldCreateCorrectWriter() { + MessageFormat.Writer writer = format.newWriter(mock(PackOutput.class)); - assertThat( writer, instanceOf( MessageWriterV4.class ) ); + assertThat(writer, instanceOf(MessageWriterV4.class)); } @Test - void shouldCreateCorrectReader() - { - MessageFormat.Reader reader = format.newReader( mock( PackInput.class ) ); + void shouldCreateCorrectReader() { + MessageFormat.Reader reader = format.newReader(mock(PackInput.class)); - assertThat( reader, instanceOf( CommonMessageReader.class ) ); + assertThat(reader, instanceOf(CommonMessageReader.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageReaderV41Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageReaderV41Test.java index 0d7f05e759..5a9b172ffb 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageReaderV41Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageReaderV41Test.java @@ -18,6 +18,18 @@ */ package org.neo4j.driver.internal.messaging.v41; +import static java.util.Arrays.asList; +import static java.util.Calendar.APRIL; +import static java.util.Calendar.AUGUST; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +39,6 @@ import java.time.ZonedDateTime; import java.util.HashMap; import java.util.stream.Stream; - import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.InternalPoint2D; @@ -42,77 +53,60 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.util.messaging.AbstractMessageReaderTestBase; -import static java.util.Arrays.asList; -import static java.util.Calendar.APRIL; -import static java.util.Calendar.AUGUST; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; - /** * The MessageReader under tests is the one provided by the {@link BoltProtocolV41} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -public class MessageReaderV41Test extends AbstractMessageReaderTestBase -{ +public class MessageReaderV41Test extends AbstractMessageReaderTestBase { @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // V2 Record types - record( value( new InternalPoint2D( 42, 120.65, -99.2 ) ) ), - record( value( new InternalPoint3D( 42, 85.391, 98.8, 11.1 ) ) ), - record( value( LocalDate.of( 2012, AUGUST, 3 ) ) ), - record( value( OffsetTime.of( 23, 59, 59, 999, ZoneOffset.MAX ) ) ), - record( value( LocalTime.of( 12, 25 ) ) ), - record( value( LocalDateTime.of( 1999, APRIL, 3, 19, 5, 5, 100_200_300 ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes( -7, -15 ) ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of( "Europe/Stockholm" ) ) ) ), - record( value( Values.isoDuration( Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1 ).asIsoDuration() ) ), - record( value( Values.isoDuration( 17, 22, 99, 15 ).asIsoDuration() ) ), + record(value(new InternalPoint2D(42, 120.65, -99.2))), + record(value(new InternalPoint3D(42, 85.391, 98.8, 11.1))), + record(value(LocalDate.of(2012, AUGUST, 3))), + record(value(OffsetTime.of(23, 59, 59, 999, ZoneOffset.MAX))), + record(value(LocalTime.of(12, 25))), + record(value(LocalDateTime.of(1999, APRIL, 3, 19, 5, 5, 100_200_300))), + record(value( + ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes(-7, -15)))), + record(value(ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of("Europe/Stockholm")))), + record(value(Values.isoDuration( + Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1) + .asIsoDuration())), + record(value(Values.isoDuration(17, 22, 99, 15).asIsoDuration())), // Bolt previous versions valid messages - new FailureMessage( "Hello", "World!" ), + new FailureMessage("Hello", "World!"), IgnoredMessage.IGNORED, - new SuccessMessage( new HashMap<>() ), - record( value( 1337L ) ), - record( value( parameters( "cat", null, "dog", null ) ) ), - record( value( parameters( "k", 12, "a", "banana" ) ) ), - record( value( asList( "k", 12, "a", "banana" ) ) ), + new SuccessMessage(new HashMap<>()), + record(value(1337L)), + record(value(parameters("cat", null, "dog", null))), + record(value(parameters("k", 12, "a", "banana"))), + record(value(asList("k", 12, "a", "banana"))), // V3 Record Types - record( emptyNodeValue() ), - record( filledNodeValue() ), - record( emptyRelationshipValue() ), - record( filledRelationshipValue() ), - record( filledPathValue() ), - record( emptyPathValue() ) - ); + record(emptyNodeValue()), + record(filledNodeValue()), + record(emptyRelationshipValue()), + record(filledRelationshipValue()), + record(filledPathValue()), + record(emptyPathValue())); } @Override - protected Stream unsupportedMessages() - { - return Stream.of( - DiscardAllMessage.DISCARD_ALL - ); + protected Stream unsupportedMessages() { + return Stream.of(DiscardAllMessage.DISCARD_ALL); } @Override - protected MessageFormat.Reader newReader( PackInput input ) - { - return BoltProtocolV41.INSTANCE.createMessageFormat().newReader( input ); + protected MessageFormat.Reader newReader(PackInput input) { + return BoltProtocolV41.INSTANCE.createMessageFormat().newReader(input); } - private Message record( Value value ) - { - return new RecordMessage( new Value[]{value} ); + private Message record(Value value) { + return new RecordMessage(new Value[] {value}); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageWriterV41Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageWriterV41Test.java index 86266f9f27..013a055fd8 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageWriterV41Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v41/MessageWriterV41Test.java @@ -18,6 +18,26 @@ */ package org.neo4j.driver.internal.messaging.v41; +import static java.time.Duration.ofSeconds; +import static java.util.Calendar.DECEMBER; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.AuthTokens.basic; +import static org.neo4j.driver.Values.point; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; +import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; +import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; +import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; +import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +47,6 @@ import java.time.ZonedDateTime; import java.util.Collections; import java.util.stream.Stream; - import org.neo4j.driver.Query; import org.neo4j.driver.internal.InternalBookmark; import org.neo4j.driver.internal.messaging.Message; @@ -40,94 +59,114 @@ import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.util.messaging.AbstractMessageWriterTestBase; -import static java.time.Duration.ofSeconds; -import static java.util.Calendar.DECEMBER; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.AuthTokens.basic; -import static org.neo4j.driver.Values.point; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; -import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; -import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; -import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; -import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; - /** * The MessageWriter under tests is the one provided by the {@link BoltProtocolV41} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageWriterV41Test extends AbstractMessageWriterTestBase -{ +class MessageWriterV41Test extends AbstractMessageWriterTestBase { @Override - protected MessageFormat.Writer newWriter( PackOutput output ) - { - return BoltProtocolV41.INSTANCE.createMessageFormat().newWriter( output ); + protected MessageFormat.Writer newWriter(PackOutput output) { + return BoltProtocolV41.INSTANCE.createMessageFormat().newWriter(output); } @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // Bolt V2 Data Types - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 12.99, -180.0 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 0.51, 2.99, 100.123 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $date", singletonMap( "date", value( LocalDate.ofEpochDay( 2147483650L ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( OffsetTime.of( 4, 16, 20, 999, ZoneOffset.MIN ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( LocalTime.of( 12, 9, 18, 999_888 ) ) ) ) ), + unmanagedTxRunMessage(new Query("RETURN $point", singletonMap("point", point(42, 12.99, -180.0)))), + unmanagedTxRunMessage( + new Query("RETURN $point", singletonMap("point", point(42, 0.51, 2.99, 100.123)))), unmanagedTxRunMessage( - new Query( "RETURN $dateTime", singletonMap( "dateTime", value( LocalDateTime.of( 2049, DECEMBER, 12, 17, 25, 49, 199 ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneOffset - .ofHoursMinutes( 9, 30 ) ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneId.of( - "Europe/Stockholm" ) ) ) ) ) ), + new Query("RETURN $date", singletonMap("date", value(LocalDate.ofEpochDay(2147483650L))))), + unmanagedTxRunMessage(new Query( + "RETURN $time", singletonMap("time", value(OffsetTime.of(4, 16, 20, 999, ZoneOffset.MIN))))), + unmanagedTxRunMessage( + new Query("RETURN $time", singletonMap("time", value(LocalTime.of(12, 9, 18, 999_888))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap("dateTime", value(LocalDateTime.of(2049, DECEMBER, 12, 17, 25, 49, 199))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of( + 2000, 1, 10, 12, 2, 49, 300, ZoneOffset.ofHoursMinutes(9, 30)))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of(2000, 1, 10, 12, 2, 49, 300, ZoneId.of("Europe/Stockholm")))))), // New Bolt V4 messages - new PullMessage( 100, 200 ), - new DiscardMessage( 300, 400 ), + new PullMessage(100, 200), + new DiscardMessage(300, 400), // Bolt V3 messages - new HelloMessage( "MyDriver/1.2.3", ((InternalAuthToken) basic( "neo4j", "neo4j" )).toMap(), Collections.emptyMap() ), + new HelloMessage( + "MyDriver/1.2.3", + ((InternalAuthToken) basic("neo4j", "neo4j")).toMap(), + Collections.emptyMap()), GOODBYE, - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), READ, - defaultDatabase(), null ), - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), WRITE, - database( "foo" ), null ), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + READ, + defaultDatabase(), + null), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + WRITE, + database("foo"), + null), COMMIT, ROLLBACK, - RESET, - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), defaultDatabase(), READ, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), database( "foo" ), WRITE, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - unmanagedTxRunMessage( new Query( "RETURN 1" ) ), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + defaultDatabase(), + READ, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + database("foo"), + WRITE, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + unmanagedTxRunMessage(new Query("RETURN 1")), // Bolt V3 messages with struct values - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - defaultDatabase(), READ, InternalBookmark.empty(), null ), - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - database( "foo" ), - WRITE, InternalBookmark.empty(), null ), - unmanagedTxRunMessage( new Query( "RETURN $x", singletonMap( "x", point( 42, 1, 2, 3 ) ) ) ) - ); + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + defaultDatabase(), + READ, + InternalBookmark.empty(), + null), + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + database("foo"), + WRITE, + InternalBookmark.empty(), + null), + unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3))))); } @Override - protected Stream unsupportedMessages() - { + protected Stream unsupportedMessages() { return Stream.of( // Bolt V1, V2 and V3 messages - PULL_ALL, - DISCARD_ALL - ); + PULL_ALL, DISCARD_ALL); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42Test.java index b163030c50..0b59ee2c6d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/BoltProtocolV42Test.java @@ -18,20 +18,47 @@ */ package org.neo4j.driver.internal.messaging.v42; +import static java.time.Duration.ofSeconds; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; +import static org.neo4j.driver.util.TestUtil.await; +import static org.neo4j.driver.util.TestUtil.connectionMock; + import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.mockito.ArgumentCaptor; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Bookmark; @@ -68,475 +95,435 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.time.Duration.ofSeconds; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; -import static org.neo4j.driver.util.TestUtil.await; -import static org.neo4j.driver.util.TestUtil.connectionMock; - -public final class BoltProtocolV42Test -{ +public final class BoltProtocolV42Test { protected static final String QUERY_TEXT = "RETURN $x"; - protected static final Map PARAMS = singletonMap( "x", value( 42 ) ); - protected static final Query QUERY = new Query( QUERY_TEXT, value( PARAMS ) ); + protected static final Map PARAMS = singletonMap("x", value(42)); + protected static final Query QUERY = new Query(QUERY_TEXT, value(PARAMS)); protected final BoltProtocol protocol = createProtocol(); private final EmbeddedChannel channel = new EmbeddedChannel(); - private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher( channel, Logging.none() ); + private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher(channel, Logging.none()); private final TransactionConfig txConfig = TransactionConfig.builder() - .withTimeout( ofSeconds( 12 ) ) - .withMetadata( singletonMap( "key", value( 42 ) ) ) - .build(); + .withTimeout(ofSeconds(12)) + .withMetadata(singletonMap("key", value(42))) + .build(); - protected BoltProtocol createProtocol() - { + protected BoltProtocol createProtocol() { return BoltProtocolV42.INSTANCE; } @BeforeEach - void beforeEach() - { - ChannelAttributes.setMessageDispatcher( channel, messageDispatcher ); + void beforeEach() { + ChannelAttributes.setMessageDispatcher(channel, messageDispatcher); } @AfterEach - void afterEach() - { + void afterEach() { channel.finishAndReleaseAll(); } @Test - void shouldCreateMessageFormat() - { - assertThat( protocol.createMessageFormat(), instanceOf( expectedMessageFormatType() ) ); + void shouldCreateMessageFormat() { + assertThat(protocol.createMessageFormat(), instanceOf(expectedMessageFormatType())); } @Test - void shouldInitializeChannel() - { + void shouldInitializeChannel() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - Map metadata = new HashMap<>(); - metadata.put( "server", value( anyServerVersion().toString() ) ); - metadata.put( "connection_id", value( "bolt-42" ) ); + Map metadata = new HashMap<>(); + metadata.put("server", value(anyServerVersion().toString())); + metadata.put("connection_id", value("bolt-42")); - messageDispatcher.handleSuccessMessage( metadata ); + messageDispatcher.handleSuccessMessage(metadata); - assertTrue( promise.isDone() ); - assertTrue( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertTrue(promise.isSuccess()); } @Test - void shouldPrepareToCloseChannel() - { - protocol.prepareToCloseChannel( channel ); + void shouldPrepareToCloseChannel() { + protocol.prepareToCloseChannel(channel); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( GoodbyeMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(GoodbyeMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); } @Test - void shouldFailToInitializeChannelWhenErrorIsReceived() - { + void shouldFailToInitializeChannelWhenErrorIsReceived() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - messageDispatcher.handleFailureMessage( "Neo.TransientError.General.DatabaseUnavailable", "Error!" ); + messageDispatcher.handleFailureMessage("Neo.TransientError.General.DatabaseUnavailable", "Error!"); - assertTrue( promise.isDone() ); - assertFalse( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertFalse(promise.isSuccess()); } @Test - void shouldBeginTransactionWithoutBookmark() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithoutBookmark() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); + CompletionStage stage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage( + InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarks() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx100" ); + void shouldBeginTransactionWithBookmarks() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx100"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, TransactionConfig.empty() ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithConfig() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithConfig() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, InternalBookmark.empty(), txConfig); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarksAndConfig() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx4242" ); + void shouldBeginTransactionWithBookmarksAndConfig() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx4242"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, txConfig); - verify( connection ).writeAndFlush( eq( new BeginMessage( bookmark, txConfig, defaultDatabase(), WRITE, null ) ), any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldCommitTransaction() - { + void shouldCommitTransaction() { String bookmarkString = "neo4j:bookmark:v1:tx4242"; - Connection connection = connectionMock( protocol ); - when( connection.protocol() ).thenReturn( protocol ); - doAnswer( invocation -> - { - ResponseHandler commitHandler = invocation.getArgument( 1 ); - commitHandler.onSuccess( singletonMap( "bookmark", value( bookmarkString ) ) ); - return null; - } ).when( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any() ); + Connection connection = connectionMock(protocol); + when(connection.protocol()).thenReturn(protocol); + doAnswer(invocation -> { + ResponseHandler commitHandler = invocation.getArgument(1); + commitHandler.onSuccess(singletonMap("bookmark", value(bookmarkString))); + return null; + }) + .when(connection) + .writeAndFlush(eq(CommitMessage.COMMIT), any()); - CompletionStage stage = protocol.commitTransaction( connection ); + CompletionStage stage = protocol.commitTransaction(connection); - verify( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any( CommitTxResponseHandler.class ) ); - assertEquals( InternalBookmark.parse( bookmarkString ), await( stage ) ); + verify(connection).writeAndFlush(eq(CommitMessage.COMMIT), any(CommitTxResponseHandler.class)); + assertEquals(InternalBookmark.parse(bookmarkString), await(stage)); } @Test - void shouldRollbackTransaction() - { - Connection connection = connectionMock( protocol ); + void shouldRollbackTransaction() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.rollbackTransaction( connection ); + CompletionStage stage = protocol.rollbackTransaction(connection); - verify( connection ).writeAndFlush( eq( RollbackMessage.ROLLBACK ), any( RollbackTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection).writeAndFlush(eq(RollbackMessage.ROLLBACK), any(RollbackTxResponseHandler.class)); + assertNull(await(stage)); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx65" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse(AccessMode mode) + throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx65"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse(InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx163" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse(AccessMode mode) + throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx163"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( false, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(false, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( true, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(true, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( false, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(false, mode); } @Test - void databaseNameInBeginTransaction() - { - testDatabaseNameSupport( false ); + void databaseNameInBeginTransaction() { + testDatabaseNameSupport(false); } @Test - void databaseNameForAutoCommitTransactions() - { - testDatabaseNameSupport( true ); + void databaseNameForAutoCommitTransactions() { + testDatabaseNameSupport(true); } @Test - void shouldSupportDatabaseNameInBeginTransaction() - { - CompletionStage txStage = protocol.beginTransaction( connectionMock( "foo", protocol ), InternalBookmark.empty(), TransactionConfig.empty() ); + void shouldSupportDatabaseNameInBeginTransaction() { + CompletionStage txStage = protocol.beginTransaction( + connectionMock("foo", protocol), InternalBookmark.empty(), TransactionConfig.empty()); - assertDoesNotThrow( () -> await( txStage ) ); + assertDoesNotThrow(() -> await(txStage)); } @Test - void shouldNotSupportDatabaseNameForAutoCommitTransactions() - { - assertDoesNotThrow( - () -> protocol.runInAutoCommitTransaction( connectionMock( "foo", protocol ), - new Query( "RETURN 1" ), BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ) ); + void shouldNotSupportDatabaseNameForAutoCommitTransactions() { + assertDoesNotThrow(() -> protocol.runInAutoCommitTransaction( + connectionMock("foo", protocol), + new Query("RETURN 1"), + BookmarkHolder.NO_OP, + TransactionConfig.empty(), + UNLIMITED_FETCH_SIZE)); } - private Class expectedMessageFormatType() - { + private Class expectedMessageFormatType() { return MessageFormatV4.class; } - private void testFailedRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testFailedRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to Run message with a failure Throwable error = new RuntimeException(); - runHandler.onFailure( error ); + runHandler.onFailure(error); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + Throwable actual = + assertThrows(error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } - private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to the run message - runHandler.onSuccess( emptyMap() ); + runHandler.onSuccess(emptyMap()); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - private void testRunInUnmanagedTransactionAndWaitForRunResponse( boolean success, AccessMode mode ) throws Exception - { + private void testRunInUnmanagedTransactionAndWaitForRunResponse(boolean success, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); + Connection connection = connectionMock(mode, protocol); - CompletableFuture cursorFuture = - protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifyTxRunInvoked( connection ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifyTxRunInvoked(connection); + assertFalse(cursorFuture.isDone()); Throwable error = new RuntimeException(); - if ( success ) - { - runHandler.onSuccess( emptyMap() ); - } - else - { + if (success) { + runHandler.onSuccess(emptyMap()); + } else { // When responded with a failure - runHandler.onFailure( error ); + runHandler.onFailure(error); } // Then - assertTrue( cursorFuture.isDone() ); - if ( success ) - { - assertNotNull( await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - } - else - { - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertTrue(cursorFuture.isDone()); + if (success) { + assertNotNull(await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + } else { + Throwable actual = assertThrows( + error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } } - private void testRunAndWaitForRunResponse( boolean autoCommitTx, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfig config, AccessMode mode) + throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - Bookmark initialBookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx987" ); + Connection connection = connectionMock(mode, protocol); + Bookmark initialBookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx987"); CompletionStage cursorStage; - if ( autoCommitTx ) - { - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( initialBookmark ); - cursorStage = protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult(); - } - else - { - cursorStage = protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult(); + if (autoCommitTx) { + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(initialBookmark); + cursorStage = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult(); + } else { + cursorStage = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult(); } // When & Then CompletableFuture cursorFuture = cursorStage.toCompletableFuture(); - assertFalse( cursorFuture.isDone() ); + assertFalse(cursorFuture.isDone()); - ResponseHandler runResponseHandler = - autoCommitTx ? verifySessionRunInvoked( connection, initialBookmark, config, mode, defaultDatabase() ) : verifyTxRunInvoked( connection ); - runResponseHandler.onSuccess( emptyMap() ); + ResponseHandler runResponseHandler = autoCommitTx + ? verifySessionRunInvoked(connection, initialBookmark, config, mode, defaultDatabase()) + : verifyTxRunInvoked(connection); + runResponseHandler.onSuccess(emptyMap()); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - private void testDatabaseNameSupport( boolean autoCommitTx ) - { - Connection connection = connectionMock( "foo", protocol ); - if ( autoCommitTx ) - { - ResultCursorFactory factory = - protocol.runInAutoCommitTransaction( connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ); + private void testDatabaseNameSupport(boolean autoCommitTx) { + Connection connection = connectionMock("foo", protocol); + if (autoCommitTx) { + ResultCursorFactory factory = protocol.runInAutoCommitTransaction( + connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE); CompletionStage resultStage = factory.asyncResult(); - ResponseHandler runHandler = - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - runHandler.onSuccess( emptyMap() ); - await( resultStage ); - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - } - else - { - CompletionStage txStage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); - await( txStage ); - verifyBeginInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); + ResponseHandler runHandler = verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + runHandler.onSuccess(emptyMap()); + await(resultStage); + verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + } else { + CompletionStage txStage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); + await(txStage); + verifyBeginInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); } } - private ResponseHandler verifyTxRunInvoked( Connection connection ) - { - return verifyRunInvoked( connection, RunWithMetadataMessage.unmanagedTxRunMessage( QUERY ) ); + private ResponseHandler verifyTxRunInvoked(Connection connection) { + return verifyRunInvoked(connection, RunWithMetadataMessage.unmanagedTxRunMessage(QUERY)); } - private ResponseHandler verifySessionRunInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, - DatabaseName databaseName ) - { - RunWithMetadataMessage runMessage = RunWithMetadataMessage.autoCommitTxRunMessage( QUERY, config, databaseName, mode, bookmark, null ); - return verifyRunInvoked( connection, runMessage ); + private ResponseHandler verifySessionRunInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + RunWithMetadataMessage runMessage = + RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmark, null); + return verifyRunInvoked(connection, runMessage); } - private ResponseHandler verifyRunInvoked( Connection connection, RunWithMetadataMessage runMessage ) - { - ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); + private ResponseHandler verifyRunInvoked(Connection connection, RunWithMetadataMessage runMessage) { + ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); - verify( connection ).write( eq( runMessage ), runHandlerCaptor.capture() ); - verify( connection ).writeAndFlush( any( PullMessage.class ), pullHandlerCaptor.capture() ); + verify(connection).write(eq(runMessage), runHandlerCaptor.capture()); + verify(connection).writeAndFlush(any(PullMessage.class), pullHandlerCaptor.capture()); - assertThat( runHandlerCaptor.getValue(), instanceOf( RunResponseHandler.class ) ); - assertThat( pullHandlerCaptor.getValue(), instanceOf( PullAllResponseHandler.class ) ); + assertThat(runHandlerCaptor.getValue(), instanceOf(RunResponseHandler.class)); + assertThat(pullHandlerCaptor.getValue(), instanceOf(PullAllResponseHandler.class)); return runHandlerCaptor.getValue(); } - private void verifyBeginInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, DatabaseName databaseName ) - { - ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - BeginMessage beginMessage = new BeginMessage( bookmark, config, databaseName, mode, null ); - verify( connection ).writeAndFlush( eq( beginMessage ), beginHandlerCaptor.capture() ); - assertThat( beginHandlerCaptor.getValue(), instanceOf( BeginTxResponseHandler.class ) ); + private void verifyBeginInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + BeginMessage beginMessage = new BeginMessage(bookmark, config, databaseName, mode, null); + verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture()); + assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class)); } - private static InternalAuthToken dummyAuthToken() - { - return (InternalAuthToken) AuthTokens.basic( "hello", "world" ); + private static InternalAuthToken dummyAuthToken() { + return (InternalAuthToken) AuthTokens.basic("hello", "world"); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageFormatV42Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageFormatV42Test.java index a110f8eaae..0338001377 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageFormatV42Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageFormatV42Test.java @@ -18,40 +18,36 @@ */ package org.neo4j.driver.internal.messaging.v42; -import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.common.CommonMessageReader; import org.neo4j.driver.internal.messaging.v4.MessageWriterV4; import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.mockito.Mockito.mock; - /** * The MessageFormat under tests is the one provided by the {@link BoltProtocolV42} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageFormatV42Test -{ +class MessageFormatV42Test { private static final MessageFormat format = BoltProtocolV42.INSTANCE.createMessageFormat(); @Test - void shouldCreateCorrectWriter() - { - MessageFormat.Writer writer = format.newWriter( mock( PackOutput.class ) ); + void shouldCreateCorrectWriter() { + MessageFormat.Writer writer = format.newWriter(mock(PackOutput.class)); - assertThat( writer, instanceOf( MessageWriterV4.class ) ); + assertThat(writer, instanceOf(MessageWriterV4.class)); } @Test - void shouldCreateCorrectReader() - { - MessageFormat.Reader reader = format.newReader( mock( PackInput.class ) ); + void shouldCreateCorrectReader() { + MessageFormat.Reader reader = format.newReader(mock(PackInput.class)); - assertThat( reader, instanceOf( CommonMessageReader.class ) ); + assertThat(reader, instanceOf(CommonMessageReader.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageReaderV42Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageReaderV42Test.java index b29b5039d0..a07e2a0426 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageReaderV42Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageReaderV42Test.java @@ -18,6 +18,18 @@ */ package org.neo4j.driver.internal.messaging.v42; +import static java.util.Arrays.asList; +import static java.util.Calendar.APRIL; +import static java.util.Calendar.AUGUST; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +39,6 @@ import java.time.ZonedDateTime; import java.util.HashMap; import java.util.stream.Stream; - import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.InternalPoint2D; @@ -42,77 +53,60 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.util.messaging.AbstractMessageReaderTestBase; -import static java.util.Arrays.asList; -import static java.util.Calendar.APRIL; -import static java.util.Calendar.AUGUST; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; - /** * The MessageReader under tests is the one provided by the {@link BoltProtocolV42} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -public class MessageReaderV42Test extends AbstractMessageReaderTestBase -{ +public class MessageReaderV42Test extends AbstractMessageReaderTestBase { @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // V2 Record types - record( value( new InternalPoint2D( 42, 120.65, -99.2 ) ) ), - record( value( new InternalPoint3D( 42, 85.391, 98.8, 11.1 ) ) ), - record( value( LocalDate.of( 2012, AUGUST, 3 ) ) ), - record( value( OffsetTime.of( 23, 59, 59, 999, ZoneOffset.MAX ) ) ), - record( value( LocalTime.of( 12, 25 ) ) ), - record( value( LocalDateTime.of( 1999, APRIL, 3, 19, 5, 5, 100_200_300 ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes( -7, -15 ) ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of( "Europe/Stockholm" ) ) ) ), - record( value( Values.isoDuration( Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1 ).asIsoDuration() ) ), - record( value( Values.isoDuration( 17, 22, 99, 15 ).asIsoDuration() ) ), + record(value(new InternalPoint2D(42, 120.65, -99.2))), + record(value(new InternalPoint3D(42, 85.391, 98.8, 11.1))), + record(value(LocalDate.of(2012, AUGUST, 3))), + record(value(OffsetTime.of(23, 59, 59, 999, ZoneOffset.MAX))), + record(value(LocalTime.of(12, 25))), + record(value(LocalDateTime.of(1999, APRIL, 3, 19, 5, 5, 100_200_300))), + record(value( + ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes(-7, -15)))), + record(value(ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of("Europe/Stockholm")))), + record(value(Values.isoDuration( + Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1) + .asIsoDuration())), + record(value(Values.isoDuration(17, 22, 99, 15).asIsoDuration())), // Bolt previous versions valid messages - new FailureMessage( "Hello", "World!" ), + new FailureMessage("Hello", "World!"), IgnoredMessage.IGNORED, - new SuccessMessage( new HashMap<>() ), - record( value( 1337L ) ), - record( value( parameters( "cat", null, "dog", null ) ) ), - record( value( parameters( "k", 12, "a", "banana" ) ) ), - record( value( asList( "k", 12, "a", "banana" ) ) ), + new SuccessMessage(new HashMap<>()), + record(value(1337L)), + record(value(parameters("cat", null, "dog", null))), + record(value(parameters("k", 12, "a", "banana"))), + record(value(asList("k", 12, "a", "banana"))), // V3 Record Types - record( emptyNodeValue() ), - record( filledNodeValue() ), - record( emptyRelationshipValue() ), - record( filledRelationshipValue() ), - record( filledPathValue() ), - record( emptyPathValue() ) - ); + record(emptyNodeValue()), + record(filledNodeValue()), + record(emptyRelationshipValue()), + record(filledRelationshipValue()), + record(filledPathValue()), + record(emptyPathValue())); } @Override - protected Stream unsupportedMessages() - { - return Stream.of( - DiscardAllMessage.DISCARD_ALL - ); + protected Stream unsupportedMessages() { + return Stream.of(DiscardAllMessage.DISCARD_ALL); } @Override - protected MessageFormat.Reader newReader( PackInput input ) - { - return BoltProtocolV42.INSTANCE.createMessageFormat().newReader( input ); + protected MessageFormat.Reader newReader(PackInput input) { + return BoltProtocolV42.INSTANCE.createMessageFormat().newReader(input); } - private Message record( Value value ) - { - return new RecordMessage( new Value[]{value} ); + private Message record(Value value) { + return new RecordMessage(new Value[] {value}); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageWriterV42Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageWriterV42Test.java index 8ebd7217bd..9203114173 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageWriterV42Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v42/MessageWriterV42Test.java @@ -18,6 +18,26 @@ */ package org.neo4j.driver.internal.messaging.v42; +import static java.time.Duration.ofSeconds; +import static java.util.Calendar.DECEMBER; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.AuthTokens.basic; +import static org.neo4j.driver.Values.point; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; +import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; +import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; +import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; +import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +47,6 @@ import java.time.ZonedDateTime; import java.util.Collections; import java.util.stream.Stream; - import org.neo4j.driver.Query; import org.neo4j.driver.internal.InternalBookmark; import org.neo4j.driver.internal.messaging.Message; @@ -40,94 +59,114 @@ import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.util.messaging.AbstractMessageWriterTestBase; -import static java.time.Duration.ofSeconds; -import static java.util.Calendar.DECEMBER; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.AuthTokens.basic; -import static org.neo4j.driver.Values.point; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; -import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; -import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; -import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; -import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; - /** * The MessageWriter under tests is the one provided by the {@link BoltProtocolV42} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageWriterV42Test extends AbstractMessageWriterTestBase -{ +class MessageWriterV42Test extends AbstractMessageWriterTestBase { @Override - protected MessageFormat.Writer newWriter( PackOutput output ) - { - return BoltProtocolV42.INSTANCE.createMessageFormat().newWriter( output ); + protected MessageFormat.Writer newWriter(PackOutput output) { + return BoltProtocolV42.INSTANCE.createMessageFormat().newWriter(output); } @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // Bolt V2 Data Types - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 12.99, -180.0 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 0.51, 2.99, 100.123 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $date", singletonMap( "date", value( LocalDate.ofEpochDay( 2147483650L ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( OffsetTime.of( 4, 16, 20, 999, ZoneOffset.MIN ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( LocalTime.of( 12, 9, 18, 999_888 ) ) ) ) ), + unmanagedTxRunMessage(new Query("RETURN $point", singletonMap("point", point(42, 12.99, -180.0)))), + unmanagedTxRunMessage( + new Query("RETURN $point", singletonMap("point", point(42, 0.51, 2.99, 100.123)))), unmanagedTxRunMessage( - new Query( "RETURN $dateTime", singletonMap( "dateTime", value( LocalDateTime.of( 2049, DECEMBER, 12, 17, 25, 49, 199 ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneOffset - .ofHoursMinutes( 9, 30 ) ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneId.of( - "Europe/Stockholm" ) ) ) ) ) ), + new Query("RETURN $date", singletonMap("date", value(LocalDate.ofEpochDay(2147483650L))))), + unmanagedTxRunMessage(new Query( + "RETURN $time", singletonMap("time", value(OffsetTime.of(4, 16, 20, 999, ZoneOffset.MIN))))), + unmanagedTxRunMessage( + new Query("RETURN $time", singletonMap("time", value(LocalTime.of(12, 9, 18, 999_888))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap("dateTime", value(LocalDateTime.of(2049, DECEMBER, 12, 17, 25, 49, 199))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of( + 2000, 1, 10, 12, 2, 49, 300, ZoneOffset.ofHoursMinutes(9, 30)))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of(2000, 1, 10, 12, 2, 49, 300, ZoneId.of("Europe/Stockholm")))))), // New Bolt V4 messages - new PullMessage( 100, 200 ), - new DiscardMessage( 300, 400 ), + new PullMessage(100, 200), + new DiscardMessage(300, 400), // Bolt V3 messages - new HelloMessage( "MyDriver/1.2.3", ((InternalAuthToken) basic( "neo4j", "neo4j" )).toMap(), Collections.emptyMap() ), + new HelloMessage( + "MyDriver/1.2.3", + ((InternalAuthToken) basic("neo4j", "neo4j")).toMap(), + Collections.emptyMap()), GOODBYE, - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), READ, - defaultDatabase(), null ), - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), WRITE, - database( "foo" ), null ), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + READ, + defaultDatabase(), + null), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + WRITE, + database("foo"), + null), COMMIT, ROLLBACK, - RESET, - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), defaultDatabase(), READ, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), database( "foo" ), WRITE, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - unmanagedTxRunMessage( new Query( "RETURN 1" ) ), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + defaultDatabase(), + READ, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + database("foo"), + WRITE, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + unmanagedTxRunMessage(new Query("RETURN 1")), // Bolt V3 messages with struct values - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - defaultDatabase(), READ, InternalBookmark.empty(), null ), - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - database( "foo" ), - WRITE, InternalBookmark.empty(), null ), - unmanagedTxRunMessage( new Query( "RETURN $x", singletonMap( "x", point( 42, 1, 2, 3 ) ) ) ) - ); + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + defaultDatabase(), + READ, + InternalBookmark.empty(), + null), + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + database("foo"), + WRITE, + InternalBookmark.empty(), + null), + unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3))))); } @Override - protected Stream unsupportedMessages() - { + protected Stream unsupportedMessages() { return Stream.of( // Bolt V1, V2 and V3 messages - PULL_ALL, - DISCARD_ALL - ); + PULL_ALL, DISCARD_ALL); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43Test.java index d8b2ee13c8..8634eed270 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/BoltProtocolV43Test.java @@ -18,20 +18,47 @@ */ package org.neo4j.driver.internal.messaging.v43; +import static java.time.Duration.ofSeconds; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; +import static org.neo4j.driver.util.TestUtil.await; +import static org.neo4j.driver.util.TestUtil.connectionMock; + import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.mockito.ArgumentCaptor; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Bookmark; @@ -67,476 +94,436 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.time.Duration.ofSeconds; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; -import static org.neo4j.driver.util.TestUtil.await; -import static org.neo4j.driver.util.TestUtil.connectionMock; - -public final class BoltProtocolV43Test -{ +public final class BoltProtocolV43Test { protected static final String QUERY_TEXT = "RETURN $x"; - protected static final Map PARAMS = singletonMap( "x", value( 42 ) ); - protected static final Query QUERY = new Query( QUERY_TEXT, value( PARAMS ) ); + protected static final Map PARAMS = singletonMap("x", value(42)); + protected static final Query QUERY = new Query(QUERY_TEXT, value(PARAMS)); protected final BoltProtocol protocol = createProtocol(); private final EmbeddedChannel channel = new EmbeddedChannel(); - private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher( channel, Logging.none() ); + private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher(channel, Logging.none()); private final TransactionConfig txConfig = TransactionConfig.builder() - .withTimeout( ofSeconds( 12 ) ) - .withMetadata( singletonMap( "key", value( 42 ) ) ) - .build(); + .withTimeout(ofSeconds(12)) + .withMetadata(singletonMap("key", value(42))) + .build(); - protected BoltProtocol createProtocol() - { + protected BoltProtocol createProtocol() { return BoltProtocolV43.INSTANCE; } @BeforeEach - void beforeEach() - { - ChannelAttributes.setMessageDispatcher( channel, messageDispatcher ); + void beforeEach() { + ChannelAttributes.setMessageDispatcher(channel, messageDispatcher); } @AfterEach - void afterEach() - { + void afterEach() { channel.finishAndReleaseAll(); } @Test - void shouldCreateMessageFormat() - { - assertThat( protocol.createMessageFormat(), instanceOf( expectedMessageFormatType() ) ); + void shouldCreateMessageFormat() { + assertThat(protocol.createMessageFormat(), instanceOf(expectedMessageFormatType())); } @Test - void shouldInitializeChannel() - { + void shouldInitializeChannel() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - Map metadata = new HashMap<>(); - metadata.put( "server", value( anyServerVersion().toString() ) ); - metadata.put( "connection_id", value( "bolt-42" ) ); + Map metadata = new HashMap<>(); + metadata.put("server", value(anyServerVersion().toString())); + metadata.put("connection_id", value("bolt-42")); - messageDispatcher.handleSuccessMessage( metadata ); + messageDispatcher.handleSuccessMessage(metadata); - assertTrue( promise.isDone() ); - assertTrue( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertTrue(promise.isSuccess()); } @Test - void shouldPrepareToCloseChannel() - { - protocol.prepareToCloseChannel( channel ); + void shouldPrepareToCloseChannel() { + protocol.prepareToCloseChannel(channel); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( GoodbyeMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(GoodbyeMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); } @Test - void shouldFailToInitializeChannelWhenErrorIsReceived() - { + void shouldFailToInitializeChannelWhenErrorIsReceived() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - messageDispatcher.handleFailureMessage( "Neo.TransientError.General.DatabaseUnavailable", "Error!" ); + messageDispatcher.handleFailureMessage("Neo.TransientError.General.DatabaseUnavailable", "Error!"); - assertTrue( promise.isDone() ); - assertFalse( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertFalse(promise.isSuccess()); } @Test - void shouldBeginTransactionWithoutBookmark() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithoutBookmark() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); + CompletionStage stage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage( + InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarks() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx100" ); + void shouldBeginTransactionWithBookmarks() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx100"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, TransactionConfig.empty() ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithConfig() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithConfig() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, InternalBookmark.empty(), txConfig); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarksAndConfig() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx4242" ); + void shouldBeginTransactionWithBookmarksAndConfig() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx4242"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, txConfig); - verify( connection ).writeAndFlush( eq( new BeginMessage( bookmark, txConfig, defaultDatabase(), WRITE, null ) ), any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldCommitTransaction() - { + void shouldCommitTransaction() { String bookmarkString = "neo4j:bookmark:v1:tx4242"; - Connection connection = connectionMock( protocol ); - when( connection.protocol() ).thenReturn( protocol ); - doAnswer( invocation -> - { - ResponseHandler commitHandler = invocation.getArgument( 1 ); - commitHandler.onSuccess( singletonMap( "bookmark", value( bookmarkString ) ) ); - return null; - } ).when( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any() ); + Connection connection = connectionMock(protocol); + when(connection.protocol()).thenReturn(protocol); + doAnswer(invocation -> { + ResponseHandler commitHandler = invocation.getArgument(1); + commitHandler.onSuccess(singletonMap("bookmark", value(bookmarkString))); + return null; + }) + .when(connection) + .writeAndFlush(eq(CommitMessage.COMMIT), any()); - CompletionStage stage = protocol.commitTransaction( connection ); + CompletionStage stage = protocol.commitTransaction(connection); - verify( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any( CommitTxResponseHandler.class ) ); - assertEquals( InternalBookmark.parse( bookmarkString ), await( stage ) ); + verify(connection).writeAndFlush(eq(CommitMessage.COMMIT), any(CommitTxResponseHandler.class)); + assertEquals(InternalBookmark.parse(bookmarkString), await(stage)); } @Test - void shouldRollbackTransaction() - { - Connection connection = connectionMock( protocol ); + void shouldRollbackTransaction() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.rollbackTransaction( connection ); + CompletionStage stage = protocol.rollbackTransaction(connection); - verify( connection ).writeAndFlush( eq( RollbackMessage.ROLLBACK ), any( RollbackTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection).writeAndFlush(eq(RollbackMessage.ROLLBACK), any(RollbackTxResponseHandler.class)); + assertNull(await(stage)); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx65" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse(AccessMode mode) + throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx65"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse(InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx163" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse(AccessMode mode) + throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx163"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( false, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(false, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( true, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(true, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( false, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(false, mode); } @Test - void databaseNameInBeginTransaction() - { - testDatabaseNameSupport( false ); + void databaseNameInBeginTransaction() { + testDatabaseNameSupport(false); } @Test - void databaseNameForAutoCommitTransactions() - { - testDatabaseNameSupport( true ); + void databaseNameForAutoCommitTransactions() { + testDatabaseNameSupport(true); } @Test - void shouldSupportDatabaseNameInBeginTransaction() - { - CompletionStage txStage = protocol.beginTransaction( connectionMock( "foo", protocol ), InternalBookmark.empty(), TransactionConfig.empty() ); + void shouldSupportDatabaseNameInBeginTransaction() { + CompletionStage txStage = protocol.beginTransaction( + connectionMock("foo", protocol), InternalBookmark.empty(), TransactionConfig.empty()); - assertDoesNotThrow( () -> await( txStage ) ); + assertDoesNotThrow(() -> await(txStage)); } @Test - void shouldNotSupportDatabaseNameForAutoCommitTransactions() - { - assertDoesNotThrow( - () -> protocol.runInAutoCommitTransaction( connectionMock( "foo", protocol ), - new Query( "RETURN 1" ), BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ) ); + void shouldNotSupportDatabaseNameForAutoCommitTransactions() { + assertDoesNotThrow(() -> protocol.runInAutoCommitTransaction( + connectionMock("foo", protocol), + new Query("RETURN 1"), + BookmarkHolder.NO_OP, + TransactionConfig.empty(), + UNLIMITED_FETCH_SIZE)); } - private Class expectedMessageFormatType() - { + private Class expectedMessageFormatType() { return MessageFormatV43.class; } - private void testFailedRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testFailedRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to Run message with a failure Throwable error = new RuntimeException(); - runHandler.onFailure( error ); + runHandler.onFailure(error); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + Throwable actual = + assertThrows(error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } - private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to the run message - runHandler.onSuccess( emptyMap() ); + runHandler.onSuccess(emptyMap()); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - private void testRunInUnmanagedTransactionAndWaitForRunResponse( boolean success, AccessMode mode ) throws Exception - { + private void testRunInUnmanagedTransactionAndWaitForRunResponse(boolean success, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); + Connection connection = connectionMock(mode, protocol); - CompletableFuture cursorFuture = - protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifyTxRunInvoked( connection ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifyTxRunInvoked(connection); + assertFalse(cursorFuture.isDone()); Throwable error = new RuntimeException(); - if ( success ) - { - runHandler.onSuccess( emptyMap() ); - } - else - { + if (success) { + runHandler.onSuccess(emptyMap()); + } else { // When responded with a failure - runHandler.onFailure( error ); + runHandler.onFailure(error); } // Then - assertTrue( cursorFuture.isDone() ); - if ( success ) - { - assertNotNull( await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - } - else - { - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertTrue(cursorFuture.isDone()); + if (success) { + assertNotNull(await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + } else { + Throwable actual = assertThrows( + error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } } - private void testRunAndWaitForRunResponse( boolean autoCommitTx, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfig config, AccessMode mode) + throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - Bookmark initialBookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx987" ); + Connection connection = connectionMock(mode, protocol); + Bookmark initialBookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx987"); CompletionStage cursorStage; - if ( autoCommitTx ) - { - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( initialBookmark ); - cursorStage = protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult(); - } - else - { - cursorStage = protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult(); + if (autoCommitTx) { + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(initialBookmark); + cursorStage = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult(); + } else { + cursorStage = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult(); } // When & Then CompletableFuture cursorFuture = cursorStage.toCompletableFuture(); - assertFalse( cursorFuture.isDone() ); + assertFalse(cursorFuture.isDone()); - ResponseHandler runResponseHandler = - autoCommitTx ? verifySessionRunInvoked( connection, initialBookmark, config, mode, defaultDatabase() ) : verifyTxRunInvoked( connection ); - runResponseHandler.onSuccess( emptyMap() ); + ResponseHandler runResponseHandler = autoCommitTx + ? verifySessionRunInvoked(connection, initialBookmark, config, mode, defaultDatabase()) + : verifyTxRunInvoked(connection); + runResponseHandler.onSuccess(emptyMap()); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - private void testDatabaseNameSupport( boolean autoCommitTx ) - { - Connection connection = connectionMock( "foo", protocol ); - if ( autoCommitTx ) - { - ResultCursorFactory factory = - protocol.runInAutoCommitTransaction( connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ); + private void testDatabaseNameSupport(boolean autoCommitTx) { + Connection connection = connectionMock("foo", protocol); + if (autoCommitTx) { + ResultCursorFactory factory = protocol.runInAutoCommitTransaction( + connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE); CompletionStage resultStage = factory.asyncResult(); - ResponseHandler runHandler = - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - runHandler.onSuccess( emptyMap() ); - await( resultStage ); - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - } - else - { - CompletionStage txStage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); - await( txStage ); - verifyBeginInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); + ResponseHandler runHandler = verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + runHandler.onSuccess(emptyMap()); + await(resultStage); + verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + } else { + CompletionStage txStage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); + await(txStage); + verifyBeginInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); } } - private ResponseHandler verifyTxRunInvoked( Connection connection ) - { - return verifyRunInvoked( connection, RunWithMetadataMessage.unmanagedTxRunMessage( QUERY ) ); + private ResponseHandler verifyTxRunInvoked(Connection connection) { + return verifyRunInvoked(connection, RunWithMetadataMessage.unmanagedTxRunMessage(QUERY)); } - private ResponseHandler verifySessionRunInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, - DatabaseName databaseName ) - { - RunWithMetadataMessage runMessage = RunWithMetadataMessage.autoCommitTxRunMessage( QUERY, config, databaseName, mode, bookmark, null ); - return verifyRunInvoked( connection, runMessage ); + private ResponseHandler verifySessionRunInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + RunWithMetadataMessage runMessage = + RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmark, null); + return verifyRunInvoked(connection, runMessage); } - private ResponseHandler verifyRunInvoked( Connection connection, RunWithMetadataMessage runMessage ) - { - ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); + private ResponseHandler verifyRunInvoked(Connection connection, RunWithMetadataMessage runMessage) { + ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); - verify( connection ).write( eq( runMessage ), runHandlerCaptor.capture() ); - verify( connection ).writeAndFlush( any( PullMessage.class ), pullHandlerCaptor.capture() ); + verify(connection).write(eq(runMessage), runHandlerCaptor.capture()); + verify(connection).writeAndFlush(any(PullMessage.class), pullHandlerCaptor.capture()); - assertThat( runHandlerCaptor.getValue(), instanceOf( RunResponseHandler.class ) ); - assertThat( pullHandlerCaptor.getValue(), instanceOf( PullAllResponseHandler.class ) ); + assertThat(runHandlerCaptor.getValue(), instanceOf(RunResponseHandler.class)); + assertThat(pullHandlerCaptor.getValue(), instanceOf(PullAllResponseHandler.class)); return runHandlerCaptor.getValue(); } - private void verifyBeginInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, DatabaseName databaseName ) - { - ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - BeginMessage beginMessage = new BeginMessage( bookmark, config, databaseName, mode, null ); - verify( connection ).writeAndFlush( eq( beginMessage ), beginHandlerCaptor.capture() ); - assertThat( beginHandlerCaptor.getValue(), instanceOf( BeginTxResponseHandler.class ) ); + private void verifyBeginInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + BeginMessage beginMessage = new BeginMessage(bookmark, config, databaseName, mode, null); + verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture()); + assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class)); } - private static InternalAuthToken dummyAuthToken() - { - return (InternalAuthToken) AuthTokens.basic( "hello", "world" ); + private static InternalAuthToken dummyAuthToken() { + return (InternalAuthToken) AuthTokens.basic("hello", "world"); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageFormatV43Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageFormatV43Test.java index 5829d094be..fcdf616666 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageFormatV43Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageFormatV43Test.java @@ -18,39 +18,35 @@ */ package org.neo4j.driver.internal.messaging.v43; -import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.common.CommonMessageReader; import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.mockito.Mockito.mock; - /** * The MessageFormat under tests is the one provided by the {@link BoltProtocolV43} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageFormatV43Test -{ +class MessageFormatV43Test { private static final MessageFormat format = BoltProtocolV43.INSTANCE.createMessageFormat(); @Test - void shouldCreateCorrectWriter() - { - MessageFormat.Writer writer = format.newWriter( mock( PackOutput.class ) ); + void shouldCreateCorrectWriter() { + MessageFormat.Writer writer = format.newWriter(mock(PackOutput.class)); - assertThat( writer, instanceOf( MessageWriterV43.class ) ); + assertThat(writer, instanceOf(MessageWriterV43.class)); } @Test - void shouldCreateCorrectReader() - { - MessageFormat.Reader reader = format.newReader( mock( PackInput.class ) ); + void shouldCreateCorrectReader() { + MessageFormat.Reader reader = format.newReader(mock(PackInput.class)); - assertThat( reader, instanceOf( CommonMessageReader.class ) ); + assertThat(reader, instanceOf(CommonMessageReader.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageReaderV43Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageReaderV43Test.java index bc6e284799..70aa3d8854 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageReaderV43Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageReaderV43Test.java @@ -18,6 +18,18 @@ */ package org.neo4j.driver.internal.messaging.v43; +import static java.util.Arrays.asList; +import static java.util.Calendar.APRIL; +import static java.util.Calendar.AUGUST; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +39,6 @@ import java.time.ZonedDateTime; import java.util.HashMap; import java.util.stream.Stream; - import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.InternalPoint2D; @@ -43,77 +54,60 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.util.messaging.AbstractMessageReaderTestBase; -import static java.util.Arrays.asList; -import static java.util.Calendar.APRIL; -import static java.util.Calendar.AUGUST; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; - /** * The MessageReader under tests is the one provided by the {@link BoltProtocolV43} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -public class MessageReaderV43Test extends AbstractMessageReaderTestBase -{ +public class MessageReaderV43Test extends AbstractMessageReaderTestBase { @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // V2 Record types - record( value( new InternalPoint2D( 42, 120.65, -99.2 ) ) ), - record( value( new InternalPoint3D( 42, 85.391, 98.8, 11.1 ) ) ), - record( value( LocalDate.of( 2012, AUGUST, 3 ) ) ), - record( value( OffsetTime.of( 23, 59, 59, 999, ZoneOffset.MAX ) ) ), - record( value( LocalTime.of( 12, 25 ) ) ), - record( value( LocalDateTime.of( 1999, APRIL, 3, 19, 5, 5, 100_200_300 ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes( -7, -15 ) ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of( "Europe/Stockholm" ) ) ) ), - record( value( Values.isoDuration( Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1 ).asIsoDuration() ) ), - record( value( Values.isoDuration( 17, 22, 99, 15 ).asIsoDuration() ) ), + record(value(new InternalPoint2D(42, 120.65, -99.2))), + record(value(new InternalPoint3D(42, 85.391, 98.8, 11.1))), + record(value(LocalDate.of(2012, AUGUST, 3))), + record(value(OffsetTime.of(23, 59, 59, 999, ZoneOffset.MAX))), + record(value(LocalTime.of(12, 25))), + record(value(LocalDateTime.of(1999, APRIL, 3, 19, 5, 5, 100_200_300))), + record(value( + ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes(-7, -15)))), + record(value(ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of("Europe/Stockholm")))), + record(value(Values.isoDuration( + Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1) + .asIsoDuration())), + record(value(Values.isoDuration(17, 22, 99, 15).asIsoDuration())), // Bolt previous versions valid messages - new FailureMessage( "Hello", "World!" ), + new FailureMessage("Hello", "World!"), IgnoredMessage.IGNORED, - new SuccessMessage( new HashMap<>() ), - record( value( 1337L ) ), - record( value( parameters( "cat", null, "dog", null ) ) ), - record( value( parameters( "k", 12, "a", "banana" ) ) ), - record( value( asList( "k", 12, "a", "banana" ) ) ), + new SuccessMessage(new HashMap<>()), + record(value(1337L)), + record(value(parameters("cat", null, "dog", null))), + record(value(parameters("k", 12, "a", "banana"))), + record(value(asList("k", 12, "a", "banana"))), // V3 Record Types - record( emptyNodeValue() ), - record( filledNodeValue() ), - record( emptyRelationshipValue() ), - record( filledRelationshipValue() ), - record( filledPathValue() ), - record( emptyPathValue() ) - ); + record(emptyNodeValue()), + record(filledNodeValue()), + record(emptyRelationshipValue()), + record(filledRelationshipValue()), + record(filledPathValue()), + record(emptyPathValue())); } @Override - protected Stream unsupportedMessages() - { - return Stream.of( - DiscardAllMessage.DISCARD_ALL - ); + protected Stream unsupportedMessages() { + return Stream.of(DiscardAllMessage.DISCARD_ALL); } @Override - protected MessageFormat.Reader newReader( PackInput input ) - { - return BoltProtocolV42.INSTANCE.createMessageFormat().newReader( input ); + protected MessageFormat.Reader newReader(PackInput input) { + return BoltProtocolV42.INSTANCE.createMessageFormat().newReader(input); } - private Message record( Value value ) - { - return new RecordMessage( new Value[]{value} ); + private Message record(Value value) { + return new RecordMessage(new Value[] {value}); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java index 2f45f29f63..d980573138 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java @@ -18,6 +18,26 @@ */ package org.neo4j.driver.internal.messaging.v43; +import static java.time.Duration.ofSeconds; +import static java.util.Calendar.DECEMBER; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.AuthTokens.basic; +import static org.neo4j.driver.Values.point; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; +import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; +import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; +import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; +import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -29,7 +49,6 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; - import org.neo4j.driver.Query; import org.neo4j.driver.Value; import org.neo4j.driver.Values; @@ -45,104 +64,123 @@ import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.util.messaging.AbstractMessageWriterTestBase; -import static java.time.Duration.ofSeconds; -import static java.util.Calendar.DECEMBER; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.AuthTokens.basic; -import static org.neo4j.driver.Values.point; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; -import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; -import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; -import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; -import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; - /** * The MessageWriter under tests is the one provided by the {@link BoltProtocolV43} and not an specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -class MessageWriterV43Test extends AbstractMessageWriterTestBase -{ +class MessageWriterV43Test extends AbstractMessageWriterTestBase { @Override - protected MessageFormat.Writer newWriter( PackOutput output ) - { - return BoltProtocolV43.INSTANCE.createMessageFormat().newWriter( output ); + protected MessageFormat.Writer newWriter(PackOutput output) { + return BoltProtocolV43.INSTANCE.createMessageFormat().newWriter(output); } @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // Bolt V2 Data Types - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 12.99, -180.0 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 0.51, 2.99, 100.123 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $date", singletonMap( "date", value( LocalDate.ofEpochDay( 2147483650L ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( OffsetTime.of( 4, 16, 20, 999, ZoneOffset.MIN ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( LocalTime.of( 12, 9, 18, 999_888 ) ) ) ) ), + unmanagedTxRunMessage(new Query("RETURN $point", singletonMap("point", point(42, 12.99, -180.0)))), + unmanagedTxRunMessage( + new Query("RETURN $point", singletonMap("point", point(42, 0.51, 2.99, 100.123)))), unmanagedTxRunMessage( - new Query( "RETURN $dateTime", singletonMap( "dateTime", value( LocalDateTime.of( 2049, DECEMBER, 12, 17, 25, 49, 199 ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneOffset - .ofHoursMinutes( 9, 30 ) ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneId.of( - "Europe/Stockholm" ) ) ) ) ) ), + new Query("RETURN $date", singletonMap("date", value(LocalDate.ofEpochDay(2147483650L))))), + unmanagedTxRunMessage(new Query( + "RETURN $time", singletonMap("time", value(OffsetTime.of(4, 16, 20, 999, ZoneOffset.MIN))))), + unmanagedTxRunMessage( + new Query("RETURN $time", singletonMap("time", value(LocalTime.of(12, 9, 18, 999_888))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap("dateTime", value(LocalDateTime.of(2049, DECEMBER, 12, 17, 25, 49, 199))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of( + 2000, 1, 10, 12, 2, 49, 300, ZoneOffset.ofHoursMinutes(9, 30)))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of(2000, 1, 10, 12, 2, 49, 300, ZoneId.of("Europe/Stockholm")))))), // New Bolt V4 messages - new PullMessage( 100, 200 ), - new DiscardMessage( 300, 400 ), + new PullMessage(100, 200), + new DiscardMessage(300, 400), // Bolt V3 messages - new HelloMessage( "MyDriver/1.2.3", ((InternalAuthToken) basic( "neo4j", "neo4j" )).toMap(), Collections.emptyMap() ), + new HelloMessage( + "MyDriver/1.2.3", + ((InternalAuthToken) basic("neo4j", "neo4j")).toMap(), + Collections.emptyMap()), GOODBYE, - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), READ, - defaultDatabase(), null ), - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), WRITE, - database( "foo" ), null ), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + READ, + defaultDatabase(), + null), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + WRITE, + database("foo"), + null), COMMIT, ROLLBACK, - RESET, - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), defaultDatabase(), READ, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), database( "foo" ), WRITE, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - unmanagedTxRunMessage( new Query( "RETURN 1" ) ), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + defaultDatabase(), + READ, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + database("foo"), + WRITE, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + unmanagedTxRunMessage(new Query("RETURN 1")), // Bolt V3 messages with struct values - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - defaultDatabase(), READ, InternalBookmark.empty(), null ), - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - database( "foo" ), - WRITE, InternalBookmark.empty(), null ), - unmanagedTxRunMessage( new Query( "RETURN $x", singletonMap( "x", point( 42, 1, 2, 3 ) ) ) ), + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + defaultDatabase(), + READ, + InternalBookmark.empty(), + null), + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + database("foo"), + WRITE, + InternalBookmark.empty(), + null), + unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3)))), // New 4.3 Messages - routeMessage() - ); + routeMessage()); } @Override - protected Stream unsupportedMessages() - { + protected Stream unsupportedMessages() { return Stream.of( // Bolt V1, V2 and V3 messages - PULL_ALL, - DISCARD_ALL - ); + PULL_ALL, DISCARD_ALL); } - private RouteMessage routeMessage() - { - Map routeContext = new HashMap<>(); - routeContext.put( "someContext", Values.value( 124 ) ); - return new RouteMessage( routeContext, InternalBookmark.empty(), "dbName", null ); + private RouteMessage routeMessage() { + Map routeContext = new HashMap<>(); + routeContext.put("someContext", Values.value(124)); + return new RouteMessage(routeContext, InternalBookmark.empty(), "dbName", null); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44Test.java index 09cd33c40e..f35814e6af 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/BoltProtocolV44Test.java @@ -18,20 +18,47 @@ */ package org.neo4j.driver.internal.messaging.v44; +import static java.time.Duration.ofSeconds; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.util.TestUtil.anyServerVersion; +import static org.neo4j.driver.util.TestUtil.await; +import static org.neo4j.driver.util.TestUtil.connectionMock; + import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.mockito.ArgumentCaptor; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Bookmark; @@ -67,476 +94,436 @@ import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ResponseHandler; -import static java.time.Duration.ofSeconds; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.util.TestUtil.anyServerVersion; -import static org.neo4j.driver.util.TestUtil.await; -import static org.neo4j.driver.util.TestUtil.connectionMock; - -public class BoltProtocolV44Test -{ +public class BoltProtocolV44Test { protected static final String QUERY_TEXT = "RETURN $x"; - protected static final Map PARAMS = singletonMap( "x", value( 42 ) ); - protected static final Query QUERY = new Query( QUERY_TEXT, value( PARAMS ) ); + protected static final Map PARAMS = singletonMap("x", value(42)); + protected static final Query QUERY = new Query(QUERY_TEXT, value(PARAMS)); protected final BoltProtocol protocol = createProtocol(); private final EmbeddedChannel channel = new EmbeddedChannel(); - private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher( channel, Logging.none() ); + private final InboundMessageDispatcher messageDispatcher = new InboundMessageDispatcher(channel, Logging.none()); private final TransactionConfig txConfig = TransactionConfig.builder() - .withTimeout( ofSeconds( 12 ) ) - .withMetadata( singletonMap( "key", value( 42 ) ) ) - .build(); + .withTimeout(ofSeconds(12)) + .withMetadata(singletonMap("key", value(42))) + .build(); - protected BoltProtocol createProtocol() - { + protected BoltProtocol createProtocol() { return BoltProtocolV44.INSTANCE; } @BeforeEach - void beforeEach() - { - ChannelAttributes.setMessageDispatcher( channel, messageDispatcher ); + void beforeEach() { + ChannelAttributes.setMessageDispatcher(channel, messageDispatcher); } @AfterEach - void afterEach() - { + void afterEach() { channel.finishAndReleaseAll(); } @Test - void shouldCreateMessageFormat() - { - assertThat( protocol.createMessageFormat(), instanceOf( expectedMessageFormatType() ) ); + void shouldCreateMessageFormat() { + assertThat(protocol.createMessageFormat(), instanceOf(expectedMessageFormatType())); } @Test - void shouldInitializeChannel() - { + void shouldInitializeChannel() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/0.0.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - Map metadata = new HashMap<>(); - metadata.put( "server", value( anyServerVersion().toString() ) ); - metadata.put( "connection_id", value( "bolt-42" ) ); + Map metadata = new HashMap<>(); + metadata.put("server", value(anyServerVersion().toString())); + metadata.put("connection_id", value("bolt-42")); - messageDispatcher.handleSuccessMessage( metadata ); + messageDispatcher.handleSuccessMessage(metadata); - assertTrue( promise.isDone() ); - assertTrue( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertTrue(promise.isSuccess()); } @Test - void shouldPrepareToCloseChannel() - { - protocol.prepareToCloseChannel( channel ); + void shouldPrepareToCloseChannel() { + protocol.prepareToCloseChannel(channel); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( GoodbyeMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(GoodbyeMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); } @Test - void shouldFailToInitializeChannelWhenErrorIsReceived() - { + void shouldFailToInitializeChannelWhenErrorIsReceived() { ChannelPromise promise = channel.newPromise(); - protocol.initializeChannel( "MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise ); + protocol.initializeChannel("MyDriver/2.2.1", dummyAuthToken(), RoutingContext.EMPTY, promise); - assertThat( channel.outboundMessages(), hasSize( 1 ) ); - assertThat( channel.outboundMessages().poll(), instanceOf( HelloMessage.class ) ); - assertEquals( 1, messageDispatcher.queuedHandlersCount() ); - assertFalse( promise.isDone() ); + assertThat(channel.outboundMessages(), hasSize(1)); + assertThat(channel.outboundMessages().poll(), instanceOf(HelloMessage.class)); + assertEquals(1, messageDispatcher.queuedHandlersCount()); + assertFalse(promise.isDone()); - messageDispatcher.handleFailureMessage( "Neo.TransientError.General.DatabaseUnavailable", "Error!" ); + messageDispatcher.handleFailureMessage("Neo.TransientError.General.DatabaseUnavailable", "Error!"); - assertTrue( promise.isDone() ); - assertFalse( promise.isSuccess() ); + assertTrue(promise.isDone()); + assertFalse(promise.isSuccess()); } @Test - void shouldBeginTransactionWithoutBookmark() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithoutBookmark() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); + CompletionStage stage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage( + InternalBookmark.empty(), TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarks() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx100" ); + void shouldBeginTransactionWithBookmarks() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx100"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, TransactionConfig.empty() ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, TransactionConfig.empty()); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, TransactionConfig.empty(), defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithConfig() - { - Connection connection = connectionMock( protocol ); + void shouldBeginTransactionWithConfig() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.beginTransaction( connection, InternalBookmark.empty(), txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, InternalBookmark.empty(), txConfig); - verify( connection ) - .writeAndFlush( eq( new BeginMessage( InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null ) ), - any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(InternalBookmark.empty(), txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldBeginTransactionWithBookmarksAndConfig() - { - Connection connection = connectionMock( protocol ); - Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx4242" ); + void shouldBeginTransactionWithBookmarksAndConfig() { + Connection connection = connectionMock(protocol); + Bookmark bookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx4242"); - CompletionStage stage = protocol.beginTransaction( connection, bookmark, txConfig ); + CompletionStage stage = protocol.beginTransaction(connection, bookmark, txConfig); - verify( connection ).writeAndFlush( eq( new BeginMessage( bookmark, txConfig, defaultDatabase(), WRITE, null ) ), any( BeginTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection) + .writeAndFlush( + eq(new BeginMessage(bookmark, txConfig, defaultDatabase(), WRITE, null)), + any(BeginTxResponseHandler.class)); + assertNull(await(stage)); } @Test - void shouldCommitTransaction() - { + void shouldCommitTransaction() { String bookmarkString = "neo4j:bookmark:v1:tx4242"; - Connection connection = connectionMock( protocol ); - when( connection.protocol() ).thenReturn( protocol ); - doAnswer( invocation -> - { - ResponseHandler commitHandler = invocation.getArgument( 1 ); - commitHandler.onSuccess( singletonMap( "bookmark", value( bookmarkString ) ) ); - return null; - } ).when( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any() ); + Connection connection = connectionMock(protocol); + when(connection.protocol()).thenReturn(protocol); + doAnswer(invocation -> { + ResponseHandler commitHandler = invocation.getArgument(1); + commitHandler.onSuccess(singletonMap("bookmark", value(bookmarkString))); + return null; + }) + .when(connection) + .writeAndFlush(eq(CommitMessage.COMMIT), any()); - CompletionStage stage = protocol.commitTransaction( connection ); + CompletionStage stage = protocol.commitTransaction(connection); - verify( connection ).writeAndFlush( eq( CommitMessage.COMMIT ), any( CommitTxResponseHandler.class ) ); - assertEquals( InternalBookmark.parse( bookmarkString ), await( stage ) ); + verify(connection).writeAndFlush(eq(CommitMessage.COMMIT), any(CommitTxResponseHandler.class)); + assertEquals(InternalBookmark.parse(bookmarkString), await(stage)); } @Test - void shouldRollbackTransaction() - { - Connection connection = connectionMock( protocol ); + void shouldRollbackTransaction() { + Connection connection = connectionMock(protocol); - CompletionStage stage = protocol.rollbackTransaction( connection ); + CompletionStage stage = protocol.rollbackTransaction(connection); - verify( connection ).writeAndFlush( eq( RollbackMessage.ROLLBACK ), any( RollbackTxResponseHandler.class ) ); - assertNull( await( stage ) ); + verify(connection).writeAndFlush(eq(RollbackMessage.ROLLBACK), any(RollbackTxResponseHandler.class)); + assertNull(await(stage)); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( true, txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitWithConfigTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(true, txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testSuccessfulRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx65" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForSuccessRunResponse(AccessMode mode) + throws Exception { + testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx65"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.empty(), TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse(InternalBookmark.empty(), TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testFailedRunInAutoCommitTxWithWaitingForResponse( InternalBookmark.parse( "neo4j:bookmark:v1:tx163" ), txConfig, mode ); + @EnumSource(AccessMode.class) + void shouldRunInAutoCommitTransactionWithBookmarkAndConfigAndWaitForFailureRunResponse(AccessMode mode) + throws Exception { + testFailedRunInAutoCommitTxWithWaitingForResponse( + InternalBookmark.parse("neo4j:bookmark:v1:tx163"), txConfig, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForRunResponse( AccessMode mode ) throws Exception - { - testRunAndWaitForRunResponse( false, TransactionConfig.empty(), mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForRunResponse(AccessMode mode) throws Exception { + testRunAndWaitForRunResponse(false, TransactionConfig.empty(), mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( true, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForSuccessRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(true, mode); } @ParameterizedTest - @EnumSource( AccessMode.class ) - void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse( AccessMode mode ) throws Exception - { - testRunInUnmanagedTransactionAndWaitForRunResponse( false, mode ); + @EnumSource(AccessMode.class) + void shouldRunInUnmanagedTransactionAndWaitForFailureRunResponse(AccessMode mode) throws Exception { + testRunInUnmanagedTransactionAndWaitForRunResponse(false, mode); } @Test - void databaseNameInBeginTransaction() - { - testDatabaseNameSupport( false ); + void databaseNameInBeginTransaction() { + testDatabaseNameSupport(false); } @Test - void databaseNameForAutoCommitTransactions() - { - testDatabaseNameSupport( true ); + void databaseNameForAutoCommitTransactions() { + testDatabaseNameSupport(true); } @Test - void shouldSupportDatabaseNameInBeginTransaction() - { - CompletionStage txStage = protocol.beginTransaction( connectionMock( "foo", protocol ), InternalBookmark.empty(), TransactionConfig.empty() ); + void shouldSupportDatabaseNameInBeginTransaction() { + CompletionStage txStage = protocol.beginTransaction( + connectionMock("foo", protocol), InternalBookmark.empty(), TransactionConfig.empty()); - assertDoesNotThrow( () -> await( txStage ) ); + assertDoesNotThrow(() -> await(txStage)); } @Test - void shouldNotSupportDatabaseNameForAutoCommitTransactions() - { - assertDoesNotThrow( - () -> protocol.runInAutoCommitTransaction( connectionMock( "foo", protocol ), - new Query( "RETURN 1" ), BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ) ); + void shouldNotSupportDatabaseNameForAutoCommitTransactions() { + assertDoesNotThrow(() -> protocol.runInAutoCommitTransaction( + connectionMock("foo", protocol), + new Query("RETURN 1"), + BookmarkHolder.NO_OP, + TransactionConfig.empty(), + UNLIMITED_FETCH_SIZE)); } - private Class expectedMessageFormatType() - { + private Class expectedMessageFormatType() { return MessageFormatV44.class; } - private void testFailedRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testFailedRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to Run message with a failure Throwable error = new RuntimeException(); - runHandler.onFailure( error ); + runHandler.onFailure(error); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + Throwable actual = + assertThrows(error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } - private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( Bookmark bookmark, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testSuccessfulRunInAutoCommitTxWithWaitingForResponse( + Bookmark bookmark, TransactionConfig config, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( bookmark ); + Connection connection = connectionMock(mode, protocol); + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(bookmark); - CompletableFuture cursorFuture = - protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifySessionRunInvoked( connection, bookmark, config, mode, defaultDatabase() ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifySessionRunInvoked(connection, bookmark, config, mode, defaultDatabase()); + assertFalse(cursorFuture.isDone()); // When I response to the run message - runHandler.onSuccess( emptyMap() ); + runHandler.onSuccess(emptyMap()); // Then - assertEquals( bookmark, bookmarkHolder.getBookmark() ); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertEquals(bookmark, bookmarkHolder.getBookmark()); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - private void testRunInUnmanagedTransactionAndWaitForRunResponse( boolean success, AccessMode mode ) throws Exception - { + private void testRunInUnmanagedTransactionAndWaitForRunResponse(boolean success, AccessMode mode) throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); + Connection connection = connectionMock(mode, protocol); - CompletableFuture cursorFuture = - protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult() - .toCompletableFuture(); + CompletableFuture cursorFuture = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult() + .toCompletableFuture(); - ResponseHandler runHandler = verifyTxRunInvoked( connection ); - assertFalse( cursorFuture.isDone() ); + ResponseHandler runHandler = verifyTxRunInvoked(connection); + assertFalse(cursorFuture.isDone()); Throwable error = new RuntimeException(); - if ( success ) - { - runHandler.onSuccess( emptyMap() ); - } - else - { + if (success) { + runHandler.onSuccess(emptyMap()); + } else { // When responded with a failure - runHandler.onFailure( error ); + runHandler.onFailure(error); } // Then - assertTrue( cursorFuture.isDone() ); - if ( success ) - { - assertNotNull( await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - } - else - { - Throwable actual = assertThrows( error.getClass(), () -> await( cursorFuture.get().mapSuccessfulRunCompletionAsync() ) ); - assertSame( error, actual ); + assertTrue(cursorFuture.isDone()); + if (success) { + assertNotNull(await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + } else { + Throwable actual = assertThrows( + error.getClass(), () -> await(cursorFuture.get().mapSuccessfulRunCompletionAsync())); + assertSame(error, actual); } } - private void testRunAndWaitForRunResponse( boolean autoCommitTx, TransactionConfig config, AccessMode mode ) throws Exception - { + private void testRunAndWaitForRunResponse(boolean autoCommitTx, TransactionConfig config, AccessMode mode) + throws Exception { // Given - Connection connection = connectionMock( mode, protocol ); - Bookmark initialBookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx987" ); + Connection connection = connectionMock(mode, protocol); + Bookmark initialBookmark = InternalBookmark.parse("neo4j:bookmark:v1:tx987"); CompletionStage cursorStage; - if ( autoCommitTx ) - { - BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder( initialBookmark ); - cursorStage = protocol.runInAutoCommitTransaction( connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE ) - .asyncResult(); - } - else - { - cursorStage = protocol.runInUnmanagedTransaction( connection, QUERY, mock( UnmanagedTransaction.class ), UNLIMITED_FETCH_SIZE ) - .asyncResult(); + if (autoCommitTx) { + BookmarkHolder bookmarkHolder = new DefaultBookmarkHolder(initialBookmark); + cursorStage = protocol.runInAutoCommitTransaction( + connection, QUERY, bookmarkHolder, config, UNLIMITED_FETCH_SIZE) + .asyncResult(); + } else { + cursorStage = protocol.runInUnmanagedTransaction( + connection, QUERY, mock(UnmanagedTransaction.class), UNLIMITED_FETCH_SIZE) + .asyncResult(); } // When & Then CompletableFuture cursorFuture = cursorStage.toCompletableFuture(); - assertFalse( cursorFuture.isDone() ); + assertFalse(cursorFuture.isDone()); - ResponseHandler runResponseHandler = - autoCommitTx ? verifySessionRunInvoked( connection, initialBookmark, config, mode, defaultDatabase() ) : verifyTxRunInvoked( connection ); - runResponseHandler.onSuccess( emptyMap() ); + ResponseHandler runResponseHandler = autoCommitTx + ? verifySessionRunInvoked(connection, initialBookmark, config, mode, defaultDatabase()) + : verifyTxRunInvoked(connection); + runResponseHandler.onSuccess(emptyMap()); - assertTrue( cursorFuture.isDone() ); - assertNotNull( cursorFuture.get() ); + assertTrue(cursorFuture.isDone()); + assertNotNull(cursorFuture.get()); } - private void testDatabaseNameSupport( boolean autoCommitTx ) - { - Connection connection = connectionMock( "foo", protocol ); - if ( autoCommitTx ) - { - ResultCursorFactory factory = - protocol.runInAutoCommitTransaction( connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE ); + private void testDatabaseNameSupport(boolean autoCommitTx) { + Connection connection = connectionMock("foo", protocol); + if (autoCommitTx) { + ResultCursorFactory factory = protocol.runInAutoCommitTransaction( + connection, QUERY, BookmarkHolder.NO_OP, TransactionConfig.empty(), UNLIMITED_FETCH_SIZE); CompletionStage resultStage = factory.asyncResult(); - ResponseHandler runHandler = - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - runHandler.onSuccess( emptyMap() ); - await( resultStage ); - verifySessionRunInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); - } - else - { - CompletionStage txStage = protocol.beginTransaction( connection, InternalBookmark.empty(), TransactionConfig.empty() ); - await( txStage ); - verifyBeginInvoked( connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database( "foo" ) ); + ResponseHandler runHandler = verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + runHandler.onSuccess(emptyMap()); + await(resultStage); + verifySessionRunInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); + } else { + CompletionStage txStage = + protocol.beginTransaction(connection, InternalBookmark.empty(), TransactionConfig.empty()); + await(txStage); + verifyBeginInvoked( + connection, InternalBookmark.empty(), TransactionConfig.empty(), AccessMode.WRITE, database("foo")); } } - private ResponseHandler verifyTxRunInvoked( Connection connection ) - { - return verifyRunInvoked( connection, RunWithMetadataMessage.unmanagedTxRunMessage( QUERY ) ); + private ResponseHandler verifyTxRunInvoked(Connection connection) { + return verifyRunInvoked(connection, RunWithMetadataMessage.unmanagedTxRunMessage(QUERY)); } - private ResponseHandler verifySessionRunInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, - DatabaseName databaseName ) - { - RunWithMetadataMessage runMessage = RunWithMetadataMessage.autoCommitTxRunMessage( QUERY, config, databaseName, mode, bookmark, null ); - return verifyRunInvoked( connection, runMessage ); + private ResponseHandler verifySessionRunInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + RunWithMetadataMessage runMessage = + RunWithMetadataMessage.autoCommitTxRunMessage(QUERY, config, databaseName, mode, bookmark, null); + return verifyRunInvoked(connection, runMessage); } - private ResponseHandler verifyRunInvoked( Connection connection, RunWithMetadataMessage runMessage ) - { - ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); + private ResponseHandler verifyRunInvoked(Connection connection, RunWithMetadataMessage runMessage) { + ArgumentCaptor runHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + ArgumentCaptor pullHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); - verify( connection ).write( eq( runMessage ), runHandlerCaptor.capture() ); - verify( connection ).writeAndFlush( any( PullMessage.class ), pullHandlerCaptor.capture() ); + verify(connection).write(eq(runMessage), runHandlerCaptor.capture()); + verify(connection).writeAndFlush(any(PullMessage.class), pullHandlerCaptor.capture()); - assertThat( runHandlerCaptor.getValue(), instanceOf( RunResponseHandler.class ) ); - assertThat( pullHandlerCaptor.getValue(), instanceOf( PullAllResponseHandler.class ) ); + assertThat(runHandlerCaptor.getValue(), instanceOf(RunResponseHandler.class)); + assertThat(pullHandlerCaptor.getValue(), instanceOf(PullAllResponseHandler.class)); return runHandlerCaptor.getValue(); } - private void verifyBeginInvoked( Connection connection, Bookmark bookmark, TransactionConfig config, AccessMode mode, DatabaseName databaseName ) - { - ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass( ResponseHandler.class ); - BeginMessage beginMessage = new BeginMessage( bookmark, config, databaseName, mode, null ); - verify( connection ).writeAndFlush( eq( beginMessage ), beginHandlerCaptor.capture() ); - assertThat( beginHandlerCaptor.getValue(), instanceOf( BeginTxResponseHandler.class ) ); + private void verifyBeginInvoked( + Connection connection, + Bookmark bookmark, + TransactionConfig config, + AccessMode mode, + DatabaseName databaseName) { + ArgumentCaptor beginHandlerCaptor = ArgumentCaptor.forClass(ResponseHandler.class); + BeginMessage beginMessage = new BeginMessage(bookmark, config, databaseName, mode, null); + verify(connection).writeAndFlush(eq(beginMessage), beginHandlerCaptor.capture()); + assertThat(beginHandlerCaptor.getValue(), instanceOf(BeginTxResponseHandler.class)); } - private static InternalAuthToken dummyAuthToken() - { - return (InternalAuthToken) AuthTokens.basic( "hello", "world" ); + private static InternalAuthToken dummyAuthToken() { + return (InternalAuthToken) AuthTokens.basic("hello", "world"); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageFormatV44Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageFormatV44Test.java index 35e97c3fdf..2eef395703 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageFormatV44Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageFormatV44Test.java @@ -18,34 +18,30 @@ */ package org.neo4j.driver.internal.messaging.v44; -import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.common.CommonMessageReader; import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.mockito.Mockito.mock; - -public class MessageFormatV44Test -{ +public class MessageFormatV44Test { private static final MessageFormat format = BoltProtocolV44.INSTANCE.createMessageFormat(); @Test - void shouldCreateCorrectWriter() - { - MessageFormat.Writer writer = format.newWriter( mock( PackOutput.class ) ); + void shouldCreateCorrectWriter() { + MessageFormat.Writer writer = format.newWriter(mock(PackOutput.class)); - assertThat( writer, instanceOf( MessageWriterV44.class ) ); + assertThat(writer, instanceOf(MessageWriterV44.class)); } @Test - void shouldCreateCorrectReader() - { - MessageFormat.Reader reader = format.newReader( mock( PackInput.class ) ); + void shouldCreateCorrectReader() { + MessageFormat.Reader reader = format.newReader(mock(PackInput.class)); - assertThat( reader, instanceOf( CommonMessageReader.class ) ); + assertThat(reader, instanceOf(CommonMessageReader.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageReaderV44Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageReaderV44Test.java index 6f3e93b590..fe0fc1986a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageReaderV44Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageReaderV44Test.java @@ -18,6 +18,18 @@ */ package org.neo4j.driver.internal.messaging.v44; +import static java.util.Arrays.asList; +import static java.util.Calendar.APRIL; +import static java.util.Calendar.AUGUST; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; +import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -27,7 +39,6 @@ import java.time.ZonedDateTime; import java.util.HashMap; import java.util.stream.Stream; - import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.InternalPoint2D; @@ -42,76 +53,59 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.util.messaging.AbstractMessageReaderTestBase; -import static java.util.Arrays.asList; -import static java.util.Calendar.APRIL; -import static java.util.Calendar.AUGUST; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; - /** * The MessageReader under tests is the one provided by the {@link BoltProtocolV44} and not a specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -public class MessageReaderV44Test extends AbstractMessageReaderTestBase -{ +public class MessageReaderV44Test extends AbstractMessageReaderTestBase { @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // V2 Record types - record( value( new InternalPoint2D( 42, 120.65, -99.2 ) ) ), - record( value( new InternalPoint3D( 42, 85.391, 98.8, 11.1 ) ) ), - record( value( LocalDate.of( 2012, AUGUST, 3 ) ) ), - record( value( OffsetTime.of( 23, 59, 59, 999, ZoneOffset.MAX ) ) ), - record( value( LocalTime.of( 12, 25 ) ) ), - record( value( LocalDateTime.of( 1999, APRIL, 3, 19, 5, 5, 100_200_300 ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes( -7, -15 ) ) ) ), - record( value( ZonedDateTime.of( 1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of( "Europe/Stockholm" ) ) ) ), - record( value( Values.isoDuration( Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1 ).asIsoDuration() ) ), - record( value( Values.isoDuration( 17, 22, 99, 15 ).asIsoDuration() ) ), + record(value(new InternalPoint2D(42, 120.65, -99.2))), + record(value(new InternalPoint3D(42, 85.391, 98.8, 11.1))), + record(value(LocalDate.of(2012, AUGUST, 3))), + record(value(OffsetTime.of(23, 59, 59, 999, ZoneOffset.MAX))), + record(value(LocalTime.of(12, 25))), + record(value(LocalDateTime.of(1999, APRIL, 3, 19, 5, 5, 100_200_300))), + record(value( + ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes(-7, -15)))), + record(value(ZonedDateTime.of(1823, 1, 12, 23, 59, 59, 999_999_999, ZoneId.of("Europe/Stockholm")))), + record(value(Values.isoDuration( + Long.MAX_VALUE - 1, Integer.MAX_VALUE - 1, Short.MAX_VALUE - 1, Byte.MAX_VALUE - 1) + .asIsoDuration())), + record(value(Values.isoDuration(17, 22, 99, 15).asIsoDuration())), // Bolt previous versions valid messages - new FailureMessage( "Hello", "World!" ), + new FailureMessage("Hello", "World!"), IgnoredMessage.IGNORED, - new SuccessMessage( new HashMap<>() ), - record( value( 1337L ) ), - record( value( parameters( "cat", null, "dog", null ) ) ), - record( value( parameters( "k", 12, "a", "banana" ) ) ), - record( value( asList( "k", 12, "a", "banana" ) ) ), + new SuccessMessage(new HashMap<>()), + record(value(1337L)), + record(value(parameters("cat", null, "dog", null))), + record(value(parameters("k", 12, "a", "banana"))), + record(value(asList("k", 12, "a", "banana"))), // V3 Record Types - record( emptyNodeValue() ), - record( filledNodeValue() ), - record( emptyRelationshipValue() ), - record( filledRelationshipValue() ), - record( filledPathValue() ), - record( emptyPathValue() ) - ); + record(emptyNodeValue()), + record(filledNodeValue()), + record(emptyRelationshipValue()), + record(filledRelationshipValue()), + record(filledPathValue()), + record(emptyPathValue())); } @Override - protected Stream unsupportedMessages() - { - return Stream.of( - DiscardAllMessage.DISCARD_ALL - ); + protected Stream unsupportedMessages() { + return Stream.of(DiscardAllMessage.DISCARD_ALL); } @Override - protected MessageFormat.Reader newReader( PackInput input ) - { - return BoltProtocolV44.INSTANCE.createMessageFormat().newReader( input ); + protected MessageFormat.Reader newReader(PackInput input) { + return BoltProtocolV44.INSTANCE.createMessageFormat().newReader(input); } - private Message record( Value value ) - { - return new RecordMessage( new Value[]{value} ); + private Message record(Value value) { + return new RecordMessage(new Value[] {value}); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44Test.java b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44Test.java index 5214bf083f..e2b079589c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44Test.java +++ b/driver/src/test/java/org/neo4j/driver/internal/messaging/v44/MessageWriterV44Test.java @@ -18,6 +18,26 @@ */ package org.neo4j.driver.internal.messaging.v44; +import static java.time.Duration.ofSeconds; +import static java.util.Calendar.DECEMBER; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.neo4j.driver.AccessMode.READ; +import static org.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.AuthTokens.basic; +import static org.neo4j.driver.Values.point; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; +import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; +import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; +import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; +import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; +import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; +import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -29,7 +49,6 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; - import org.neo4j.driver.Query; import org.neo4j.driver.Value; import org.neo4j.driver.Values; @@ -45,104 +64,123 @@ import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.util.messaging.AbstractMessageWriterTestBase; -import static java.time.Duration.ofSeconds; -import static java.util.Calendar.DECEMBER; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.neo4j.driver.AccessMode.READ; -import static org.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.AuthTokens.basic; -import static org.neo4j.driver.Values.point; -import static org.neo4j.driver.Values.value; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.messaging.request.CommitMessage.COMMIT; -import static org.neo4j.driver.internal.messaging.request.DiscardAllMessage.DISCARD_ALL; -import static org.neo4j.driver.internal.messaging.request.GoodbyeMessage.GOODBYE; -import static org.neo4j.driver.internal.messaging.request.PullAllMessage.PULL_ALL; -import static org.neo4j.driver.internal.messaging.request.ResetMessage.RESET; -import static org.neo4j.driver.internal.messaging.request.RollbackMessage.ROLLBACK; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.autoCommitTxRunMessage; -import static org.neo4j.driver.internal.messaging.request.RunWithMetadataMessage.unmanagedTxRunMessage; - /** * The MessageWriter under tests is the one provided by the {@link BoltProtocolV44} and not a specific class implementation. *

* It's done on this way to make easy to replace the implementation and still getting the same behaviour. */ -public class MessageWriterV44Test extends AbstractMessageWriterTestBase -{ +public class MessageWriterV44Test extends AbstractMessageWriterTestBase { @Override - protected MessageFormat.Writer newWriter( PackOutput output ) - { - return BoltProtocolV44.INSTANCE.createMessageFormat().newWriter( output ); + protected MessageFormat.Writer newWriter(PackOutput output) { + return BoltProtocolV44.INSTANCE.createMessageFormat().newWriter(output); } @Override - protected Stream supportedMessages() - { + protected Stream supportedMessages() { return Stream.of( // Bolt V2 Data Types - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 12.99, -180.0 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $point", singletonMap( "point", point( 42, 0.51, 2.99, 100.123 ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $date", singletonMap( "date", value( LocalDate.ofEpochDay( 2147483650L ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( OffsetTime.of( 4, 16, 20, 999, ZoneOffset.MIN ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $time", singletonMap( "time", value( LocalTime.of( 12, 9, 18, 999_888 ) ) ) ) ), + unmanagedTxRunMessage(new Query("RETURN $point", singletonMap("point", point(42, 12.99, -180.0)))), + unmanagedTxRunMessage( + new Query("RETURN $point", singletonMap("point", point(42, 0.51, 2.99, 100.123)))), unmanagedTxRunMessage( - new Query( "RETURN $dateTime", singletonMap( "dateTime", value( LocalDateTime.of( 2049, DECEMBER, 12, 17, 25, 49, 199 ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneOffset - .ofHoursMinutes( 9, 30 ) ) ) ) ) ), - unmanagedTxRunMessage( new Query( "RETURN $dateTime", singletonMap( "dateTime", value( ZonedDateTime.of( 2000, 1, 10, 12, 2, 49, 300, ZoneId.of( - "Europe/Stockholm" ) ) ) ) ) ), + new Query("RETURN $date", singletonMap("date", value(LocalDate.ofEpochDay(2147483650L))))), + unmanagedTxRunMessage(new Query( + "RETURN $time", singletonMap("time", value(OffsetTime.of(4, 16, 20, 999, ZoneOffset.MIN))))), + unmanagedTxRunMessage( + new Query("RETURN $time", singletonMap("time", value(LocalTime.of(12, 9, 18, 999_888))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap("dateTime", value(LocalDateTime.of(2049, DECEMBER, 12, 17, 25, 49, 199))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of( + 2000, 1, 10, 12, 2, 49, 300, ZoneOffset.ofHoursMinutes(9, 30)))))), + unmanagedTxRunMessage(new Query( + "RETURN $dateTime", + singletonMap( + "dateTime", + value(ZonedDateTime.of(2000, 1, 10, 12, 2, 49, 300, ZoneId.of("Europe/Stockholm")))))), // New Bolt V4 messages - new PullMessage( 100, 200 ), - new DiscardMessage( 300, 400 ), + new PullMessage(100, 200), + new DiscardMessage(300, 400), // Bolt V3 messages - new HelloMessage( "MyDriver/1.2.3", ((InternalAuthToken) basic( "neo4j", "neo4j" )).toMap(), Collections.emptyMap() ), + new HelloMessage( + "MyDriver/1.2.3", + ((InternalAuthToken) basic("neo4j", "neo4j")).toMap(), + Collections.emptyMap()), GOODBYE, - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), READ, - defaultDatabase(), null ), - new BeginMessage( InternalBookmark.parse( "neo4j:bookmark:v1:tx123" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), WRITE, - database( "foo" ), null ), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + READ, + defaultDatabase(), + null), + new BeginMessage( + InternalBookmark.parse("neo4j:bookmark:v1:tx123"), + ofSeconds(5), + singletonMap("key", value(42)), + WRITE, + database("foo"), + null), COMMIT, ROLLBACK, - RESET, - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), defaultDatabase(), READ, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - autoCommitTxRunMessage( new Query( "RETURN 1" ), ofSeconds( 5 ), singletonMap( "key", value( 42 ) ), database( "foo" ), WRITE, - InternalBookmark.parse( "neo4j:bookmark:v1:tx1" ), null ), - unmanagedTxRunMessage( new Query( "RETURN 1" ) ), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + defaultDatabase(), + READ, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + autoCommitTxRunMessage( + new Query("RETURN 1"), + ofSeconds(5), + singletonMap("key", value(42)), + database("foo"), + WRITE, + InternalBookmark.parse("neo4j:bookmark:v1:tx1"), + null), + unmanagedTxRunMessage(new Query("RETURN 1")), // Bolt V3 messages with struct values - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - defaultDatabase(), READ, InternalBookmark.empty(), null ), - autoCommitTxRunMessage( new Query( "RETURN $x", singletonMap( "x", value( ZonedDateTime.now() ) ) ), ofSeconds( 1 ), emptyMap(), - database( "foo" ), - WRITE, InternalBookmark.empty(), null ), - unmanagedTxRunMessage( new Query( "RETURN $x", singletonMap( "x", point( 42, 1, 2, 3 ) ) ) ), + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + defaultDatabase(), + READ, + InternalBookmark.empty(), + null), + autoCommitTxRunMessage( + new Query("RETURN $x", singletonMap("x", value(ZonedDateTime.now()))), + ofSeconds(1), + emptyMap(), + database("foo"), + WRITE, + InternalBookmark.empty(), + null), + unmanagedTxRunMessage(new Query("RETURN $x", singletonMap("x", point(42, 1, 2, 3)))), // New 4.3 Messages - routeMessage() - ); + routeMessage()); } @Override - protected Stream unsupportedMessages() - { + protected Stream unsupportedMessages() { return Stream.of( // Bolt V1, V2 and V3 messages - PULL_ALL, - DISCARD_ALL - ); + PULL_ALL, DISCARD_ALL); } - private RouteMessage routeMessage() - { - Map routeContext = new HashMap<>(); - routeContext.put( "someContext", Values.value( 124 ) ); - return new RouteMessage( routeContext, InternalBookmark.empty(), "dbName", null ); + private RouteMessage routeMessage() { + Map routeContext = new HashMap<>(); + routeContext.put("someContext", Values.value(124)); + return new RouteMessage(routeContext, InternalBookmark.empty(), "dbName", null); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerConnectionPoolMetricsTest.java b/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerConnectionPoolMetricsTest.java index ea9891b3c0..b49774ea49 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerConnectionPoolMetricsTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerConnectionPoolMetricsTest.java @@ -18,27 +18,24 @@ */ package org.neo4j.driver.internal.metrics; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.IntSupplier; - +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.neo4j.driver.ConnectionPoolMetrics; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.spi.ConnectionPool; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -class MicrometerConnectionPoolMetricsTest -{ +class MicrometerConnectionPoolMetricsTest { static final String ID = "id"; MicrometerConnectionPoolMetrics metrics; @@ -51,250 +48,258 @@ class MicrometerConnectionPoolMetricsTest IntSupplier idleSupplier = idle::get; @BeforeEach - void beforeEach() - { - address = new BoltServerAddress( "host", "127.0.0.1", 7687 ); - pool = mock( ConnectionPool.class ); + void beforeEach() { + address = new BoltServerAddress("host", "127.0.0.1", 7687); + pool = mock(ConnectionPool.class); registry = new SimpleMeterRegistry(); - metrics = new MicrometerConnectionPoolMetrics( ID, address, inUseSupplier, idleSupplier, registry ); + metrics = new MicrometerConnectionPoolMetrics(ID, address, inUseSupplier, idleSupplier, registry); } @Test - void shouldIncrementCreatingAndStartTimerOnBeforeCreating() - { + void shouldIncrementCreatingAndStartTimerOnBeforeCreating() { // GIVEN - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.creating() ).willReturn( 1 ); - ListenerEvent event = mock( ListenerEvent.class ); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.creating()).willReturn(1); + ListenerEvent event = mock(ListenerEvent.class); // WHEN - metrics.beforeCreating( event ); + metrics.beforeCreating(event); // THEN - verifyMetrics( expectedMetrics, metrics ); - then( event ).should().start(); + verifyMetrics(expectedMetrics, metrics); + then(event).should().start(); } @Test - void shouldIncrementFailedToCreateAndDecrementCreatingOnAfterFailedToCreate() - { + void shouldIncrementFailedToCreateAndDecrementCreatingOnAfterFailedToCreate() { // GIVEN - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.failedToCreate() ).willReturn( 1L ); - given( expectedMetrics.creating() ).willReturn( -1 ); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.failedToCreate()).willReturn(1L); + given(expectedMetrics.creating()).willReturn(-1); // WHEN metrics.afterFailedToCreate(); // THEN - verifyMetrics( expectedMetrics, metrics ); + verifyMetrics(expectedMetrics, metrics); } @Test - void shouldDecrementCreatingAndIncrementCreatedAndStopTimerOnAfterCreated() - { + void shouldDecrementCreatingAndIncrementCreatedAndStopTimerOnAfterCreated() { // GIVEN - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.creating() ).willReturn( -1 ); - given( expectedMetrics.created() ).willReturn( 1L ); - Timer timer = registry.get( MicrometerConnectionPoolMetrics.CREATION ).timer(); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.creating()).willReturn(-1); + given(expectedMetrics.created()).willReturn(1L); + Timer timer = registry.get(MicrometerConnectionPoolMetrics.CREATION).timer(); long timerCount = timer.count(); - MicrometerTimerListenerEvent event = new MicrometerTimerListenerEvent( registry ); + MicrometerTimerListenerEvent event = new MicrometerTimerListenerEvent(registry); event.start(); // WHEN - metrics.afterCreated( event ); + metrics.afterCreated(event); // THEN - verifyMetrics( expectedMetrics, metrics ); - assertEquals( timerCount + 1, timer.count() ); + verifyMetrics(expectedMetrics, metrics); + assertEquals(timerCount + 1, timer.count()); } @Test - void shouldIncrementClosedOnAfterClosed() - { + void shouldIncrementClosedOnAfterClosed() { // GIVEN - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.closed() ).willReturn( 1L ); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.closed()).willReturn(1L); // WHEN metrics.afterClosed(); // THEN - verifyMetrics( expectedMetrics, metrics ); + verifyMetrics(expectedMetrics, metrics); } @Test - void shouldStartTimerAndIncrementAcquiringOnBeforeAcquiringOrCreating() - { + void shouldStartTimerAndIncrementAcquiringOnBeforeAcquiringOrCreating() { // GIVEN - ListenerEvent event = mock( ListenerEvent.class ); - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.acquiring() ).willReturn( 1 ); + ListenerEvent event = mock(ListenerEvent.class); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.acquiring()).willReturn(1); // WHEN - metrics.beforeAcquiringOrCreating( event ); + metrics.beforeAcquiringOrCreating(event); // THEN - then( event ).should().start(); - verifyMetrics( expectedMetrics, metrics ); + then(event).should().start(); + verifyMetrics(expectedMetrics, metrics); } @Test - void shouldDecrementAcquiringOnAfterAcquiringOrCreating() - { + void shouldDecrementAcquiringOnAfterAcquiringOrCreating() { // GIVEN - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.acquiring() ).willReturn( -1 ); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.acquiring()).willReturn(-1); // WHEN metrics.afterAcquiringOrCreating(); // THEN - verifyMetrics( expectedMetrics, metrics ); + verifyMetrics(expectedMetrics, metrics); } @Test - void shouldIncrementAcquiredAndStopTimerOnAfterAcquiredOrCreated() - { + void shouldIncrementAcquiredAndStopTimerOnAfterAcquiredOrCreated() { // GIVEN - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.acquired() ).willReturn( 1L ); - Timer timer = registry.get( MicrometerConnectionPoolMetrics.ACQUISITION ).timer(); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.acquired()).willReturn(1L); + Timer timer = registry.get(MicrometerConnectionPoolMetrics.ACQUISITION).timer(); long timerCount = timer.count(); - MicrometerTimerListenerEvent event = new MicrometerTimerListenerEvent( registry ); + MicrometerTimerListenerEvent event = new MicrometerTimerListenerEvent(registry); event.start(); // WHEN - metrics.afterAcquiredOrCreated( event ); + metrics.afterAcquiredOrCreated(event); // THEN - verifyMetrics( expectedMetrics, metrics ); - assertEquals( timerCount + 1, timer.count() ); + verifyMetrics(expectedMetrics, metrics); + assertEquals(timerCount + 1, timer.count()); } @Test - void shouldIncrementTimedOutToAcquireOnAfterTimedOutToAcquireOrCreate() - { + void shouldIncrementTimedOutToAcquireOnAfterTimedOutToAcquireOrCreate() { // GIVEN - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.timedOutToAcquire() ).willReturn( 1L ); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.timedOutToAcquire()).willReturn(1L); // WHEN metrics.afterTimedOutToAcquireOrCreate(); // THEN - verifyMetrics( expectedMetrics, metrics ); + verifyMetrics(expectedMetrics, metrics); } @Test - void shouldStartTimerOnAcquired() - { + void shouldStartTimerOnAcquired() { // GIVEN - ListenerEvent event = mock( ListenerEvent.class ); + ListenerEvent event = mock(ListenerEvent.class); // WHEN - metrics.acquired( event ); + metrics.acquired(event); // THEN - then( event ).should().start(); + then(event).should().start(); } @Test - void shouldIncrementReleasedAndStopTimerOnReleased() - { + void shouldIncrementReleasedAndStopTimerOnReleased() { // GIVEN - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.totalInUseCount() ).willReturn( 1L ); - Timer timer = registry.get( MicrometerConnectionPoolMetrics.USAGE ).timer(); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.totalInUseCount()).willReturn(1L); + Timer timer = registry.get(MicrometerConnectionPoolMetrics.USAGE).timer(); long timerCount = timer.count(); - MicrometerTimerListenerEvent event = new MicrometerTimerListenerEvent( registry ); + MicrometerTimerListenerEvent event = new MicrometerTimerListenerEvent(registry); event.start(); // WHEN - metrics.released( event ); + metrics.released(event); // THEN - verifyMetrics( expectedMetrics, metrics ); - assertEquals( timerCount + 1, timer.count() ); + verifyMetrics(expectedMetrics, metrics); + assertEquals(timerCount + 1, timer.count()); } @Test - void shouldUseInUseSupplier() - { - try - { + void shouldUseInUseSupplier() { + try { // GIVEN int expected = 5; - inUse.compareAndSet( 0, expected ); - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.inUse() ).willReturn( expected ); + inUse.compareAndSet(0, expected); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.inUse()).willReturn(expected); // WHEN int actual = metrics.inUse(); // THEN - assertEquals( expected, actual ); - verifyMetrics( expectedMetrics, metrics ); - } finally - { - inUse.set( 0 ); + assertEquals(expected, actual); + verifyMetrics(expectedMetrics, metrics); + } finally { + inUse.set(0); } } @Test - void shouldUseIdleSupplier() - { - try - { + void shouldUseIdleSupplier() { + try { // GIVEN int expected = 5; - idle.compareAndSet( 0, expected ); - ConnectionPoolMetrics expectedMetrics = mock( ConnectionPoolMetrics.class ); - given( expectedMetrics.idle() ).willReturn( expected ); + idle.compareAndSet(0, expected); + ConnectionPoolMetrics expectedMetrics = mock(ConnectionPoolMetrics.class); + given(expectedMetrics.idle()).willReturn(expected); // WHEN int actual = metrics.idle(); // THEN - assertEquals( expected, actual ); - verifyMetrics( expectedMetrics, metrics ); - } finally - { - idle.set( 0 ); + assertEquals(expected, actual); + verifyMetrics(expectedMetrics, metrics); + } finally { + idle.set(0); } } - void verifyMetrics( ConnectionPoolMetrics expected, ConnectionPoolMetrics actual ) - { - assertEquals( ID, actual.id() ); - assertEquals( expected.inUse(), actual.inUse() ); - assertEquals( expected.inUse(), registry.get( MicrometerConnectionPoolMetrics.IN_USE ).gauge().value() ); - assertEquals( expected.idle(), actual.idle() ); - assertEquals( expected.idle(), registry.get( MicrometerConnectionPoolMetrics.IDLE ).gauge().value() ); - assertEquals( expected.creating(), actual.creating() ); - assertEquals( expected.creating(), registry.get( MicrometerConnectionPoolMetrics.CREATING ).gauge().value() ); - assertEquals( expected.created(), actual.created() ); - assertEquals( expected.created(), registry.get( MicrometerConnectionPoolMetrics.CREATION ).timer().count() ); - assertEquals( expected.failedToCreate(), actual.failedToCreate() ); - assertEquals( expected.failedToCreate(), registry.get( MicrometerConnectionPoolMetrics.FAILED ).counter().count() ); - assertEquals( expected.closed(), actual.closed() ); - assertEquals( expected.closed(), registry.get( MicrometerConnectionPoolMetrics.CLOSED ).counter().count() ); - assertEquals( expected.acquiring(), actual.acquiring() ); - assertEquals( expected.acquiring(), registry.get( MicrometerConnectionPoolMetrics.ACQUIRING ).gauge().value() ); - assertEquals( expected.acquired(), actual.acquired() ); - assertEquals( expected.acquired(), registry.get( MicrometerConnectionPoolMetrics.ACQUISITION ).timer().count() ); - assertEquals( expected.timedOutToAcquire(), actual.timedOutToAcquire() ); - assertEquals( expected.timedOutToAcquire(), registry.get( MicrometerConnectionPoolMetrics.ACQUISITION_TIMEOUT ).counter().count() ); - assertEquals( expected.totalAcquisitionTime(), actual.totalAcquisitionTime() ); - assertEquals( expected.totalAcquisitionTime(), - (long) registry.get( MicrometerConnectionPoolMetrics.ACQUISITION ).timer().totalTime( TimeUnit.MILLISECONDS ) ); - assertEquals( expected.totalConnectionTime(), actual.totalConnectionTime() ); - assertEquals( expected.totalConnectionTime(), - (long) registry.get( MicrometerConnectionPoolMetrics.CREATION ).timer().totalTime( TimeUnit.MILLISECONDS ) ); - assertEquals( expected.totalInUseTime(), actual.totalInUseTime() ); - assertEquals( expected.totalInUseTime(), (long) registry.get( MicrometerConnectionPoolMetrics.USAGE ).timer().totalTime( TimeUnit.MILLISECONDS ) ); - assertEquals( expected.totalInUseCount(), actual.totalInUseCount() ); - assertEquals( expected.totalInUseCount(), registry.get( MicrometerConnectionPoolMetrics.USAGE ).timer().count() ); + void verifyMetrics(ConnectionPoolMetrics expected, ConnectionPoolMetrics actual) { + assertEquals(ID, actual.id()); + assertEquals(expected.inUse(), actual.inUse()); + assertEquals( + expected.inUse(), + registry.get(MicrometerConnectionPoolMetrics.IN_USE).gauge().value()); + assertEquals(expected.idle(), actual.idle()); + assertEquals( + expected.idle(), + registry.get(MicrometerConnectionPoolMetrics.IDLE).gauge().value()); + assertEquals(expected.creating(), actual.creating()); + assertEquals( + expected.creating(), + registry.get(MicrometerConnectionPoolMetrics.CREATING).gauge().value()); + assertEquals(expected.created(), actual.created()); + assertEquals( + expected.created(), + registry.get(MicrometerConnectionPoolMetrics.CREATION).timer().count()); + assertEquals(expected.failedToCreate(), actual.failedToCreate()); + assertEquals( + expected.failedToCreate(), + registry.get(MicrometerConnectionPoolMetrics.FAILED).counter().count()); + assertEquals(expected.closed(), actual.closed()); + assertEquals( + expected.closed(), + registry.get(MicrometerConnectionPoolMetrics.CLOSED).counter().count()); + assertEquals(expected.acquiring(), actual.acquiring()); + assertEquals( + expected.acquiring(), + registry.get(MicrometerConnectionPoolMetrics.ACQUIRING).gauge().value()); + assertEquals(expected.acquired(), actual.acquired()); + assertEquals( + expected.acquired(), + registry.get(MicrometerConnectionPoolMetrics.ACQUISITION) + .timer() + .count()); + assertEquals(expected.timedOutToAcquire(), actual.timedOutToAcquire()); + assertEquals( + expected.timedOutToAcquire(), + registry.get(MicrometerConnectionPoolMetrics.ACQUISITION_TIMEOUT) + .counter() + .count()); + assertEquals(expected.totalAcquisitionTime(), actual.totalAcquisitionTime()); + assertEquals(expected.totalAcquisitionTime(), (long) registry.get(MicrometerConnectionPoolMetrics.ACQUISITION) + .timer() + .totalTime(TimeUnit.MILLISECONDS)); + assertEquals(expected.totalConnectionTime(), actual.totalConnectionTime()); + assertEquals(expected.totalConnectionTime(), (long) + registry.get(MicrometerConnectionPoolMetrics.CREATION).timer().totalTime(TimeUnit.MILLISECONDS)); + assertEquals(expected.totalInUseTime(), actual.totalInUseTime()); + assertEquals(expected.totalInUseTime(), (long) + registry.get(MicrometerConnectionPoolMetrics.USAGE).timer().totalTime(TimeUnit.MILLISECONDS)); + assertEquals(expected.totalInUseCount(), actual.totalInUseCount()); + assertEquals( + expected.totalInUseCount(), + registry.get(MicrometerConnectionPoolMetrics.USAGE).timer().count()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerMetricsProviderTest.java b/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerMetricsProviderTest.java index 9d4a8bd694..5f4e55d7f8 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerMetricsProviderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerMetricsProviderTest.java @@ -18,41 +18,35 @@ */ package org.neo4j.driver.internal.metrics; -import io.micrometer.core.instrument.MeterRegistry; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - import org.neo4j.driver.Metrics; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class MicrometerMetricsProviderTest -{ +class MicrometerMetricsProviderTest { MetricsProvider provider; @BeforeEach - void beforeEach() - { + void beforeEach() { provider = MicrometerMetricsProvider.forGlobalRegistry(); } @Test - void shouldReturnMicrometerMetricsOnMetrics() - { + void shouldReturnMicrometerMetricsOnMetrics() { // GIVEN & WHEN Metrics metrics = provider.metrics(); // THEN - assertTrue( metrics instanceof MicrometerMetrics ); + assertTrue(metrics instanceof MicrometerMetrics); } @Test - void shouldReturnMicrometerMetricsOnMetricsListener() - { + void shouldReturnMicrometerMetricsOnMetricsListener() { // GIVEN & WHEN MetricsListener listener = provider.metricsListener(); // THEN - assertTrue( listener instanceof MicrometerMetrics ); + assertTrue(listener instanceof MicrometerMetrics); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerMetricsTest.java b/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerMetricsTest.java index f4dae3fe02..50055d396d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerMetricsTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerMetricsTest.java @@ -18,24 +18,21 @@ */ package org.neo4j.driver.internal.metrics; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; + import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import java.util.Collection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; - -import java.util.Collection; - import org.neo4j.driver.ConnectionPoolMetrics; import org.neo4j.driver.internal.BoltServerAddress; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.mock; - -class MicrometerMetricsTest -{ +class MicrometerMetricsTest { static final String ID = "id"; MicrometerMetrics metrics; @@ -44,204 +41,191 @@ class MicrometerMetricsTest ConnectionPoolMetricsListener poolMetricsListener; @BeforeEach - void beforeEach() - { + void beforeEach() { registry = new SimpleMeterRegistry(); - metrics = new MicrometerMetrics( registry ); - poolMetricsListener = mock( ConnectionPoolMetricsListener.class, Mockito.withSettings().extraInterfaces( ConnectionPoolMetrics.class ) ); + metrics = new MicrometerMetrics(registry); + poolMetricsListener = mock( + ConnectionPoolMetricsListener.class, + Mockito.withSettings().extraInterfaces(ConnectionPoolMetrics.class)); poolMetrics = (ConnectionPoolMetrics) poolMetricsListener; } @Test - void shouldReturnEmptyConnectionPoolMetrics() - { + void shouldReturnEmptyConnectionPoolMetrics() { // GIVEN & WHEN Collection collection = metrics.connectionPoolMetrics(); // THEN - assertTrue( collection.isEmpty() ); + assertTrue(collection.isEmpty()); } @Test - void shouldDelegateBeforeCreating() - { + void shouldDelegateBeforeCreating() { // GIVEN - ListenerEvent event = mock( ListenerEvent.class ); - metrics.putPoolMetrics( ID, poolMetrics ); + ListenerEvent event = mock(ListenerEvent.class); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.beforeCreating( ID, event ); + metrics.beforeCreating(ID, event); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().beforeCreating( event ); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().beforeCreating(event); } @Test - void shouldDelegateAfterCreated() - { + void shouldDelegateAfterCreated() { // GIVEN - ListenerEvent event = mock( ListenerEvent.class ); - metrics.putPoolMetrics( ID, poolMetrics ); + ListenerEvent event = mock(ListenerEvent.class); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.afterCreated( ID, event ); + metrics.afterCreated(ID, event); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().afterCreated( event ); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().afterCreated(event); } @Test - void shouldDelegateAfterFailedToCreate() - { + void shouldDelegateAfterFailedToCreate() { // GIVEN - metrics.putPoolMetrics( ID, poolMetrics ); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.afterFailedToCreate( ID ); + metrics.afterFailedToCreate(ID); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().afterFailedToCreate(); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().afterFailedToCreate(); } @Test - void shouldDelegateAfterClosed() - { + void shouldDelegateAfterClosed() { // GIVEN - metrics.putPoolMetrics( ID, poolMetrics ); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.afterClosed( ID ); + metrics.afterClosed(ID); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().afterClosed(); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().afterClosed(); } @Test - void shouldDelegateBeforeAcquiringOrCreating() - { + void shouldDelegateBeforeAcquiringOrCreating() { // GIVEN - ListenerEvent event = mock( ListenerEvent.class ); - metrics.putPoolMetrics( ID, poolMetrics ); + ListenerEvent event = mock(ListenerEvent.class); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.beforeAcquiringOrCreating( ID, event ); + metrics.beforeAcquiringOrCreating(ID, event); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().beforeAcquiringOrCreating( event ); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().beforeAcquiringOrCreating(event); } @Test - void shouldDelegateAfterAcquiringOrCreating() - { + void shouldDelegateAfterAcquiringOrCreating() { // GIVEN - metrics.putPoolMetrics( ID, poolMetrics ); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.afterAcquiringOrCreating( ID ); + metrics.afterAcquiringOrCreating(ID); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().afterAcquiringOrCreating(); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().afterAcquiringOrCreating(); } @Test - void shouldDelegateAfterAcquiredOrCreated() - { + void shouldDelegateAfterAcquiredOrCreated() { // GIVEN - ListenerEvent event = mock( ListenerEvent.class ); - metrics.putPoolMetrics( ID, poolMetrics ); + ListenerEvent event = mock(ListenerEvent.class); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.afterAcquiredOrCreated( ID, event ); + metrics.afterAcquiredOrCreated(ID, event); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().afterAcquiredOrCreated( event ); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().afterAcquiredOrCreated(event); } @Test - void shouldDelegateAfterTimedOutToAcquireOrCreate() - { + void shouldDelegateAfterTimedOutToAcquireOrCreate() { // GIVEN - metrics.putPoolMetrics( ID, poolMetrics ); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.afterTimedOutToAcquireOrCreate( ID ); + metrics.afterTimedOutToAcquireOrCreate(ID); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().afterTimedOutToAcquireOrCreate(); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().afterTimedOutToAcquireOrCreate(); } @Test - void shouldDelegateAfterConnectionCreated() - { + void shouldDelegateAfterConnectionCreated() { // GIVEN - ListenerEvent event = mock( ListenerEvent.class ); - metrics.putPoolMetrics( ID, poolMetrics ); + ListenerEvent event = mock(ListenerEvent.class); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.afterConnectionCreated( ID, event ); + metrics.afterConnectionCreated(ID, event); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().acquired( event ); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().acquired(event); } @Test - void shouldDelegateAfterConnectionReleased() - { + void shouldDelegateAfterConnectionReleased() { // GIVEN - ListenerEvent event = mock( ListenerEvent.class ); - metrics.putPoolMetrics( ID, poolMetrics ); + ListenerEvent event = mock(ListenerEvent.class); + metrics.putPoolMetrics(ID, poolMetrics); // WHEN - metrics.afterConnectionReleased( ID, event ); + metrics.afterConnectionReleased(ID, event); // THEN - assertEquals( 1, metrics.connectionPoolMetrics().size() ); - then( poolMetricsListener ).should().released( event ); + assertEquals(1, metrics.connectionPoolMetrics().size()); + then(poolMetricsListener).should().released(event); } @Test - void shouldCreateListenerEvent() - { + void shouldCreateListenerEvent() { // GIVEN & WHEN ListenerEvent event = metrics.createListenerEvent(); // THEN - assertTrue( event instanceof MicrometerTimerListenerEvent ); + assertTrue(event instanceof MicrometerTimerListenerEvent); } @Test - void shouldPutPoolMetrics() - { + void shouldPutPoolMetrics() { // GIVEN int size = metrics.connectionPoolMetrics().size(); // WHEN - metrics.registerPoolMetrics( ID, BoltServerAddress.LOCAL_DEFAULT, () -> 23, () -> 42 ); + metrics.registerPoolMetrics(ID, BoltServerAddress.LOCAL_DEFAULT, () -> 23, () -> 42); // THEN - assertEquals( size + 1, metrics.connectionPoolMetrics().size() ); + assertEquals(size + 1, metrics.connectionPoolMetrics().size()); } @Test - void shouldRemovePoolMetrics() - { + void shouldRemovePoolMetrics() { // GIVEN - metrics.putPoolMetrics( ID, poolMetrics ); + metrics.putPoolMetrics(ID, poolMetrics); int size = metrics.connectionPoolMetrics().size(); // WHEN - metrics.removePoolMetrics( ID ); + metrics.removePoolMetrics(ID); // THEN - assertEquals( size - 1, metrics.connectionPoolMetrics().size() ); + assertEquals(size - 1, metrics.connectionPoolMetrics().size()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerTimerListenerEventTest.java b/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerTimerListenerEventTest.java index 4513ae532b..fbe348a3ce 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerTimerListenerEventTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/metrics/MicrometerTimerListenerEventTest.java @@ -18,27 +18,24 @@ */ package org.neo4j.driver.internal.metrics; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -class MicrometerTimerListenerEventTest -{ +class MicrometerTimerListenerEventTest { MicrometerTimerListenerEvent event; @BeforeEach - void beforeEach() - { - event = new MicrometerTimerListenerEvent( new SimpleMeterRegistry() ); + void beforeEach() { + event = new MicrometerTimerListenerEvent(new SimpleMeterRegistry()); } @Test - void shouldCreateTimerSampleOnStartAndReturnOnGetSample() - { + void shouldCreateTimerSampleOnStartAndReturnOnGetSample() { // GIVEN Timer.Sample initialSample = event.getSample(); @@ -47,7 +44,7 @@ void shouldCreateTimerSampleOnStartAndReturnOnGetSample() // THEN Timer.Sample sample = event.getSample(); - assertNull( initialSample ); - assertNotNull( sample ); + assertNull(initialSample); + assertNotNull(sample); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/net/BoltServerAddressParsingTest.java b/driver/src/test/java/org/neo4j/driver/internal/net/BoltServerAddressParsingTest.java index e423817bd3..3895f94f9d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/net/BoltServerAddressParsingTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/net/BoltServerAddressParsingTest.java @@ -18,96 +18,90 @@ */ package org.neo4j.driver.internal.net; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.neo4j.driver.internal.BoltServerAddress.DEFAULT_PORT; + +import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - import org.neo4j.driver.internal.BoltServerAddress; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.neo4j.driver.internal.BoltServerAddress.DEFAULT_PORT; - -class BoltServerAddressParsingTest -{ - private static Stream addressesToParse() - { +class BoltServerAddressParsingTest { + private static Stream addressesToParse() { return Stream.of( // Hostname - Arguments.of( "localhost", "localhost", DEFAULT_PORT ), - Arguments.of( "localhost:9193", "localhost", 9193 ), - Arguments.of( "neo4j.com", "neo4j.com", DEFAULT_PORT ), - Arguments.of( "royal-server.com.uk", "royal-server.com.uk", DEFAULT_PORT ), - Arguments.of( "royal-server.com.uk:4546", "royal-server.com.uk", 4546 ), + Arguments.of("localhost", "localhost", DEFAULT_PORT), + Arguments.of("localhost:9193", "localhost", 9193), + Arguments.of("neo4j.com", "neo4j.com", DEFAULT_PORT), + Arguments.of("royal-server.com.uk", "royal-server.com.uk", DEFAULT_PORT), + Arguments.of("royal-server.com.uk:4546", "royal-server.com.uk", 4546), // Hostname with scheme - Arguments.of( "bolt://localhost", "localhost", DEFAULT_PORT ), - Arguments.of( "neo4j://localhost", "localhost", DEFAULT_PORT ), - Arguments.of( "bolt://localhost:9193", "localhost", 9193 ), - Arguments.of( "neo4j://localhost:9193", "localhost", 9193 ), - Arguments.of( "bolt://neo4j.com", "neo4j.com", DEFAULT_PORT ), - Arguments.of( "neo4j://neo4j.com", "neo4j.com", DEFAULT_PORT ), - Arguments.of( "bolt://royal-server.com.uk", "royal-server.com.uk", DEFAULT_PORT ), - Arguments.of( "neo4j://royal-server.com.uk", "royal-server.com.uk", DEFAULT_PORT ), - Arguments.of( "bolt://royal-server.com.uk:4546", "royal-server.com.uk", 4546 ), - Arguments.of( "neo4j://royal-server.com.uk:4546", "royal-server.com.uk", 4546 ), + Arguments.of("bolt://localhost", "localhost", DEFAULT_PORT), + Arguments.of("neo4j://localhost", "localhost", DEFAULT_PORT), + Arguments.of("bolt://localhost:9193", "localhost", 9193), + Arguments.of("neo4j://localhost:9193", "localhost", 9193), + Arguments.of("bolt://neo4j.com", "neo4j.com", DEFAULT_PORT), + Arguments.of("neo4j://neo4j.com", "neo4j.com", DEFAULT_PORT), + Arguments.of("bolt://royal-server.com.uk", "royal-server.com.uk", DEFAULT_PORT), + Arguments.of("neo4j://royal-server.com.uk", "royal-server.com.uk", DEFAULT_PORT), + Arguments.of("bolt://royal-server.com.uk:4546", "royal-server.com.uk", 4546), + Arguments.of("neo4j://royal-server.com.uk:4546", "royal-server.com.uk", 4546), // IPv4 - Arguments.of( "127.0.0.1", "127.0.0.1", DEFAULT_PORT ), - Arguments.of( "8.8.8.8:8080", "8.8.8.8", 8080 ), - Arguments.of( "0.0.0.0", "0.0.0.0", DEFAULT_PORT ), - Arguments.of( "192.0.2.235:4329", "192.0.2.235", 4329 ), - Arguments.of( "172.31.255.255:255", "172.31.255.255", 255 ), + Arguments.of("127.0.0.1", "127.0.0.1", DEFAULT_PORT), + Arguments.of("8.8.8.8:8080", "8.8.8.8", 8080), + Arguments.of("0.0.0.0", "0.0.0.0", DEFAULT_PORT), + Arguments.of("192.0.2.235:4329", "192.0.2.235", 4329), + Arguments.of("172.31.255.255:255", "172.31.255.255", 255), // IPv4 with scheme - Arguments.of( "bolt://198.51.100.0", "198.51.100.0", DEFAULT_PORT ), - Arguments.of( "bolt://65.21.10.12:5656", "65.21.10.12", 5656 ), - Arguments.of( "neo4j://12.0.0.5", "12.0.0.5", DEFAULT_PORT ), - Arguments.of( "neo4j://155.55.20.6:9191", "155.55.20.6", 9191 ), + Arguments.of("bolt://198.51.100.0", "198.51.100.0", DEFAULT_PORT), + Arguments.of("bolt://65.21.10.12:5656", "65.21.10.12", 5656), + Arguments.of("neo4j://12.0.0.5", "12.0.0.5", DEFAULT_PORT), + Arguments.of("neo4j://155.55.20.6:9191", "155.55.20.6", 9191), // IPv6 - Arguments.of( "::1", "[::1]", DEFAULT_PORT ), - Arguments.of( "ff02::2:ff00:0", "[ff02::2:ff00:0]", DEFAULT_PORT ), - Arguments.of( "[1afc:0:a33:85a3::ff2f]", "[1afc:0:a33:85a3::ff2f]", DEFAULT_PORT ), - Arguments.of( "[::1]:1515", "[::1]", 1515 ), - Arguments.of( "[ff0a::101]:8989", "[ff0a::101]", 8989 ), + Arguments.of("::1", "[::1]", DEFAULT_PORT), + Arguments.of("ff02::2:ff00:0", "[ff02::2:ff00:0]", DEFAULT_PORT), + Arguments.of("[1afc:0:a33:85a3::ff2f]", "[1afc:0:a33:85a3::ff2f]", DEFAULT_PORT), + Arguments.of("[::1]:1515", "[::1]", 1515), + Arguments.of("[ff0a::101]:8989", "[ff0a::101]", 8989), // IPv6 with scheme - Arguments.of( "bolt://[::1]", "[::1]", DEFAULT_PORT ), - Arguments.of( "neo4j://[::1]", "[::1]", DEFAULT_PORT ), - Arguments.of( "bolt://[ff02::d]", "[ff02::d]", DEFAULT_PORT ), - Arguments.of( "neo4j://[fe80::b279:2f]", "[fe80::b279:2f]", DEFAULT_PORT ), - Arguments.of( "bolt://[::1]:8687", "[::1]", 8687 ), - Arguments.of( "neo4j://[::1]:1212", "[::1]", 1212 ), - Arguments.of( "bolt://[ff02::d]:9090", "[ff02::d]", 9090 ), - Arguments.of( "neo4j://[fe80::b279:2f]:7878", "[fe80::b279:2f]", 7878 ), + Arguments.of("bolt://[::1]", "[::1]", DEFAULT_PORT), + Arguments.of("neo4j://[::1]", "[::1]", DEFAULT_PORT), + Arguments.of("bolt://[ff02::d]", "[ff02::d]", DEFAULT_PORT), + Arguments.of("neo4j://[fe80::b279:2f]", "[fe80::b279:2f]", DEFAULT_PORT), + Arguments.of("bolt://[::1]:8687", "[::1]", 8687), + Arguments.of("neo4j://[::1]:1212", "[::1]", 1212), + Arguments.of("bolt://[ff02::d]:9090", "[ff02::d]", 9090), + Arguments.of("neo4j://[fe80::b279:2f]:7878", "[fe80::b279:2f]", 7878), // IPv6 with zone id - Arguments.of( "::1%eth0", "[::1%eth0]", DEFAULT_PORT ), - Arguments.of( "ff02::2:ff00:0%12", "[ff02::2:ff00:0%12]", DEFAULT_PORT ), - Arguments.of( "[1afc:0:a33:85a3::ff2f%eth1]", "[1afc:0:a33:85a3::ff2f%eth1]", DEFAULT_PORT ), - Arguments.of( "[::1%eth0]:3030", "[::1%eth0]", 3030 ), - Arguments.of( "[ff0a::101%8]:4040", "[ff0a::101%8]", 4040 ), + Arguments.of("::1%eth0", "[::1%eth0]", DEFAULT_PORT), + Arguments.of("ff02::2:ff00:0%12", "[ff02::2:ff00:0%12]", DEFAULT_PORT), + Arguments.of("[1afc:0:a33:85a3::ff2f%eth1]", "[1afc:0:a33:85a3::ff2f%eth1]", DEFAULT_PORT), + Arguments.of("[::1%eth0]:3030", "[::1%eth0]", 3030), + Arguments.of("[ff0a::101%8]:4040", "[ff0a::101%8]", 4040), // IPv6 with scheme and zone id - Arguments.of( "bolt://[::1%eth5]", "[::1%eth5]", DEFAULT_PORT ), - Arguments.of( "neo4j://[::1%12]", "[::1%12]", DEFAULT_PORT ), - Arguments.of( "bolt://[ff02::d%3]", "[ff02::d%3]", DEFAULT_PORT ), - Arguments.of( "neo4j://[fe80::b279:2f%eth0]", "[fe80::b279:2f%eth0]", DEFAULT_PORT ), - Arguments.of( "bolt://[::1%eth3]:8687", "[::1%eth3]", 8687 ), - Arguments.of( "neo4j://[::1%2]:1212", "[::1%2]", 1212 ), - Arguments.of( "bolt://[ff02::d%3]:9090", "[ff02::d%3]", 9090 ), - Arguments.of( "neo4j://[fe80::b279:2f%eth1]:7878", "[fe80::b279:2f%eth1]", 7878 ) - ); + Arguments.of("bolt://[::1%eth5]", "[::1%eth5]", DEFAULT_PORT), + Arguments.of("neo4j://[::1%12]", "[::1%12]", DEFAULT_PORT), + Arguments.of("bolt://[ff02::d%3]", "[ff02::d%3]", DEFAULT_PORT), + Arguments.of("neo4j://[fe80::b279:2f%eth0]", "[fe80::b279:2f%eth0]", DEFAULT_PORT), + Arguments.of("bolt://[::1%eth3]:8687", "[::1%eth3]", 8687), + Arguments.of("neo4j://[::1%2]:1212", "[::1%2]", 1212), + Arguments.of("bolt://[ff02::d%3]:9090", "[ff02::d%3]", 9090), + Arguments.of("neo4j://[fe80::b279:2f%eth1]:7878", "[fe80::b279:2f%eth1]", 7878)); } @ParameterizedTest - @MethodSource( "addressesToParse" ) - void shouldParseAddress( String address, String expectedHost, int expectedPort ) - { - BoltServerAddress parsed = new BoltServerAddress( address ); - assertEquals( expectedHost, parsed.host() ); - assertEquals( expectedPort, parsed.port() ); + @MethodSource("addressesToParse") + void shouldParseAddress(String address, String expectedHost, int expectedPort) { + BoltServerAddress parsed = new BoltServerAddress(address); + assertEquals(expectedHost, parsed.host()); + assertEquals(expectedPort, parsed.port()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/net/BoltServerAddressTest.java b/driver/src/test/java/org/neo4j/driver/internal/net/BoltServerAddressTest.java index aa7341582c..2831b9bb11 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/net/BoltServerAddressTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/net/BoltServerAddressTest.java @@ -18,13 +18,6 @@ */ package org.neo4j.driver.internal.net; -import org.junit.jupiter.api.Test; - -import java.net.URI; - -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.net.ServerAddress; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -34,100 +27,94 @@ import static org.mockito.Mockito.when; import static org.neo4j.driver.internal.BoltServerAddress.DEFAULT_PORT; -class BoltServerAddressTest -{ +import java.net.URI; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.net.ServerAddress; + +class BoltServerAddressTest { @Test - void defaultPortShouldBe7687() - { - assertThat( DEFAULT_PORT, equalTo( 7687 ) ); + void defaultPortShouldBe7687() { + assertThat(DEFAULT_PORT, equalTo(7687)); } @Test - void portShouldUseDefaultIfNotSupplied() - { - assertThat( new BoltServerAddress( "localhost" ).port(), equalTo( BoltServerAddress.DEFAULT_PORT ) ); + void portShouldUseDefaultIfNotSupplied() { + assertThat(new BoltServerAddress("localhost").port(), equalTo(BoltServerAddress.DEFAULT_PORT)); } @Test - void shouldHaveCorrectToString() - { - assertEquals( "localhost:4242", new BoltServerAddress( "localhost", 4242 ).toString() ); - assertEquals( "127.0.0.1:8888", new BoltServerAddress( "127.0.0.1", 8888 ).toString() ); + void shouldHaveCorrectToString() { + assertEquals("localhost:4242", new BoltServerAddress("localhost", 4242).toString()); + assertEquals("127.0.0.1:8888", new BoltServerAddress("127.0.0.1", 8888).toString()); } @Test - void shouldVerifyHost() - { - assertThrows( NullPointerException.class, () -> new BoltServerAddress( null, 0 ) ); + void shouldVerifyHost() { + assertThrows(NullPointerException.class, () -> new BoltServerAddress(null, 0)); } @Test - void shouldVerifyPort() - { - assertThrows( IllegalArgumentException.class, () -> new BoltServerAddress( "localhost", -1 ) ); - assertThrows( IllegalArgumentException.class, () -> new BoltServerAddress( "localhost", -42 ) ); - assertThrows( IllegalArgumentException.class, () -> new BoltServerAddress( "localhost", 65_536 ) ); - assertThrows( IllegalArgumentException.class, () -> new BoltServerAddress( "localhost", 99_999 ) ); + void shouldVerifyPort() { + assertThrows(IllegalArgumentException.class, () -> new BoltServerAddress("localhost", -1)); + assertThrows(IllegalArgumentException.class, () -> new BoltServerAddress("localhost", -42)); + assertThrows(IllegalArgumentException.class, () -> new BoltServerAddress("localhost", 65_536)); + assertThrows(IllegalArgumentException.class, () -> new BoltServerAddress("localhost", 99_999)); } @Test - void shouldCreateBoltServerAddressFromServerAddress() - { - BoltServerAddress address1 = new BoltServerAddress( "my.server.com", 8899 ); - assertSame( address1, BoltServerAddress.from( address1 ) ); - - BoltServerAddress address2 = new BoltServerAddress( "db.neo4j.com" ); - assertSame( address2, BoltServerAddress.from( address2 ) ); - - ServerAddress address3 = mock( ServerAddress.class ); - when( address3.host() ).thenReturn( "graph.database.com" ); - when( address3.port() ).thenReturn( 20600 ); - assertEquals( new BoltServerAddress( "graph.database.com", 20600 ), BoltServerAddress.from( address3 ) ); + void shouldCreateBoltServerAddressFromServerAddress() { + BoltServerAddress address1 = new BoltServerAddress("my.server.com", 8899); + assertSame(address1, BoltServerAddress.from(address1)); + + BoltServerAddress address2 = new BoltServerAddress("db.neo4j.com"); + assertSame(address2, BoltServerAddress.from(address2)); + + ServerAddress address3 = mock(ServerAddress.class); + when(address3.host()).thenReturn("graph.database.com"); + when(address3.port()).thenReturn(20600); + assertEquals(new BoltServerAddress("graph.database.com", 20600), BoltServerAddress.from(address3)); } @Test - void shouldFailToCreateBoltServerAddressFromInvalidServerAddress() - { - ServerAddress address1 = mock( ServerAddress.class ); - when( address1.host() ).thenReturn( null ); - when( address1.port() ).thenReturn( 8888 ); - assertThrows( NullPointerException.class, () -> BoltServerAddress.from( address1 ) ); - - ServerAddress address2 = mock( ServerAddress.class ); - when( address2.host() ).thenReturn( "neo4j.host.com" ); - when( address2.port() ).thenReturn( -1 ); - assertThrows( IllegalArgumentException.class, () -> BoltServerAddress.from( address2 ) ); - - ServerAddress address3 = mock( ServerAddress.class ); - when( address3.host() ).thenReturn( "my.database.org" ); - when( address3.port() ).thenReturn( 99_000 ); - assertThrows( IllegalArgumentException.class, () -> BoltServerAddress.from( address3 ) ); + void shouldFailToCreateBoltServerAddressFromInvalidServerAddress() { + ServerAddress address1 = mock(ServerAddress.class); + when(address1.host()).thenReturn(null); + when(address1.port()).thenReturn(8888); + assertThrows(NullPointerException.class, () -> BoltServerAddress.from(address1)); + + ServerAddress address2 = mock(ServerAddress.class); + when(address2.host()).thenReturn("neo4j.host.com"); + when(address2.port()).thenReturn(-1); + assertThrows(IllegalArgumentException.class, () -> BoltServerAddress.from(address2)); + + ServerAddress address3 = mock(ServerAddress.class); + when(address3.host()).thenReturn("my.database.org"); + when(address3.port()).thenReturn(99_000); + assertThrows(IllegalArgumentException.class, () -> BoltServerAddress.from(address3)); } @Test - void shouldUseUriWithHostButWithoutPort() - { - URI uri = URI.create( "bolt://neo4j.com" ); - BoltServerAddress address = new BoltServerAddress( uri ); + void shouldUseUriWithHostButWithoutPort() { + URI uri = URI.create("bolt://neo4j.com"); + BoltServerAddress address = new BoltServerAddress(uri); - assertEquals( "neo4j.com", address.host() ); - assertEquals( DEFAULT_PORT, address.port() ); + assertEquals("neo4j.com", address.host()); + assertEquals(DEFAULT_PORT, address.port()); } @Test - void shouldUseUriWithHostAndPort() - { - URI uri = URI.create( "bolt://neo4j.com:12345" ); - BoltServerAddress address = new BoltServerAddress( uri ); + void shouldUseUriWithHostAndPort() { + URI uri = URI.create("bolt://neo4j.com:12345"); + BoltServerAddress address = new BoltServerAddress(uri); - assertEquals( "neo4j.com", address.host() ); - assertEquals( 12345, address.port() ); + assertEquals("neo4j.com", address.host()); + assertEquals(12345, address.port()); } @Test - void shouldIncludeHostAndPortInToString() - { - BoltServerAddress address = new BoltServerAddress( "localhost", 8081 ); - assertThat( address.toString(), equalTo( "localhost:8081" ) ); + void shouldIncludeHostAndPortInToString() { + BoltServerAddress address = new BoltServerAddress("localhost", 8081); + assertThat(address.toString(), equalTo("localhost:8081")); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/packstream/PackStreamTest.java b/driver/src/test/java/org/neo4j/driver/internal/packstream/PackStreamTest.java index 4388aa5924..226c84a677 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/packstream/PackStreamTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/packstream/PackStreamTest.java @@ -18,7 +18,14 @@ */ package org.neo4j.driver.internal.packstream; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -29,80 +36,58 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.util.Iterables; import org.neo4j.driver.internal.util.io.BufferedChannelInput; import org.neo4j.driver.internal.util.io.ChannelOutput; -import static java.util.Arrays.asList; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.lessThanOrEqualTo; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class PackStreamTest -{ - public static Map asMap( Object... keysAndValues ) - { - Map map = Iterables.newLinkedHashMapWithSize( keysAndValues.length / 2 ); +public class PackStreamTest { + public static Map asMap(Object... keysAndValues) { + Map map = Iterables.newLinkedHashMapWithSize(keysAndValues.length / 2); String key = null; - for ( Object keyOrValue : keysAndValues ) - { - if ( key == null ) - { + for (Object keyOrValue : keysAndValues) { + if (key == null) { key = keyOrValue.toString(); - } - else - { - map.put( key, keyOrValue ); + } else { + map.put(key, keyOrValue); key = null; } } return map; } - private static class Machine - { + private static class Machine { private final ByteArrayOutputStream output; private final WritableByteChannel writable; private final PackStream.Packer packer; - Machine() - { + Machine() { this.output = new ByteArrayOutputStream(); - this.writable = Channels.newChannel( this.output ); - this.packer = new PackStream.Packer( new ChannelOutput( this.writable ) ); + this.writable = Channels.newChannel(this.output); + this.packer = new PackStream.Packer(new ChannelOutput(this.writable)); } - public void reset() - { + public void reset() { output.reset(); } - public byte[] output() - { + public byte[] output() { return output.toByteArray(); } - PackStream.Packer packer() - { + PackStream.Packer packer() { return packer; } } - private PackStream.Unpacker newUnpacker( byte[] bytes ) - { - ByteArrayInputStream input = new ByteArrayInputStream( bytes ); - return new PackStream.Unpacker( new BufferedChannelInput( Channels.newChannel( input ) ) ); + private PackStream.Unpacker newUnpacker(byte[] bytes) { + ByteArrayInputStream input = new ByteArrayInputStream(bytes); + return new PackStream.Unpacker(new BufferedChannelInput(Channels.newChannel(input))); } @Test - void testCanPackAndUnpackNull() throws Throwable - { + void testCanPackAndUnpackNull() throws Throwable { // Given Machine machine = new Machine(); @@ -111,477 +96,430 @@ void testCanPackAndUnpackNull() throws Throwable // Then byte[] bytes = machine.output(); - assertThat( bytes, equalTo( new byte[]{(byte) 0xC0} ) ); + assertThat(bytes, equalTo(new byte[] {(byte) 0xC0})); // When - PackStream.Unpacker unpacker = newUnpacker( bytes ); + PackStream.Unpacker unpacker = newUnpacker(bytes); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.NULL ) ); - + assertThat(packType, equalTo(PackType.NULL)); } @Test - void testCanPackAndUnpackTrue() throws Throwable - { + void testCanPackAndUnpackTrue() throws Throwable { // Given Machine machine = new Machine(); // When - machine.packer().pack( true ); + machine.packer().pack(true); // Then byte[] bytes = machine.output(); - assertThat( bytes, equalTo( new byte[]{(byte) 0xC3} ) ); + assertThat(bytes, equalTo(new byte[] {(byte) 0xC3})); // When - PackStream.Unpacker unpacker = newUnpacker( bytes ); + PackStream.Unpacker unpacker = newUnpacker(bytes); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.BOOLEAN ) ); - assertThat( unpacker.unpackBoolean(), equalTo( true ) ); - + assertThat(packType, equalTo(PackType.BOOLEAN)); + assertThat(unpacker.unpackBoolean(), equalTo(true)); } @Test - void testCanPackAndUnpackFalse() throws Throwable - { + void testCanPackAndUnpackFalse() throws Throwable { // Given Machine machine = new Machine(); // When - machine.packer().pack( false ); + machine.packer().pack(false); // Then byte[] bytes = machine.output(); - assertThat( bytes, equalTo( new byte[]{(byte) 0xC2} ) ); + assertThat(bytes, equalTo(new byte[] {(byte) 0xC2})); // When - PackStream.Unpacker unpacker = newUnpacker( bytes ); + PackStream.Unpacker unpacker = newUnpacker(bytes); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.BOOLEAN ) ); - assertThat( unpacker.unpackBoolean(), equalTo( false ) ); - + assertThat(packType, equalTo(PackType.BOOLEAN)); + assertThat(unpacker.unpackBoolean(), equalTo(false)); } @Test - void testCanPackAndUnpackTinyIntegers() throws Throwable - { + void testCanPackAndUnpackTinyIntegers() throws Throwable { // Given Machine machine = new Machine(); - for ( long i = -16; i < 128; i++ ) - { + for (long i = -16; i < 128; i++) { // When machine.reset(); - machine.packer().pack( i ); + machine.packer().pack(i); // Then byte[] bytes = machine.output(); - assertThat( bytes.length, equalTo( 1 ) ); + assertThat(bytes.length, equalTo(1)); // When - PackStream.Unpacker unpacker = newUnpacker( bytes ); + PackStream.Unpacker unpacker = newUnpacker(bytes); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.INTEGER ) ); - assertThat( unpacker.unpackLong(), equalTo( i ) ); + assertThat(packType, equalTo(PackType.INTEGER)); + assertThat(unpacker.unpackLong(), equalTo(i)); } } @Test - void testCanPackAndUnpackShortIntegers() throws Throwable - { + void testCanPackAndUnpackShortIntegers() throws Throwable { // Given Machine machine = new Machine(); - for ( long i = -32768; i < 32768; i++ ) - { + for (long i = -32768; i < 32768; i++) { // When machine.reset(); - machine.packer().pack( i ); + machine.packer().pack(i); // Then byte[] bytes = machine.output(); - assertThat( bytes.length, lessThanOrEqualTo( 3 ) ); + assertThat(bytes.length, lessThanOrEqualTo(3)); // When - PackStream.Unpacker unpacker = newUnpacker( bytes ); + PackStream.Unpacker unpacker = newUnpacker(bytes); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.INTEGER ) ); - assertThat( unpacker.unpackLong(), equalTo( i ) ); - + assertThat(packType, equalTo(PackType.INTEGER)); + assertThat(unpacker.unpackLong(), equalTo(i)); } - } @Test - void testCanPackAndUnpackPowersOfTwoAsIntegers() throws Throwable - { + void testCanPackAndUnpackPowersOfTwoAsIntegers() throws Throwable { // Given Machine machine = new Machine(); - for ( int i = 0; i < 32; i++ ) - { - long n = (long) Math.pow( 2, i ); + for (int i = 0; i < 32; i++) { + long n = (long) Math.pow(2, i); // When machine.reset(); - machine.packer().pack( n ); + machine.packer().pack(n); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.INTEGER ) ); - assertThat( unpacker.unpackLong(), equalTo( n ) ); - + assertThat(packType, equalTo(PackType.INTEGER)); + assertThat(unpacker.unpackLong(), equalTo(n)); } - } @Test - void testCanPackAndUnpackPowersOfTwoPlusABitAsDoubles() throws Throwable - { + void testCanPackAndUnpackPowersOfTwoPlusABitAsDoubles() throws Throwable { // Given Machine machine = new Machine(); - for ( int i = 0; i < 32; i++ ) - { - double n = Math.pow( 2, i ) + 0.5; + for (int i = 0; i < 32; i++) { + double n = Math.pow(2, i) + 0.5; // When machine.reset(); - machine.packer().pack( n ); + machine.packer().pack(n); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.FLOAT ) ); - assertThat( unpacker.unpackDouble(), equalTo( n ) ); - + assertThat(packType, equalTo(PackType.FLOAT)); + assertThat(unpacker.unpackDouble(), equalTo(n)); } - } @Test - void testCanPackAndUnpackPowersOfTwoMinusABitAsDoubles() throws Throwable - { + void testCanPackAndUnpackPowersOfTwoMinusABitAsDoubles() throws Throwable { // Given Machine machine = new Machine(); - for ( int i = 0; i < 32; i++ ) - { - double n = Math.pow( 2, i ) - 0.5; + for (int i = 0; i < 32; i++) { + double n = Math.pow(2, i) - 0.5; // When machine.reset(); - machine.packer().pack( n ); + machine.packer().pack(n); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.FLOAT ) ); - assertThat( unpacker.unpackDouble(), equalTo( n ) ); - + assertThat(packType, equalTo(PackType.FLOAT)); + assertThat(unpacker.unpackDouble(), equalTo(n)); } - } @Test - void testCanPackAndUnpackByteArrays() throws Throwable - { + void testCanPackAndUnpackByteArrays() throws Throwable { // Given Machine machine = new Machine(); - testByteArrayPackingAndUnpacking( machine, 0 ); - for ( int i = 0; i < 24; i++ ) - { - testByteArrayPackingAndUnpacking( machine, (int) Math.pow( 2, i ) ); + testByteArrayPackingAndUnpacking(machine, 0); + for (int i = 0; i < 24; i++) { + testByteArrayPackingAndUnpacking(machine, (int) Math.pow(2, i)); } } - private void testByteArrayPackingAndUnpacking( Machine machine, int length ) throws Throwable - { + private void testByteArrayPackingAndUnpacking(Machine machine, int length) throws Throwable { byte[] array = new byte[length]; machine.reset(); - machine.packer().pack( array ); + machine.packer().pack(array); - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.BYTES ) ); - assertArrayEquals( array, unpacker.unpackBytes() ); + assertThat(packType, equalTo(PackType.BYTES)); + assertArrayEquals(array, unpacker.unpackBytes()); } @Test - void testCanPackAndUnpackStrings() throws Throwable - { + void testCanPackAndUnpackStrings() throws Throwable { // Given Machine machine = new Machine(); - for ( int i = 0; i < 24; i++ ) - { - String string = new String( new byte[(int) Math.pow( 2, i )] ); + for (int i = 0; i < 24; i++) { + String string = new String(new byte[(int) Math.pow(2, i)]); // When machine.reset(); - machine.packer().pack( string ); + machine.packer().pack(string); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.STRING ) ); - assertThat( unpacker.unpackString(), equalTo( string ) ); + assertThat(packType, equalTo(PackType.STRING)); + assertThat(unpacker.unpackString(), equalTo(string)); } - } @Test - void testCanPackAndUnpackBytes() throws Throwable - { + void testCanPackAndUnpackBytes() throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - packer.pack( "ABCDEFGHIJ".getBytes() ); + packer.pack("ABCDEFGHIJ".getBytes()); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.BYTES ) ); - assertArrayEquals( "ABCDEFGHIJ".getBytes(), unpacker.unpackBytes() ); - + assertThat(packType, equalTo(PackType.BYTES)); + assertArrayEquals("ABCDEFGHIJ".getBytes(), unpacker.unpackBytes()); } @Test - void testCanPackAndUnpackString() throws Throwable - { + void testCanPackAndUnpackString() throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - packer.pack( "ABCDEFGHIJ" ); + packer.pack("ABCDEFGHIJ"); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.STRING ) ); - assertThat( unpacker.unpackString(), equalTo( "ABCDEFGHIJ" )); - + assertThat(packType, equalTo(PackType.STRING)); + assertThat(unpacker.unpackString(), equalTo("ABCDEFGHIJ")); } @Test - void testCanPackAndUnpackSpecialString() throws Throwable - { + void testCanPackAndUnpackSpecialString() throws Throwable { // Given Machine machine = new Machine(); String code = "Mjölnir"; // When PackStream.Packer packer = machine.packer(); - packer.pack( code ); + packer.pack(code); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); // Then - assertThat( packType, equalTo( PackType.STRING ) ); - assertThat( unpacker.unpackString(), equalTo( code )); + assertThat(packType, equalTo(PackType.STRING)); + assertThat(unpacker.unpackString(), equalTo(code)); } @Test - void testCanPackAndUnpackListOneItemAtATime() throws Throwable - { + void testCanPackAndUnpackListOneItemAtATime() throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - packer.packListHeader( 3 ); - packer.pack( 12 ); - packer.pack( 13 ); - packer.pack( 14 ); + packer.packListHeader(3); + packer.pack(12); + packer.pack(13); + packer.pack(14); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.LIST ) ); - assertThat( unpacker.unpackListHeader(), equalTo( 3L ) ); - assertThat( unpacker.unpackLong(), equalTo( 12L ) ); - assertThat( unpacker.unpackLong(), equalTo( 13L ) ); - assertThat( unpacker.unpackLong(), equalTo( 14L ) ); - + assertThat(packType, equalTo(PackType.LIST)); + assertThat(unpacker.unpackListHeader(), equalTo(3L)); + assertThat(unpacker.unpackLong(), equalTo(12L)); + assertThat(unpacker.unpackLong(), equalTo(13L)); + assertThat(unpacker.unpackLong(), equalTo(14L)); } @Test - void testCanPackAndUnpackListOfString() throws Throwable - { + void testCanPackAndUnpackListOfString() throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - packer.pack( asList( "eins", "zwei", "drei" ) ); + packer.pack(asList("eins", "zwei", "drei")); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.LIST ) ); - assertThat( unpacker.unpackListHeader(), equalTo( 3L ) ); - assertThat( unpacker.unpackString(), equalTo( "eins" ) ); - assertThat( unpacker.unpackString(), equalTo( "zwei" ) ); - assertThat( unpacker.unpackString(), equalTo( "drei" ) ); - + assertThat(packType, equalTo(PackType.LIST)); + assertThat(unpacker.unpackListHeader(), equalTo(3L)); + assertThat(unpacker.unpackString(), equalTo("eins")); + assertThat(unpacker.unpackString(), equalTo("zwei")); + assertThat(unpacker.unpackString(), equalTo("drei")); } @Test - void testCanPackAndUnpackListOfSpecialStrings() throws Throwable - { - assertPackStringLists( 3, "Mjölnir" ); - assertPackStringLists( 126, "Mjölnir" ); - assertPackStringLists( 3000, "Mjölnir" ); - assertPackStringLists( 32768, "Mjölnir" ); + void testCanPackAndUnpackListOfSpecialStrings() throws Throwable { + assertPackStringLists(3, "Mjölnir"); + assertPackStringLists(126, "Mjölnir"); + assertPackStringLists(3000, "Mjölnir"); + assertPackStringLists(32768, "Mjölnir"); } @Test - void testCanPackAndUnpackListOfStringOneByOne() throws Throwable - { + void testCanPackAndUnpackListOfStringOneByOne() throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - packer.packListHeader( 3 ); - packer.pack( "eins" ); - packer.pack( "zwei" ); - packer.pack( "drei" ); + packer.packListHeader(3); + packer.pack("eins"); + packer.pack("zwei"); + packer.pack("drei"); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.LIST ) ); - assertThat( unpacker.unpackListHeader(), equalTo( 3L ) ); - assertThat( unpacker.unpackString(), equalTo( "eins" ) ); - assertThat( unpacker.unpackString(), equalTo( "zwei" ) ); - assertThat( unpacker.unpackString(), equalTo( "drei" ) ); - + assertThat(packType, equalTo(PackType.LIST)); + assertThat(unpacker.unpackListHeader(), equalTo(3L)); + assertThat(unpacker.unpackString(), equalTo("eins")); + assertThat(unpacker.unpackString(), equalTo("zwei")); + assertThat(unpacker.unpackString(), equalTo("drei")); } @Test - void testCanPackAndUnpackListOfSpecialStringOneByOne() throws Throwable - { + void testCanPackAndUnpackListOfSpecialStringOneByOne() throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - packer.packListHeader( 3 ); - packer.pack( "Mjölnir" ); - packer.pack( "Mjölnir" ); - packer.pack( "Mjölnir" ); + packer.packListHeader(3); + packer.pack("Mjölnir"); + packer.pack("Mjölnir"); + packer.pack("Mjölnir"); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.LIST ) ); - assertThat( unpacker.unpackListHeader(), equalTo( 3L ) ); - assertThat( unpacker.unpackString(), equalTo( "Mjölnir" ) ); - assertThat( unpacker.unpackString(), equalTo( "Mjölnir" ) ); - assertThat( unpacker.unpackString(), equalTo( "Mjölnir" ) ); - + assertThat(packType, equalTo(PackType.LIST)); + assertThat(unpacker.unpackListHeader(), equalTo(3L)); + assertThat(unpacker.unpackString(), equalTo("Mjölnir")); + assertThat(unpacker.unpackString(), equalTo("Mjölnir")); + assertThat(unpacker.unpackString(), equalTo("Mjölnir")); } @Test - void testCanPackAndUnpackMap() throws Throwable - { - assertMap( 2 ); - assertMap( 126 ); - assertMap( 2439 ); - assertMap( 32768 ); + void testCanPackAndUnpackMap() throws Throwable { + assertMap(2); + assertMap(126); + assertMap(2439); + assertMap(32768); } @Test - void testCanPackAndUnpackStruct() throws Throwable - { + void testCanPackAndUnpackStruct() throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - packer.packStructHeader( 3, (byte)'N' ); - packer.pack( 12 ); - packer.pack( asList( "Person", "Employee" ) ); - packer.pack( asMap( "name", "Alice", "age", 33 ) ); + packer.packStructHeader(3, (byte) 'N'); + packer.pack(12); + packer.pack(asList("Person", "Employee")); + packer.pack(asMap("name", "Alice", "age", 33)); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.STRUCT ) ); - assertThat( unpacker.unpackStructHeader(), equalTo( 3L ) ); - assertThat( unpacker.unpackStructSignature(), equalTo( (byte)'N' ) ); + assertThat(packType, equalTo(PackType.STRUCT)); + assertThat(unpacker.unpackStructHeader(), equalTo(3L)); + assertThat(unpacker.unpackStructSignature(), equalTo((byte) 'N')); - assertThat( unpacker.unpackLong(), equalTo( 12L ) ); + assertThat(unpacker.unpackLong(), equalTo(12L)); - assertThat( unpacker.unpackListHeader(), equalTo( 2L ) ); - assertThat( unpacker.unpackString(), equalTo( "Person" )); - assertThat( unpacker.unpackString(), equalTo( "Employee" )); + assertThat(unpacker.unpackListHeader(), equalTo(2L)); + assertThat(unpacker.unpackString(), equalTo("Person")); + assertThat(unpacker.unpackString(), equalTo("Employee")); - assertThat( unpacker.unpackMapHeader(), equalTo( 2L ) ); - assertThat( unpacker.unpackString(), equalTo( "name" )); - assertThat( unpacker.unpackString(), equalTo( "Alice" )); - assertThat( unpacker.unpackString(), equalTo( "age" )); - assertThat( unpacker.unpackLong(), equalTo( 33L ) ); + assertThat(unpacker.unpackMapHeader(), equalTo(2L)); + assertThat(unpacker.unpackString(), equalTo("name")); + assertThat(unpacker.unpackString(), equalTo("Alice")); + assertThat(unpacker.unpackString(), equalTo("age")); + assertThat(unpacker.unpackLong(), equalTo(33L)); } @Test - void testCanPackAndUnpackStructsOfDifferentSizes() throws Throwable - { - assertStruct( 2 ); - assertStruct( 126 ); - assertStruct( 2439 ); + void testCanPackAndUnpackStructsOfDifferentSizes() throws Throwable { + assertStruct(2); + assertStruct(126); + assertStruct(2439); - //we cannot have 'too many' fields - assertThrows( PackStream.Overflow.class, () -> assertStruct( 65536 ) ); + // we cannot have 'too many' fields + assertThrows(PackStream.Overflow.class, () -> assertStruct(65536)); } @Test - void testCanDoStreamingListUnpacking() throws Throwable - { + void testCanDoStreamingListUnpacking() throws Throwable { // Given Machine machine = new Machine(); PackStream.Packer packer = machine.packer(); - packer.pack( asList(1,2,3,asList(4,5)) ); + packer.pack(asList(1, 2, 3, asList(4, 5))); // When I unpack this value - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); // Then I can do streaming unpacking long size = unpacker.unpackListHeader(); @@ -594,29 +532,28 @@ void testCanDoStreamingListUnpacking() throws Throwable long e = unpacker.unpackLong(); // And all the values should be sane - assertEquals( 4, size ); - assertEquals( 2, innerSize ); - assertEquals( 1, a ); - assertEquals( 2, b ); - assertEquals( 3, c ); - assertEquals( 4, d ); - assertEquals( 5, e ); + assertEquals(4, size); + assertEquals(2, innerSize); + assertEquals(1, a); + assertEquals(2, b); + assertEquals(3, c); + assertEquals(4, d); + assertEquals(5, e); } @Test - void testCanDoStreamingStructUnpacking() throws Throwable - { + void testCanDoStreamingStructUnpacking() throws Throwable { // Given Machine machine = new Machine(); PackStream.Packer packer = machine.packer(); - packer.packStructHeader( 4, (byte)'~' ); - packer.pack( 1 ); - packer.pack( 2 ); - packer.pack( 3 ); - packer.pack( asList( 4,5 ) ); + packer.packStructHeader(4, (byte) '~'); + packer.pack(1); + packer.pack(2); + packer.pack(3); + packer.pack(asList(4, 5)); // When I unpack this value - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); // Then I can do streaming unpacking long size = unpacker.unpackStructHeader(); @@ -630,30 +567,29 @@ void testCanDoStreamingStructUnpacking() throws Throwable long e = unpacker.unpackLong(); // And all the values should be sane - assertEquals( 4, size ); - assertEquals( '~', signature ); - assertEquals( 2, innerSize ); - assertEquals( 1, a ); - assertEquals( 2, b ); - assertEquals( 3, c ); - assertEquals( 4, d ); - assertEquals( 5, e ); + assertEquals(4, size); + assertEquals('~', signature); + assertEquals(2, innerSize); + assertEquals(1, a); + assertEquals(2, b); + assertEquals(3, c); + assertEquals(4, d); + assertEquals(5, e); } @Test - void testCanDoStreamingMapUnpacking() throws Throwable - { + void testCanDoStreamingMapUnpacking() throws Throwable { // Given Machine machine = new Machine(); PackStream.Packer packer = machine.packer(); - packer.packMapHeader( 2 ); - packer.pack( "name" ); - packer.pack( "Bob" ); - packer.pack( "cat_ages" ); - packer.pack( asList( 4.3, true ) ); + packer.packMapHeader(2); + packer.pack("name"); + packer.pack("Bob"); + packer.pack("cat_ages"); + packer.pack(asList(4.3, true)); // When I unpack this value - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); // Then I can do streaming unpacking long size = unpacker.unpackMapHeader(); @@ -666,26 +602,25 @@ void testCanDoStreamingMapUnpacking() throws Throwable boolean e = unpacker.unpackBoolean(); // And all the values should be sane - assertEquals( 2, size ); - assertEquals( 2, innerSize ); - assertEquals( "name", k1 ); - assertEquals( "Bob", v1 ); - assertEquals( "cat_ages", k2 ); - assertEquals( 4.3, d, 0.0001 ); - assertTrue( e ); + assertEquals(2, size); + assertEquals(2, innerSize); + assertEquals("name", k1); + assertEquals("Bob", v1); + assertEquals("cat_ages", k2); + assertEquals(4.3, d, 0.0001); + assertTrue(e); } @Test - void handlesDataCrossingBufferBoundaries() throws Throwable - { + void handlesDataCrossingBufferBoundaries() throws Throwable { // Given Machine machine = new Machine(); PackStream.Packer packer = machine.packer(); - packer.pack( Long.MAX_VALUE ); - packer.pack( Long.MAX_VALUE ); + packer.pack(Long.MAX_VALUE); + packer.pack(Long.MAX_VALUE); - ReadableByteChannel ch = Channels.newChannel( new ByteArrayInputStream( machine.output() ) ); - PackStream.Unpacker unpacker = new PackStream.Unpacker( new BufferedChannelInput( 11, ch ) ); + ReadableByteChannel ch = Channels.newChannel(new ByteArrayInputStream(machine.output())); + PackStream.Unpacker unpacker = new PackStream.Unpacker(new BufferedChannelInput(11, ch)); // Serialized ch will look like, and misalign with the 11-byte unpack buffer: @@ -703,123 +638,109 @@ void handlesDataCrossingBufferBoundaries() throws Throwable } @Test - void testCanPeekOnNextType() throws Throwable - { + void testCanPeekOnNextType() throws Throwable { // When & Then - assertPeekType( PackType.STRING, "a string" ); - assertPeekType( PackType.INTEGER, 123 ); - assertPeekType( PackType.FLOAT, 123.123 ); - assertPeekType( PackType.BOOLEAN, true ); - assertPeekType( PackType.LIST, asList( 1,2,3 ) ); - assertPeekType( PackType.MAP, asMap( "l",3 ) ); + assertPeekType(PackType.STRING, "a string"); + assertPeekType(PackType.INTEGER, 123); + assertPeekType(PackType.FLOAT, 123.123); + assertPeekType(PackType.BOOLEAN, true); + assertPeekType(PackType.LIST, asList(1, 2, 3)); + assertPeekType(PackType.MAP, asMap("l", 3)); } @Test - void shouldFailForUnknownValue() throws IOException - { + void shouldFailForUnknownValue() throws IOException { // Given Machine machine = new Machine(); PackStream.Packer packer = machine.packer(); // Expect - assertThrows( PackStream.UnPackable.class, () -> packer.pack( new MyRandomClass() ) ); + assertThrows(PackStream.UnPackable.class, () -> packer.pack(new MyRandomClass())); } - private static class MyRandomClass{} + private static class MyRandomClass {} - private void assertPeekType( PackType type, Object value ) throws IOException - { + private void assertPeekType(PackType type, Object value) throws IOException { // Given Machine machine = new Machine(); PackStream.Packer packer = machine.packer(); - packer.pack( value ); + packer.pack(value); - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); // When & Then - assertEquals( type, unpacker.peekNextType() ); + assertEquals(type, unpacker.peekNextType()); } - private void assertPackStringLists( int size, String value ) throws Throwable - { + private void assertPackStringLists(int size, String value) throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - ArrayList strings = new ArrayList<>( size ); - for ( int i = 0; i < size; i++ ) - { - strings.add( i, value ); + ArrayList strings = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + strings.add(i, value); } - packer.pack( strings ); + packer.pack(strings); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.LIST ) ); + assertThat(packType, equalTo(PackType.LIST)); - assertThat( unpacker.unpackListHeader(), equalTo( (long) size ) ); - for ( int i = 0; i < size; i++ ) - { - assertThat( unpacker.unpackString(), equalTo( "Mjölnir" ) ); + assertThat(unpacker.unpackListHeader(), equalTo((long) size)); + for (int i = 0; i < size; i++) { + assertThat(unpacker.unpackString(), equalTo("Mjölnir")); } } - private void assertMap( int size ) throws Throwable - { + private void assertMap(int size) throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - HashMap map = new HashMap<>(); - for ( int i = 0; i < size; i++ ) - { - map.put( Integer.toString( i ), i ); + HashMap map = new HashMap<>(); + for (int i = 0; i < size; i++) { + map.put(Integer.toString(i), i); } - packer.pack( map ); + packer.pack(map); // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.MAP ) ); + assertThat(packType, equalTo(PackType.MAP)); + assertThat(unpacker.unpackMapHeader(), equalTo((long) size)); - assertThat( unpacker.unpackMapHeader(), equalTo( (long) size ) ); - - for ( int i = 0; i < size; i++ ) - { - assertThat( unpacker.unpackString(), equalTo( Long.toString( unpacker.unpackLong() ) ) ); + for (int i = 0; i < size; i++) { + assertThat(unpacker.unpackString(), equalTo(Long.toString(unpacker.unpackLong()))); } } - private void assertStruct( int size ) throws Throwable - { + private void assertStruct(int size) throws Throwable { // Given Machine machine = new Machine(); // When PackStream.Packer packer = machine.packer(); - packer.packStructHeader( size, (byte) 'N' ); - for ( int i = 0; i < size; i++ ) - { - packer.pack( i ); + packer.packStructHeader(size, (byte) 'N'); + for (int i = 0; i < size; i++) { + packer.pack(i); } - // Then - PackStream.Unpacker unpacker = newUnpacker( machine.output() ); + PackStream.Unpacker unpacker = newUnpacker(machine.output()); PackType packType = unpacker.peekNextType(); - assertThat( packType, equalTo( PackType.STRUCT ) ); - assertThat( unpacker.unpackStructHeader(), equalTo( (long) size ) ); - assertThat( unpacker.unpackStructSignature(), equalTo( (byte) 'N' ) ); + assertThat(packType, equalTo(PackType.STRUCT)); + assertThat(unpacker.unpackStructHeader(), equalTo((long) size)); + assertThat(unpacker.unpackStructSignature(), equalTo((byte) 'N')); - for ( int i = 0; i < size; i++ ) - { - assertThat( unpacker.unpackLong(), equalTo( (long) i ) ); + for (int i = 0; i < size; i++) { + assertThat(unpacker.unpackLong(), equalTo((long) i)); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxResultTest.java b/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxResultTest.java index 365be4e432..2198ca4b60 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxResultTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxResultTest.java @@ -18,16 +18,24 @@ */ package org.neo4j.driver.internal.reactive; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +import static java.util.Arrays.asList; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static java.util.function.Predicate.isEqual; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Values.values; +import static org.neo4j.driver.internal.util.Futures.failedFuture; import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.Record; import org.neo4j.driver.internal.InternalRecord; import org.neo4j.driver.internal.cursor.RxResultCursor; @@ -38,183 +46,167 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.summary.ResultSummary; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; -import static java.util.Arrays.asList; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static java.util.function.Predicate.isEqual; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Values.values; -import static org.neo4j.driver.internal.util.Futures.failedFuture; - -class InternalRxResultTest -{ +class InternalRxResultTest { @Test - void shouldInitCursorFuture() - { + void shouldInitCursorFuture() { // Given - RxResultCursor cursor = mock( RxResultCursorImpl.class ); - InternalRxResult rxResult = newRxResult( cursor ); + RxResultCursor cursor = mock(RxResultCursorImpl.class); + InternalRxResult rxResult = newRxResult(cursor); // When - CompletableFuture cursorFuture = rxResult.initCursorFuture().toCompletableFuture(); + CompletableFuture cursorFuture = + rxResult.initCursorFuture().toCompletableFuture(); // Then - assertTrue( cursorFuture.isDone() ); - assertThat( Futures.getNow( cursorFuture ), equalTo( cursor ) ); + assertTrue(cursorFuture.isDone()); + assertThat(Futures.getNow(cursorFuture), equalTo(cursor)); } @Test - void shouldInitCursorFutureWithFailedCursor() - { + void shouldInitCursorFutureWithFailedCursor() { // Given - RuntimeException error = new RuntimeException( "Failed to obtain cursor probably due to connection problem" ); - InternalRxResult rxResult = newRxResult( error ); + RuntimeException error = new RuntimeException("Failed to obtain cursor probably due to connection problem"); + InternalRxResult rxResult = newRxResult(error); // When - CompletableFuture cursorFuture = rxResult.initCursorFuture().toCompletableFuture(); + CompletableFuture cursorFuture = + rxResult.initCursorFuture().toCompletableFuture(); // Then - assertTrue( cursorFuture.isDone() ); - RuntimeException actualError = assertThrows( RuntimeException.class, () -> Futures.getNow( cursorFuture ) ); - assertThat( actualError.getCause(), equalTo( error ) ); + assertTrue(cursorFuture.isDone()); + RuntimeException actualError = assertThrows(RuntimeException.class, () -> Futures.getNow(cursorFuture)); + assertThat(actualError.getCause(), equalTo(error)); } @Test - void shouldObtainKeys() - { + void shouldObtainKeys() { // Given - RxResultCursor cursor = mock( RxResultCursorImpl.class ); - RxResult rxResult = newRxResult( cursor ); + RxResultCursor cursor = mock(RxResultCursorImpl.class); + RxResult rxResult = newRxResult(cursor); - List keys = Arrays.asList( "one", "two", "three" ); - when( cursor.keys() ).thenReturn( keys ); + List keys = Arrays.asList("one", "two", "three"); + when(cursor.keys()).thenReturn(keys); // When & Then - StepVerifier.create( Flux.from( rxResult.keys() ) ) - .expectNext( Arrays.asList( "one", "two", "three" ) ) - .verifyComplete(); + StepVerifier.create(Flux.from(rxResult.keys())) + .expectNext(Arrays.asList("one", "two", "three")) + .verifyComplete(); } @Test - void shouldErrorWhenFailedObtainKeys() - { + void shouldErrorWhenFailedObtainKeys() { // Given - RuntimeException error = new RuntimeException( "Failed to obtain cursor" ); - InternalRxResult rxResult = newRxResult( error ); + RuntimeException error = new RuntimeException("Failed to obtain cursor"); + InternalRxResult rxResult = newRxResult(error); // When & Then - StepVerifier.create( Flux.from( rxResult.keys() ) ) - .expectErrorMatches( isEqual( error ) ) - .verify(); + StepVerifier.create(Flux.from(rxResult.keys())) + .expectErrorMatches(isEqual(error)) + .verify(); } @Test - void shouldCancelKeys() - { + void shouldCancelKeys() { // Given - RxResultCursor cursor = mock( RxResultCursorImpl.class ); - RxResult rxResult = newRxResult( cursor ); + RxResultCursor cursor = mock(RxResultCursorImpl.class); + RxResult rxResult = newRxResult(cursor); - List keys = Arrays.asList( "one", "two", "three" ); - when( cursor.keys() ).thenReturn( keys ); + List keys = Arrays.asList("one", "two", "three"); + when(cursor.keys()).thenReturn(keys); // When & Then - StepVerifier.create( Flux.from( rxResult.keys() ).limitRate( 1 ).take( 1 ) ) - .expectNext( Arrays.asList( "one", "two", "three" ) ) - .verifyComplete(); + StepVerifier.create(Flux.from(rxResult.keys()).limitRate(1).take(1)) + .expectNext(Arrays.asList("one", "two", "three")) + .verifyComplete(); } @Test - void shouldObtainRecordsAndSummary() - { + void shouldObtainRecordsAndSummary() { // Given - Record record1 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 1, 1, 1 ) ); - Record record2 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 2, 2, 2 ) ); - Record record3 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 3, 3, 3 ) ); + Record record1 = new InternalRecord(asList("key1", "key2", "key3"), values(1, 1, 1)); + Record record2 = new InternalRecord(asList("key1", "key2", "key3"), values(2, 2, 2)); + Record record3 = new InternalRecord(asList("key1", "key2", "key3"), values(3, 3, 3)); - PullResponseHandler pullHandler = new ListBasedPullHandler( Arrays.asList( record1, record2, record3 ) ); - RxResult rxResult = newRxResult( pullHandler ); + PullResponseHandler pullHandler = new ListBasedPullHandler(Arrays.asList(record1, record2, record3)); + RxResult rxResult = newRxResult(pullHandler); // When - StepVerifier.create( Flux.from( rxResult.records() ) ) - .expectNext( record1 ) - .expectNext( record2 ) - .expectNext( record3 ) - .verifyComplete(); - StepVerifier.create( Mono.from( rxResult.consume() ) ).expectNextCount( 1 ).verifyComplete(); + StepVerifier.create(Flux.from(rxResult.records())) + .expectNext(record1) + .expectNext(record2) + .expectNext(record3) + .verifyComplete(); + StepVerifier.create(Mono.from(rxResult.consume())).expectNextCount(1).verifyComplete(); } @Test - void shouldCancelStreamingButObtainSummary() - { + void shouldCancelStreamingButObtainSummary() { // Given - Record record1 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 1, 1, 1 ) ); - Record record2 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 2, 2, 2 ) ); - Record record3 = new InternalRecord( asList( "key1", "key2", "key3" ), values( 3, 3, 3 ) ); + Record record1 = new InternalRecord(asList("key1", "key2", "key3"), values(1, 1, 1)); + Record record2 = new InternalRecord(asList("key1", "key2", "key3"), values(2, 2, 2)); + Record record3 = new InternalRecord(asList("key1", "key2", "key3"), values(3, 3, 3)); - PullResponseHandler pullHandler = new ListBasedPullHandler( Arrays.asList( record1, record2, record3 ) ); - RxResult rxResult = newRxResult( pullHandler ); + PullResponseHandler pullHandler = new ListBasedPullHandler(Arrays.asList(record1, record2, record3)); + RxResult rxResult = newRxResult(pullHandler); // When - StepVerifier.create( Flux.from( rxResult.records() ).limitRate( 1 ).take( 1 ) ) - .expectNext( record1 ) - .verifyComplete(); - StepVerifier.create( Mono.from( rxResult.consume() ) ).expectNextCount( 1 ).verifyComplete(); + StepVerifier.create(Flux.from(rxResult.records()).limitRate(1).take(1)) + .expectNext(record1) + .verifyComplete(); + StepVerifier.create(Mono.from(rxResult.consume())).expectNextCount(1).verifyComplete(); } @Test - void shouldErrorIfFailedToCreateCursor() - { + void shouldErrorIfFailedToCreateCursor() { // Given - Throwable error = new RuntimeException( "Hi" ); - RxResult rxResult = newRxResult( error ); + Throwable error = new RuntimeException("Hi"); + RxResult rxResult = newRxResult(error); // When & Then - StepVerifier.create( Flux.from( rxResult.records() ) ).expectErrorMatches( isEqual( error ) ).verify(); - StepVerifier.create( Mono.from( rxResult.consume() ) ).expectErrorMatches( isEqual( error ) ).verify(); + StepVerifier.create(Flux.from(rxResult.records())) + .expectErrorMatches(isEqual(error)) + .verify(); + StepVerifier.create(Mono.from(rxResult.consume())) + .expectErrorMatches(isEqual(error)) + .verify(); } @Test - void shouldErrorIfFailedToStream() - { + void shouldErrorIfFailedToStream() { // Given - Throwable error = new RuntimeException( "Hi" ); - RxResult rxResult = newRxResult( new ListBasedPullHandler( error ) ); + Throwable error = new RuntimeException("Hi"); + RxResult rxResult = newRxResult(new ListBasedPullHandler(error)); // When & Then - StepVerifier.create( Flux.from( rxResult.records() ) ).expectErrorMatches( isEqual( error ) ).verify(); - StepVerifier.create( Mono.from( rxResult.consume() ) ) - .assertNext( summary -> assertThat( summary, instanceOf( ResultSummary.class ) ) ).verifyComplete(); + StepVerifier.create(Flux.from(rxResult.records())) + .expectErrorMatches(isEqual(error)) + .verify(); + StepVerifier.create(Mono.from(rxResult.consume())) + .assertNext(summary -> assertThat(summary, instanceOf(ResultSummary.class))) + .verifyComplete(); } - private InternalRxResult newRxResult( PullResponseHandler pullHandler ) - { - RunResponseHandler runHandler = mock( RunResponseHandler.class ); - RxResultCursor cursor = new RxResultCursorImpl( runHandler, pullHandler ); - return newRxResult( cursor ); + private InternalRxResult newRxResult(PullResponseHandler pullHandler) { + RunResponseHandler runHandler = mock(RunResponseHandler.class); + RxResultCursor cursor = new RxResultCursorImpl(runHandler, pullHandler); + return newRxResult(cursor); } - private InternalRxResult newRxResult( RxResultCursor cursor ) - { - return new InternalRxResult( () -> - { - // now we successfully run - return completedFuture( cursor ); - } ); + private InternalRxResult newRxResult(RxResultCursor cursor) { + return new InternalRxResult(() -> { + // now we successfully run + return completedFuture(cursor); + }); } - private InternalRxResult newRxResult( Throwable error ) - { - return new InternalRxResult( () -> - { - // now we successfully run - return failedFuture( new CompletionException( error ) ); - } ); + private InternalRxResult newRxResult(Throwable error) { + return new InternalRxResult(() -> { + // now we successfully run + return failedFuture(new CompletionException(error)); + }); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxSessionTest.java b/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxSessionTest.java index 2ca1ea21fe..f3d752e21e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxSessionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxSessionTest.java @@ -18,13 +18,21 @@ */ package org.neo4j.driver.internal.reactive; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.TransactionConfig.empty; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; @@ -32,7 +40,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Query; import org.neo4j.driver.TransactionConfig; @@ -48,282 +58,255 @@ import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.reactive.RxTransaction; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.TransactionConfig.empty; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; - -class InternalRxSessionTest -{ - private static Stream> allSessionRunMethods() - { +class InternalRxSessionTest { + private static Stream> allSessionRunMethods() { return Stream.of( - rxSession -> rxSession.run( "RETURN 1" ), - rxSession -> rxSession.run( "RETURN $x", parameters( "x", 1 ) ), - rxSession -> rxSession.run( "RETURN $x", singletonMap( "x", 1 ) ), - rxSession -> rxSession.run( "RETURN $x", - new InternalRecord( singletonList( "x" ), new Value[]{new IntegerValue( 1 )} ) ), - rxSession -> rxSession.run( new Query( "RETURN $x", parameters( "x", 1 ) ) ), - rxSession -> rxSession.run( new Query( "RETURN $x", parameters( "x", 1 ) ), empty() ), - rxSession -> rxSession.run( "RETURN $x", singletonMap( "x", 1 ), empty() ), - rxSession -> rxSession.run( "RETURN 1", empty() ) - ); + rxSession -> rxSession.run("RETURN 1"), + rxSession -> rxSession.run("RETURN $x", parameters("x", 1)), + rxSession -> rxSession.run("RETURN $x", singletonMap("x", 1)), + rxSession -> rxSession.run( + "RETURN $x", new InternalRecord(singletonList("x"), new Value[] {new IntegerValue(1)})), + rxSession -> rxSession.run(new Query("RETURN $x", parameters("x", 1))), + rxSession -> rxSession.run(new Query("RETURN $x", parameters("x", 1)), empty()), + rxSession -> rxSession.run("RETURN $x", singletonMap("x", 1), empty()), + rxSession -> rxSession.run("RETURN 1", empty())); } - private static Stream>> allBeginTxMethods() - { + private static Stream>> allBeginTxMethods() { return Stream.of( rxSession -> rxSession.beginTransaction(), - rxSession -> rxSession.beginTransaction( TransactionConfig.empty() ) - ); + rxSession -> rxSession.beginTransaction(TransactionConfig.empty())); } - private static Stream>> allRunTxMethods() - { + private static Stream>> allRunTxMethods() { return Stream.of( - rxSession -> rxSession.readTransaction( tx -> Flux.just( "a" ) ), - rxSession -> rxSession.writeTransaction( tx -> Flux.just( "a" ) ), - rxSession -> rxSession.readTransaction( tx -> Flux.just( "a" ), empty() ), - rxSession -> rxSession.writeTransaction( tx -> Flux.just( "a" ), empty() ) - ); + rxSession -> rxSession.readTransaction(tx -> Flux.just("a")), + rxSession -> rxSession.writeTransaction(tx -> Flux.just("a")), + rxSession -> rxSession.readTransaction(tx -> Flux.just("a"), empty()), + rxSession -> rxSession.writeTransaction(tx -> Flux.just("a"), empty())); } @ParameterizedTest - @MethodSource( "allSessionRunMethods" ) - void shouldDelegateRun( Function runReturnOne ) throws Throwable - { + @MethodSource("allSessionRunMethods") + void shouldDelegateRun(Function runReturnOne) throws Throwable { // Given - NetworkSession session = mock( NetworkSession.class ); - RxResultCursor cursor = mock( RxResultCursorImpl.class ); + NetworkSession session = mock(NetworkSession.class); + RxResultCursor cursor = mock(RxResultCursorImpl.class); // Run succeeded with a cursor - when( session.runRx( any( Query.class ), any( TransactionConfig.class ) ) ).thenReturn( completedFuture( cursor ) ); - InternalRxSession rxSession = new InternalRxSession( session ); + when(session.runRx(any(Query.class), any(TransactionConfig.class))).thenReturn(completedFuture(cursor)); + InternalRxSession rxSession = new InternalRxSession(session); // When - RxResult result = runReturnOne.apply( rxSession ); + RxResult result = runReturnOne.apply(rxSession); // Execute the run - CompletionStage cursorFuture = ((InternalRxResult) result).cursorFutureSupplier().get(); + CompletionStage cursorFuture = + ((InternalRxResult) result).cursorFutureSupplier().get(); // Then - verify( session ).runRx( any( Query.class ), any( TransactionConfig.class ) ); - assertThat( Futures.getNow( cursorFuture ), equalTo( cursor ) ); + verify(session).runRx(any(Query.class), any(TransactionConfig.class)); + assertThat(Futures.getNow(cursorFuture), equalTo(cursor)); } @ParameterizedTest - @MethodSource( "allSessionRunMethods" ) - void shouldReleaseConnectionIfFailedToRun( Function runReturnOne ) throws Throwable - { + @MethodSource("allSessionRunMethods") + void shouldReleaseConnectionIfFailedToRun(Function runReturnOne) throws Throwable { // Given - Throwable error = new RuntimeException( "Hi there" ); - NetworkSession session = mock( NetworkSession.class ); + Throwable error = new RuntimeException("Hi there"); + NetworkSession session = mock(NetworkSession.class); // Run failed with error - when( session.runRx( any( Query.class ), any( TransactionConfig.class ) ) ).thenReturn( Futures.failedFuture( error ) ); - when( session.releaseConnectionAsync() ).thenReturn( Futures.completedWithNull() ); + when(session.runRx(any(Query.class), any(TransactionConfig.class))).thenReturn(Futures.failedFuture(error)); + when(session.releaseConnectionAsync()).thenReturn(Futures.completedWithNull()); - InternalRxSession rxSession = new InternalRxSession( session ); + InternalRxSession rxSession = new InternalRxSession(session); // When - RxResult result = runReturnOne.apply( rxSession ); + RxResult result = runReturnOne.apply(rxSession); // Execute the run - CompletionStage cursorFuture = ((InternalRxResult) result).cursorFutureSupplier().get(); + CompletionStage cursorFuture = + ((InternalRxResult) result).cursorFutureSupplier().get(); // Then - verify( session ).runRx( any( Query.class ), any( TransactionConfig.class ) ); - RuntimeException t = assertThrows( CompletionException.class, () -> Futures.getNow( cursorFuture ) ); - assertThat( t.getCause(), equalTo( error ) ); - verify( session ).releaseConnectionAsync(); + verify(session).runRx(any(Query.class), any(TransactionConfig.class)); + RuntimeException t = assertThrows(CompletionException.class, () -> Futures.getNow(cursorFuture)); + assertThat(t.getCause(), equalTo(error)); + verify(session).releaseConnectionAsync(); } @ParameterizedTest - @MethodSource( "allBeginTxMethods" ) - void shouldDelegateBeginTx( Function> beginTx ) throws Throwable - { + @MethodSource("allBeginTxMethods") + void shouldDelegateBeginTx(Function> beginTx) throws Throwable { // Given - NetworkSession session = mock( NetworkSession.class ); - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); + NetworkSession session = mock(NetworkSession.class); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); - when( session.beginTransactionAsync( any( TransactionConfig.class ) ) ).thenReturn( completedFuture( tx ) ); - InternalRxSession rxSession = new InternalRxSession( session ); + when(session.beginTransactionAsync(any(TransactionConfig.class))).thenReturn(completedFuture(tx)); + InternalRxSession rxSession = new InternalRxSession(session); // When - Publisher rxTx = beginTx.apply( rxSession ); - StepVerifier.create( Mono.from( rxTx ) ).expectNextCount( 1 ).verifyComplete(); + Publisher rxTx = beginTx.apply(rxSession); + StepVerifier.create(Mono.from(rxTx)).expectNextCount(1).verifyComplete(); // Then - verify( session ).beginTransactionAsync( any( TransactionConfig.class ) ); + verify(session).beginTransactionAsync(any(TransactionConfig.class)); } @ParameterizedTest - @MethodSource( "allBeginTxMethods" ) - void shouldReleaseConnectionIfFailedToBeginTx( Function> beginTx ) throws Throwable - { + @MethodSource("allBeginTxMethods") + void shouldReleaseConnectionIfFailedToBeginTx(Function> beginTx) + throws Throwable { // Given - Throwable error = new RuntimeException( "Hi there" ); - NetworkSession session = mock( NetworkSession.class ); + Throwable error = new RuntimeException("Hi there"); + NetworkSession session = mock(NetworkSession.class); // Run failed with error - when( session.beginTransactionAsync( any( TransactionConfig.class ) ) ).thenReturn( Futures.failedFuture( error ) ); - when( session.releaseConnectionAsync() ).thenReturn( Futures.completedWithNull() ); + when(session.beginTransactionAsync(any(TransactionConfig.class))).thenReturn(Futures.failedFuture(error)); + when(session.releaseConnectionAsync()).thenReturn(Futures.completedWithNull()); - InternalRxSession rxSession = new InternalRxSession( session ); + InternalRxSession rxSession = new InternalRxSession(session); // When - Publisher rxTx = beginTx.apply( rxSession ); - CompletableFuture txFuture = Mono.from( rxTx ).toFuture(); + Publisher rxTx = beginTx.apply(rxSession); + CompletableFuture txFuture = Mono.from(rxTx).toFuture(); // Then - verify( session ).beginTransactionAsync( any( TransactionConfig.class ) ); - RuntimeException t = assertThrows( CompletionException.class, () -> Futures.getNow( txFuture ) ); - assertThat( t.getCause(), equalTo( error ) ); - verify( session ).releaseConnectionAsync(); + verify(session).beginTransactionAsync(any(TransactionConfig.class)); + RuntimeException t = assertThrows(CompletionException.class, () -> Futures.getNow(txFuture)); + assertThat(t.getCause(), equalTo(error)); + verify(session).releaseConnectionAsync(); } @ParameterizedTest - @MethodSource( "allRunTxMethods" ) - void shouldDelegateRunTx( Function> runTx ) throws Throwable - { + @MethodSource("allRunTxMethods") + void shouldDelegateRunTx(Function> runTx) throws Throwable { // Given - NetworkSession session = mock( NetworkSession.class ); - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.closeAsync( true ) ).thenReturn( completedWithNull() ); + NetworkSession session = mock(NetworkSession.class); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.closeAsync(true)).thenReturn(completedWithNull()); - when( session.beginTransactionAsync( any( AccessMode.class ), any( TransactionConfig.class ) ) ).thenReturn( completedFuture( tx ) ); - when( session.retryLogic() ).thenReturn( new FixedRetryLogic( 1 ) ); - InternalRxSession rxSession = new InternalRxSession( session ); + when(session.beginTransactionAsync(any(AccessMode.class), any(TransactionConfig.class))) + .thenReturn(completedFuture(tx)); + when(session.retryLogic()).thenReturn(new FixedRetryLogic(1)); + InternalRxSession rxSession = new InternalRxSession(session); // When - Publisher strings = runTx.apply( rxSession ); - StepVerifier.create( Flux.from( strings ) ).expectNext( "a" ).verifyComplete(); + Publisher strings = runTx.apply(rxSession); + StepVerifier.create(Flux.from(strings)).expectNext("a").verifyComplete(); // Then - verify( session ).beginTransactionAsync( any( AccessMode.class ), any( TransactionConfig.class ) ); - verify( tx ).closeAsync( true ); + verify(session).beginTransactionAsync(any(AccessMode.class), any(TransactionConfig.class)); + verify(tx).closeAsync(true); } @Test - void shouldRetryOnError() throws Throwable - { + void shouldRetryOnError() throws Throwable { // Given int retryCount = 2; - NetworkSession session = mock( NetworkSession.class ); - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.closeAsync( false ) ).thenReturn( completedWithNull() ); + NetworkSession session = mock(NetworkSession.class); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.closeAsync(false)).thenReturn(completedWithNull()); - when( session.beginTransactionAsync( any( AccessMode.class ), any( TransactionConfig.class ) ) ).thenReturn( completedFuture( tx ) ); - when( session.retryLogic() ).thenReturn( new FixedRetryLogic( retryCount ) ); - InternalRxSession rxSession = new InternalRxSession( session ); + when(session.beginTransactionAsync(any(AccessMode.class), any(TransactionConfig.class))) + .thenReturn(completedFuture(tx)); + when(session.retryLogic()).thenReturn(new FixedRetryLogic(retryCount)); + InternalRxSession rxSession = new InternalRxSession(session); // When - Publisher strings = rxSession.readTransaction( - t -> - Flux.just( "a" ).then( Mono.error( new RuntimeException( "Errored" ) ) ) ); - StepVerifier.create( Flux.from( strings ) ) - // we lost the "a"s too as the user only see the last failure - .expectError( RuntimeException.class ) - .verify(); + Publisher strings = + rxSession.readTransaction(t -> Flux.just("a").then(Mono.error(new RuntimeException("Errored")))); + StepVerifier.create(Flux.from(strings)) + // we lost the "a"s too as the user only see the last failure + .expectError(RuntimeException.class) + .verify(); // Then - verify( session, times( retryCount + 1 ) ).beginTransactionAsync( any( AccessMode.class ), any( TransactionConfig.class ) ); - verify( tx, times( retryCount + 1 ) ).closeAsync( false ); + verify(session, times(retryCount + 1)) + .beginTransactionAsync(any(AccessMode.class), any(TransactionConfig.class)); + verify(tx, times(retryCount + 1)).closeAsync(false); } @Test - void shouldObtainResultIfRetrySucceed() throws Throwable - { + void shouldObtainResultIfRetrySucceed() throws Throwable { // Given int retryCount = 2; - NetworkSession session = mock( NetworkSession.class ); - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.closeAsync( false ) ).thenReturn( completedWithNull() ); - when( tx.closeAsync( true ) ).thenReturn( completedWithNull() ); + NetworkSession session = mock(NetworkSession.class); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.closeAsync(false)).thenReturn(completedWithNull()); + when(tx.closeAsync(true)).thenReturn(completedWithNull()); - when( session.beginTransactionAsync( any( AccessMode.class ), any( TransactionConfig.class ) ) ).thenReturn( completedFuture( tx ) ); - when( session.retryLogic() ).thenReturn( new FixedRetryLogic( retryCount ) ); - InternalRxSession rxSession = new InternalRxSession( session ); + when(session.beginTransactionAsync(any(AccessMode.class), any(TransactionConfig.class))) + .thenReturn(completedFuture(tx)); + when(session.retryLogic()).thenReturn(new FixedRetryLogic(retryCount)); + InternalRxSession rxSession = new InternalRxSession(session); // When AtomicInteger count = new AtomicInteger(); - Publisher strings = rxSession.readTransaction( - t -> - { - // we fail for the first few retries, and then success on the last run. - if ( count.getAndIncrement() == retryCount ) - { - return Flux.just( "a" ); - } - else - { - return Flux.just( "a" ).then( Mono.error( new RuntimeException( "Errored" ) ) ); - } - } ); - StepVerifier.create( Flux.from( strings ) ).expectNext( "a" ).verifyComplete(); + Publisher strings = rxSession.readTransaction(t -> { + // we fail for the first few retries, and then success on the last run. + if (count.getAndIncrement() == retryCount) { + return Flux.just("a"); + } else { + return Flux.just("a").then(Mono.error(new RuntimeException("Errored"))); + } + }); + StepVerifier.create(Flux.from(strings)).expectNext("a").verifyComplete(); // Then - verify( session, times( retryCount + 1 ) ).beginTransactionAsync( any( AccessMode.class ), any( TransactionConfig.class ) ); - verify( tx, times( retryCount ) ).closeAsync( false ); - verify( tx ).closeAsync( true ); + verify(session, times(retryCount + 1)) + .beginTransactionAsync(any(AccessMode.class), any(TransactionConfig.class)); + verify(tx, times(retryCount)).closeAsync(false); + verify(tx).closeAsync(true); } @Test - void shouldDelegateBookmark() throws Throwable - { + void shouldDelegateBookmark() throws Throwable { // Given - NetworkSession session = mock( NetworkSession.class ); - InternalRxSession rxSession = new InternalRxSession( session ); + NetworkSession session = mock(NetworkSession.class); + InternalRxSession rxSession = new InternalRxSession(session); // When rxSession.lastBookmark(); // Then - verify( session ).lastBookmark(); - verifyNoMoreInteractions( session ); + verify(session).lastBookmark(); + verifyNoMoreInteractions(session); } @Test - void shouldDelegateReset() throws Throwable - { + void shouldDelegateReset() throws Throwable { // Given - NetworkSession session = mock( NetworkSession.class ); - when( session.resetAsync() ).thenReturn( completedWithNull() ); - InternalRxSession rxSession = new InternalRxSession( session ); + NetworkSession session = mock(NetworkSession.class); + when(session.resetAsync()).thenReturn(completedWithNull()); + InternalRxSession rxSession = new InternalRxSession(session); // When Publisher mono = rxSession.reset(); // Then - StepVerifier.create( mono ).verifyComplete(); - verify( session ).resetAsync(); - verifyNoMoreInteractions( session ); + StepVerifier.create(mono).verifyComplete(); + verify(session).resetAsync(); + verifyNoMoreInteractions(session); } @Test - void shouldDelegateClose() throws Throwable - { + void shouldDelegateClose() throws Throwable { // Given - NetworkSession session = mock( NetworkSession.class ); - when( session.closeAsync() ).thenReturn( completedWithNull() ); - InternalRxSession rxSession = new InternalRxSession( session ); + NetworkSession session = mock(NetworkSession.class); + when(session.closeAsync()).thenReturn(completedWithNull()); + InternalRxSession rxSession = new InternalRxSession(session); // When Publisher mono = rxSession.close(); // Then - StepVerifier.create( mono ).verifyComplete(); - verify( session ).closeAsync(); - verifyNoMoreInteractions( session ); + StepVerifier.create(mono).verifyComplete(); + verify(session).closeAsync(); + verifyNoMoreInteractions(session); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxTransactionTest.java b/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxTransactionTest.java index 5a9f0bb4b6..6fc7cf169c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxTransactionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/reactive/InternalRxTransactionTest.java @@ -18,17 +18,25 @@ */ package org.neo4j.driver.internal.reactive; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.reactivestreams.Publisher; -import reactor.test.StepVerifier; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.Values.parameters; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; import java.util.function.Function; import java.util.stream.Stream; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.neo4j.driver.Query; import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalRecord; @@ -39,128 +47,111 @@ import org.neo4j.driver.internal.value.IntegerValue; import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxTransaction; +import org.reactivestreams.Publisher; +import reactor.test.StepVerifier; -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.neo4j.driver.Values.parameters; - -class InternalRxTransactionTest -{ +class InternalRxTransactionTest { @Test - void commitShouldDelegate() - { - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.commitAsync() ).thenReturn( Futures.completedWithNull() ); + void commitShouldDelegate() { + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.commitAsync()).thenReturn(Futures.completedWithNull()); - InternalRxTransaction rxTx = new InternalRxTransaction( tx ); + InternalRxTransaction rxTx = new InternalRxTransaction(tx); Publisher publisher = rxTx.commit(); - StepVerifier.create( publisher ).verifyComplete(); + StepVerifier.create(publisher).verifyComplete(); - verify( tx ).commitAsync(); + verify(tx).commitAsync(); } @Test - void rollbackShouldDelegate() - { - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.rollbackAsync() ).thenReturn( Futures.completedWithNull() ); + void rollbackShouldDelegate() { + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.rollbackAsync()).thenReturn(Futures.completedWithNull()); - InternalRxTransaction rxTx = new InternalRxTransaction( tx ); + InternalRxTransaction rxTx = new InternalRxTransaction(tx); Publisher publisher = rxTx.rollback(); - StepVerifier.create( publisher ).verifyComplete(); + StepVerifier.create(publisher).verifyComplete(); - verify( tx ).rollbackAsync(); + verify(tx).rollbackAsync(); } - private static Stream> allTxRunMethods() - { + private static Stream> allTxRunMethods() { return Stream.of( - rxSession -> rxSession.run( "RETURN 1" ), - rxSession -> rxSession.run( "RETURN $x", parameters( "x", 1 ) ), - rxSession -> rxSession.run( "RETURN $x", singletonMap( "x", 1 ) ), - rxSession -> rxSession.run( "RETURN $x", - new InternalRecord( singletonList( "x" ), new Value[]{new IntegerValue( 1 )} ) ), - rxSession -> rxSession.run( new Query( "RETURN $x", parameters( "x", 1 ) ) ) - ); + rxSession -> rxSession.run("RETURN 1"), + rxSession -> rxSession.run("RETURN $x", parameters("x", 1)), + rxSession -> rxSession.run("RETURN $x", singletonMap("x", 1)), + rxSession -> rxSession.run( + "RETURN $x", new InternalRecord(singletonList("x"), new Value[] {new IntegerValue(1)})), + rxSession -> rxSession.run(new Query("RETURN $x", parameters("x", 1)))); } @ParameterizedTest - @MethodSource( "allTxRunMethods" ) - void shouldDelegateRun( Function runReturnOne ) throws Throwable - { + @MethodSource("allTxRunMethods") + void shouldDelegateRun(Function runReturnOne) throws Throwable { // Given - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - RxResultCursor cursor = mock( RxResultCursorImpl.class ); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + RxResultCursor cursor = mock(RxResultCursorImpl.class); // Run succeeded with a cursor - when( tx.runRx( any( Query.class ) ) ).thenReturn( completedFuture( cursor ) ); - InternalRxTransaction rxTx = new InternalRxTransaction( tx ); + when(tx.runRx(any(Query.class))).thenReturn(completedFuture(cursor)); + InternalRxTransaction rxTx = new InternalRxTransaction(tx); // When - RxResult result = runReturnOne.apply( rxTx ); + RxResult result = runReturnOne.apply(rxTx); // Execute the run - CompletionStage cursorFuture = ((InternalRxResult) result).cursorFutureSupplier().get(); + CompletionStage cursorFuture = + ((InternalRxResult) result).cursorFutureSupplier().get(); // Then - verify( tx ).runRx( any( Query.class ) ); - assertThat( Futures.getNow( cursorFuture ), equalTo( cursor ) ); + verify(tx).runRx(any(Query.class)); + assertThat(Futures.getNow(cursorFuture), equalTo(cursor)); } @ParameterizedTest - @MethodSource( "allTxRunMethods" ) - void shouldMarkTxIfFailedToRun( Function runReturnOne ) throws Throwable - { + @MethodSource("allTxRunMethods") + void shouldMarkTxIfFailedToRun(Function runReturnOne) throws Throwable { // Given - Throwable error = new RuntimeException( "Hi there" ); - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); + Throwable error = new RuntimeException("Hi there"); + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); // Run failed with error - when( tx.runRx( any( Query.class ) ) ).thenReturn( Futures.failedFuture( error ) ); - InternalRxTransaction rxTx = new InternalRxTransaction( tx ); + when(tx.runRx(any(Query.class))).thenReturn(Futures.failedFuture(error)); + InternalRxTransaction rxTx = new InternalRxTransaction(tx); // When - RxResult result = runReturnOne.apply( rxTx ); + RxResult result = runReturnOne.apply(rxTx); // Execute the run - CompletionStage cursorFuture = ((InternalRxResult) result).cursorFutureSupplier().get(); + CompletionStage cursorFuture = + ((InternalRxResult) result).cursorFutureSupplier().get(); // Then - verify( tx ).runRx( any( Query.class ) ); - RuntimeException t = assertThrows( CompletionException.class, () -> Futures.getNow( cursorFuture ) ); - assertThat( t.getCause(), equalTo( error ) ); - verify( tx ).markTerminated( error ); + verify(tx).runRx(any(Query.class)); + RuntimeException t = assertThrows(CompletionException.class, () -> Futures.getNow(cursorFuture)); + assertThat(t.getCause(), equalTo(error)); + verify(tx).markTerminated(error); } @Test - void shouldDelegateConditionalClose() - { - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.closeAsync( true ) ).thenReturn( Futures.completedWithNull() ); + void shouldDelegateConditionalClose() { + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.closeAsync(true)).thenReturn(Futures.completedWithNull()); - InternalRxTransaction rxTx = new InternalRxTransaction( tx ); - Publisher publisher = rxTx.close( true ); - StepVerifier.create( publisher ).verifyComplete(); + InternalRxTransaction rxTx = new InternalRxTransaction(tx); + Publisher publisher = rxTx.close(true); + StepVerifier.create(publisher).verifyComplete(); - verify( tx ).closeAsync( true ); + verify(tx).closeAsync(true); } @Test - void shouldDelegateClose() - { - UnmanagedTransaction tx = mock( UnmanagedTransaction.class ); - when( tx.closeAsync( false ) ).thenReturn( Futures.completedWithNull() ); + void shouldDelegateClose() { + UnmanagedTransaction tx = mock(UnmanagedTransaction.class); + when(tx.closeAsync(false)).thenReturn(Futures.completedWithNull()); - InternalRxTransaction rxTx = new InternalRxTransaction( tx ); + InternalRxTransaction rxTx = new InternalRxTransaction(tx); Publisher publisher = rxTx.close(); - StepVerifier.create( publisher ).verifyComplete(); + StepVerifier.create(publisher).verifyComplete(); - verify( tx ).closeAsync( false ); + verify(tx).closeAsync(false); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/reactive/RxUtilsTest.java b/driver/src/test/java/org/neo4j/driver/internal/reactive/RxUtilsTest.java index 7adc1b7f2a..b0bf9ceae8 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/reactive/RxUtilsTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/reactive/RxUtilsTest.java @@ -18,60 +18,53 @@ */ package org.neo4j.driver.internal.reactive; -import org.junit.jupiter.api.Test; -import org.reactivestreams.Publisher; -import reactor.test.StepVerifier; - -import java.util.concurrent.CompletableFuture; -import java.util.function.Predicate; - -import org.neo4j.driver.internal.util.Futures; - import static org.mockito.Mockito.mock; import static org.neo4j.driver.internal.reactive.RxUtils.createEmptyPublisher; import static org.neo4j.driver.internal.reactive.RxUtils.createSingleItemPublisher; import static org.neo4j.driver.internal.util.Futures.failedFuture; -class RxUtilsTest -{ +import java.util.concurrent.CompletableFuture; +import java.util.function.Predicate; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.util.Futures; +import org.reactivestreams.Publisher; +import reactor.test.StepVerifier; + +class RxUtilsTest { @Test - void emptyPublisherShouldComplete() - { - Publisher emptyPublisher = createEmptyPublisher( Futures::completedWithNull ); - StepVerifier.create( emptyPublisher ).verifyComplete(); + void emptyPublisherShouldComplete() { + Publisher emptyPublisher = createEmptyPublisher(Futures::completedWithNull); + StepVerifier.create(emptyPublisher).verifyComplete(); } @Test - void emptyPublisherShouldErrorWhenSupplierErrors() - { - RuntimeException error = new RuntimeException( "Error" ); - Publisher emptyPublisher = createEmptyPublisher( () -> failedFuture( error ) ); + void emptyPublisherShouldErrorWhenSupplierErrors() { + RuntimeException error = new RuntimeException("Error"); + Publisher emptyPublisher = createEmptyPublisher(() -> failedFuture(error)); - StepVerifier.create( emptyPublisher ).verifyErrorMatches( Predicate.isEqual( error ) ); + StepVerifier.create(emptyPublisher).verifyErrorMatches(Predicate.isEqual(error)); } @Test - void singleItemPublisherShouldCompleteWithValue() - { - Publisher publisher = createSingleItemPublisher( () -> CompletableFuture.completedFuture( "One" ), () -> mock( Throwable.class ) ); - StepVerifier.create( publisher ).expectNext( "One" ).verifyComplete(); + void singleItemPublisherShouldCompleteWithValue() { + Publisher publisher = + createSingleItemPublisher(() -> CompletableFuture.completedFuture("One"), () -> mock(Throwable.class)); + StepVerifier.create(publisher).expectNext("One").verifyComplete(); } @Test - void singleItemPublisherShouldErrorWhenFutureCompletesWithNull() - { - Throwable error = mock( Throwable.class ); - Publisher publisher = createSingleItemPublisher( Futures::completedWithNull, () -> error ); + void singleItemPublisherShouldErrorWhenFutureCompletesWithNull() { + Throwable error = mock(Throwable.class); + Publisher publisher = createSingleItemPublisher(Futures::completedWithNull, () -> error); - StepVerifier.create( publisher ).verifyErrorMatches( actualError -> error == actualError ); + StepVerifier.create(publisher).verifyErrorMatches(actualError -> error == actualError); } @Test - void singleItemPublisherShouldErrorWhenSupplierErrors() - { - RuntimeException error = mock( RuntimeException.class ); - Publisher publisher = createSingleItemPublisher( () -> failedFuture( error ), () -> mock( Throwable.class ) ); + void singleItemPublisherShouldErrorWhenSupplierErrors() { + RuntimeException error = mock(RuntimeException.class); + Publisher publisher = createSingleItemPublisher(() -> failedFuture(error), () -> mock(Throwable.class)); - StepVerifier.create( publisher ).verifyErrorMatches( actualError -> error == actualError ); + StepVerifier.create(publisher).verifyErrorMatches(actualError -> error == actualError); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/reactive/util/ListBasedPullHandler.java b/driver/src/test/java/org/neo4j/driver/internal/reactive/util/ListBasedPullHandler.java index b41d33e411..f2acd0f7f9 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/reactive/util/ListBasedPullHandler.java +++ b/driver/src/test/java/org/neo4j/driver/internal/reactive/util/ListBasedPullHandler.java @@ -18,9 +18,16 @@ */ package org.neo4j.driver.internal.reactive.util; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import java.util.List; import java.util.Map; - import org.neo4j.driver.Query; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -33,85 +40,65 @@ import org.neo4j.driver.internal.value.BooleanValue; import org.neo4j.driver.summary.ResultSummary; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ListBasedPullHandler extends BasicPullResponseHandler -{ +public class ListBasedPullHandler extends BasicPullResponseHandler { private final List list; private final Throwable error; private int index = 0; - public ListBasedPullHandler() - { - this( emptyList(), null ); + public ListBasedPullHandler() { + this(emptyList(), null); } - public ListBasedPullHandler( List list ) - { - this( list, null ); + public ListBasedPullHandler(List list) { + this(list, null); } - public ListBasedPullHandler( Throwable error ) - { - this( emptyList(), error ); + public ListBasedPullHandler(Throwable error) { + this(emptyList(), error); } - private ListBasedPullHandler( List list, Throwable error ) - { - super( mock( Query.class ), mock( RunResponseHandler.class ), mock( Connection.class ), mock( MetadataExtractor.class ), mock( - PullResponseCompletionListener.class ) ); + private ListBasedPullHandler(List list, Throwable error) { + super( + mock(Query.class), + mock(RunResponseHandler.class), + mock(Connection.class), + mock(MetadataExtractor.class), + mock(PullResponseCompletionListener.class)); this.list = list; this.error = error; - when( super.metadataExtractor.extractSummary( any( Query.class ), any( Connection.class ), anyLong(), any( Map.class ) ) ).thenReturn( - mock( ResultSummary.class ) ); - if ( list.size() > 1 ) - { - Record record = list.get( 0 ); - when( super.runResponseHandler.queryKeys() ).thenReturn( new QueryKeys( record.keys() ) ); + when(super.metadataExtractor.extractSummary(any(Query.class), any(Connection.class), anyLong(), any(Map.class))) + .thenReturn(mock(ResultSummary.class)); + if (list.size() > 1) { + Record record = list.get(0); + when(super.runResponseHandler.queryKeys()).thenReturn(new QueryKeys(record.keys())); } } @Override - public void request( long n ) - { - super.request( n ); - while ( index < list.size() && (n == -1 || n-- > 0) ) - { - onRecord( list.get( index++ ).values().toArray( new Value[0] ) ); + public void request(long n) { + super.request(n); + while (index < list.size() && (n == -1 || n-- > 0)) { + onRecord(list.get(index++).values().toArray(new Value[0])); } - if ( index == list.size() ) - { + if (index == list.size()) { complete(); - } - else - { - onSuccess( singletonMap( "has_more", BooleanValue.TRUE ) ); + } else { + onSuccess(singletonMap("has_more", BooleanValue.TRUE)); } } @Override - public void cancel() - { + public void cancel() { super.cancel(); complete(); } - private void complete() - { - if ( error != null ) - { - onFailure( error ); - } - else - { - onSuccess( emptyMap() ); + private void complete() { + if (error != null) { + onFailure(error); + } else { + onSuccess(emptyMap()); } } } 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 0a2acb57b3..f826358993 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 @@ -18,40 +18,6 @@ */ package org.neo4j.driver.internal.retry; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.ArgumentCaptor; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.publisher.MonoSink; -import reactor.test.StepVerifier; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import org.neo4j.driver.Logger; -import org.neo4j.driver.Logging; -import org.neo4j.driver.exceptions.AuthorizationExpiredException; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; -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 static java.lang.Long.MAX_VALUE; import static java.util.concurrent.CompletableFuture.completedFuture; import static org.hamcrest.Matchers.allOf; @@ -81,559 +47,566 @@ import static org.neo4j.driver.internal.util.Futures.failedFuture; import static org.neo4j.driver.util.TestUtil.await; -class ExponentialBackoffRetryLogicTest -{ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.ArgumentCaptor; +import org.neo4j.driver.Logger; +import org.neo4j.driver.Logging; +import org.neo4j.driver.exceptions.AuthorizationExpiredException; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.exceptions.ConnectionReadTimeoutException; +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; +import reactor.core.publisher.Mono; +import reactor.core.publisher.MonoSink; +import reactor.test.StepVerifier; + +class ExponentialBackoffRetryLogicTest { private final ImmediateSchedulingEventExecutor eventExecutor = new ImmediateSchedulingEventExecutor(); @Test - void throwsForIllegalMaxRetryTime() - { - IllegalArgumentException error = assertThrows( IllegalArgumentException.class, () -> newRetryLogic( -100, 1, 1, 1, Clock.SYSTEM ) ); - assertThat( error.getMessage(), containsString( "Max retry time" ) ); + void throwsForIllegalMaxRetryTime() { + IllegalArgumentException error = + assertThrows(IllegalArgumentException.class, () -> newRetryLogic(-100, 1, 1, 1, Clock.SYSTEM)); + assertThat(error.getMessage(), containsString("Max retry time")); } @Test - void throwsForIllegalInitialRetryDelay() - { - IllegalArgumentException error = assertThrows( IllegalArgumentException.class, () -> newRetryLogic( 1, -100, 1, 1, Clock.SYSTEM ) ); - assertThat( error.getMessage(), containsString( "Initial retry delay" ) ); + void throwsForIllegalInitialRetryDelay() { + IllegalArgumentException error = + assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, -100, 1, 1, Clock.SYSTEM)); + assertThat(error.getMessage(), containsString("Initial retry delay")); } @Test - void throwsForIllegalMultiplier() - { - IllegalArgumentException error = assertThrows( IllegalArgumentException.class, () -> newRetryLogic( 1, 1, 0.42, 1, Clock.SYSTEM ) ); - assertThat( error.getMessage(), containsString( "Multiplier" ) ); + void throwsForIllegalMultiplier() { + IllegalArgumentException error = + assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 0.42, 1, Clock.SYSTEM)); + assertThat(error.getMessage(), containsString("Multiplier")); } @Test - void throwsForIllegalJitterFactor() - { - IllegalArgumentException error1 = assertThrows( IllegalArgumentException.class, () -> newRetryLogic( 1, 1, 1, -0.42, Clock.SYSTEM ) ); - assertThat( error1.getMessage(), containsString( "Jitter" ) ); + void throwsForIllegalJitterFactor() { + IllegalArgumentException error1 = + assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 1, -0.42, Clock.SYSTEM)); + assertThat(error1.getMessage(), containsString("Jitter")); - IllegalArgumentException error2 = assertThrows( IllegalArgumentException.class, () -> newRetryLogic( 1, 1, 1, 1.42, Clock.SYSTEM ) ); - assertThat( error2.getMessage(), containsString( "Jitter" ) ); + IllegalArgumentException error2 = + assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 1, 1.42, Clock.SYSTEM)); + assertThat(error2.getMessage(), containsString("Jitter")); } @Test - void throwsForIllegalClock() - { - IllegalArgumentException error = assertThrows( IllegalArgumentException.class, () -> newRetryLogic( 1, 1, 1, 1, null ) ); - assertThat( error.getMessage(), containsString( "Clock" ) ); + void throwsForIllegalClock() { + IllegalArgumentException error = + assertThrows(IllegalArgumentException.class, () -> newRetryLogic(1, 1, 1, 1, null)); + assertThat(error.getMessage(), containsString("Clock")); } @Test - void nextDelayCalculatedAccordingToMultiplier() throws Exception - { + void nextDelayCalculatedAccordingToMultiplier() throws Exception { int retries = 27; int initialDelay = 1; int multiplier = 3; int noJitter = 0; - Clock clock = mock( Clock.class ); - ExponentialBackoffRetryLogic logic = newRetryLogic( MAX_VALUE, initialDelay, multiplier, noJitter, clock ); + Clock clock = mock(Clock.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, clock); - retry( logic, retries ); + retry(logic, retries); - assertEquals( delaysWithoutJitter( initialDelay, multiplier, retries ), sleepValues( clock, retries ) ); + assertEquals(delaysWithoutJitter(initialDelay, multiplier, retries), sleepValues(clock, retries)); } @Test - void nextDelayCalculatedAccordingToMultiplierAsync() - { + void nextDelayCalculatedAccordingToMultiplierAsync() { String result = "The Result"; int retries = 14; int initialDelay = 1; int multiplier = 2; int noJitter = 0; - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( MAX_VALUE, initialDelay, multiplier, noJitter, - Clock.SYSTEM ); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, Clock.SYSTEM); - CompletionStage future = retryAsync( retryLogic, retries, result ); + CompletionStage future = retryAsync(retryLogic, retries, result); - assertEquals( result, await( future ) ); - assertEquals( delaysWithoutJitter( initialDelay, multiplier, retries ), eventExecutor.scheduleDelays() ); + assertEquals(result, await(future)); + assertEquals(delaysWithoutJitter(initialDelay, multiplier, retries), eventExecutor.scheduleDelays()); } @Test - void nextDelayCalculatedAccordingToMultiplierRx() - { + void nextDelayCalculatedAccordingToMultiplierRx() { String result = "The Result"; int retries = 14; int initialDelay = 1; int multiplier = 2; int noJitter = 0; - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( MAX_VALUE, initialDelay, multiplier, noJitter, - Clock.SYSTEM ); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(MAX_VALUE, initialDelay, multiplier, noJitter, Clock.SYSTEM); - Mono single = Flux.from( retryRx( retryLogic, retries, result ) ).single(); + Mono single = Flux.from(retryRx(retryLogic, retries, result)).single(); - assertEquals( result, await( single ) ); - assertEquals( delaysWithoutJitter( initialDelay, multiplier, retries ), eventExecutor.scheduleDelays() ); + assertEquals(result, await(single)); + assertEquals(delaysWithoutJitter(initialDelay, multiplier, retries), eventExecutor.scheduleDelays()); } @Test - void nextDelayCalculatedAccordingToJitter() throws Exception - { + void nextDelayCalculatedAccordingToJitter() throws Exception { int retries = 32; double jitterFactor = 0.2; int initialDelay = 1; int multiplier = 2; - Clock clock = mock( Clock.class ); + Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic logic = newRetryLogic( MAX_VALUE, initialDelay, multiplier, jitterFactor, clock ); + ExponentialBackoffRetryLogic logic = newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, clock); - retry( logic, retries ); + retry(logic, retries); - List sleepValues = sleepValues( clock, retries ); - List delaysWithoutJitter = delaysWithoutJitter( initialDelay, multiplier, retries ); + List sleepValues = sleepValues(clock, retries); + List delaysWithoutJitter = delaysWithoutJitter(initialDelay, multiplier, retries); - assertDelaysApproximatelyEqual( delaysWithoutJitter, sleepValues, jitterFactor ); + assertDelaysApproximatelyEqual(delaysWithoutJitter, sleepValues, jitterFactor); } @Test - void nextDelayCalculatedAccordingToJitterAsync() - { + void nextDelayCalculatedAccordingToJitterAsync() { String result = "The Result"; int retries = 24; double jitterFactor = 0.2; int initialDelay = 1; int multiplier = 2; - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( MAX_VALUE, initialDelay, multiplier, jitterFactor, - mock( Clock.class ) ); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, mock(Clock.class)); - CompletionStage future = retryAsync( retryLogic, retries, result ); - assertEquals( result, await( future ) ); + CompletionStage future = retryAsync(retryLogic, retries, result); + assertEquals(result, await(future)); List scheduleDelays = eventExecutor.scheduleDelays(); - List delaysWithoutJitter = delaysWithoutJitter( initialDelay, multiplier, retries ); + List delaysWithoutJitter = delaysWithoutJitter(initialDelay, multiplier, retries); - assertDelaysApproximatelyEqual( delaysWithoutJitter, scheduleDelays, jitterFactor ); + assertDelaysApproximatelyEqual(delaysWithoutJitter, scheduleDelays, jitterFactor); } @Test - void nextDelayCalculatedAccordingToJitterRx() - { + void nextDelayCalculatedAccordingToJitterRx() { String result = "The Result"; int retries = 24; double jitterFactor = 0.2; int initialDelay = 1; int multiplier = 2; - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( MAX_VALUE, initialDelay, multiplier, jitterFactor, - mock( Clock.class ) ); + ExponentialBackoffRetryLogic retryLogic = + newRetryLogic(MAX_VALUE, initialDelay, multiplier, jitterFactor, mock(Clock.class)); - Mono single = Flux.from( retryRx( retryLogic, retries, result ) ).single(); - assertEquals( result, await( single ) ); + Mono single = Flux.from(retryRx(retryLogic, retries, result)).single(); + assertEquals(result, await(single)); List scheduleDelays = eventExecutor.scheduleDelays(); - List delaysWithoutJitter = delaysWithoutJitter( initialDelay, multiplier, retries ); + List delaysWithoutJitter = delaysWithoutJitter(initialDelay, multiplier, retries); - assertDelaysApproximatelyEqual( delaysWithoutJitter, scheduleDelays, jitterFactor ); + assertDelaysApproximatelyEqual(delaysWithoutJitter, scheduleDelays, jitterFactor); } @Test - void doesNotRetryWhenMaxRetryTimeExceeded() throws Exception - { + void doesNotRetryWhenMaxRetryTimeExceeded() throws Exception { long retryStart = Clock.SYSTEM.millis(); int initialDelay = 100; int multiplier = 2; long maxRetryTimeMs = 45; - Clock clock = mock( Clock.class ); - when( clock.millis() ).thenReturn( retryStart ) - .thenReturn( retryStart + maxRetryTimeMs - 5 ) - .thenReturn( retryStart + maxRetryTimeMs + 7 ); + Clock clock = mock(Clock.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); Supplier workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); - when( workMock.get() ).thenThrow( error ); + when(workMock.get()).thenThrow(error); - Exception e = assertThrows( Exception.class, () -> logic.retry( workMock ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> logic.retry(workMock)); + assertEquals(error, e); - verify( clock ).sleep( initialDelay ); - verify( clock ).sleep( initialDelay * multiplier ); - verify( workMock, times( 3 ) ).get(); + verify(clock).sleep(initialDelay); + verify(clock).sleep(initialDelay * multiplier); + verify(workMock, times(3)).get(); } @Test - void doesNotRetryWhenMaxRetryTimeExceededAsync() - { + void doesNotRetryWhenMaxRetryTimeExceededAsync() { long retryStart = Clock.SYSTEM.millis(); int initialDelay = 100; int multiplier = 2; long maxRetryTimeMs = 45; - Clock clock = mock( Clock.class ); - when( clock.millis() ).thenReturn( retryStart ) - .thenReturn( retryStart + maxRetryTimeMs - 5 ) - .thenReturn( retryStart + maxRetryTimeMs + 7 ); + Clock clock = mock(Clock.class); + when(clock.millis()) + .thenReturn(retryStart) + .thenReturn(retryStart + maxRetryTimeMs - 5) + .thenReturn(retryStart + maxRetryTimeMs + 7); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( maxRetryTimeMs, initialDelay, multiplier, 0, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(maxRetryTimeMs, initialDelay, multiplier, 0, clock); Supplier> workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); - when( workMock.get() ).thenReturn( failedFuture( error ) ); + when(workMock.get()).thenReturn(failedFuture(error)); - CompletionStage future = retryLogic.retryAsync( workMock ); + CompletionStage future = retryLogic.retryAsync(workMock); - Exception e = assertThrows( Exception.class, () -> await( future ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> await(future)); + assertEquals(error, e); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 2, scheduleDelays.size() ); - assertEquals( initialDelay, scheduleDelays.get( 0 ).intValue() ); - assertEquals( initialDelay * multiplier, scheduleDelays.get( 1 ).intValue() ); + assertEquals(2, scheduleDelays.size()); + assertEquals(initialDelay, scheduleDelays.get(0).intValue()); + assertEquals(initialDelay * multiplier, scheduleDelays.get(1).intValue()); - verify( workMock, times( 3 ) ).get(); + verify(workMock, times(3)).get(); } @Test - void doesNotRetryWhenMaxRetryTimeExceededRx() - { + void doesNotRetryWhenMaxRetryTimeExceededRx() { long retryStart = Clock.SYSTEM.millis(); int initialDelay = 100; int multiplier = 2; long maxRetryTimeMs = 45; - Clock clock = mock( Clock.class ); - when( clock.millis() ).thenReturn( retryStart ) - .thenReturn( retryStart + maxRetryTimeMs - 5 ) - .thenReturn( retryStart + maxRetryTimeMs + 7 ); + Clock clock = mock(Clock.class); + when(clock.millis()) + .thenReturn(retryStart) + .thenReturn(retryStart + maxRetryTimeMs - 5) + .thenReturn(retryStart + maxRetryTimeMs + 7); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( maxRetryTimeMs, initialDelay, multiplier, 0, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(maxRetryTimeMs, initialDelay, multiplier, 0, clock); SessionExpiredException error = sessionExpired(); AtomicInteger executionCount = new AtomicInteger(); - Publisher publisher = retryLogic.retryRx( Mono.error( error ).doOnTerminate( executionCount::getAndIncrement ) ); + Publisher publisher = + retryLogic.retryRx(Mono.error(error).doOnTerminate(executionCount::getAndIncrement)); - Exception e = assertThrows( Exception.class, () -> await( publisher ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> await(publisher)); + assertEquals(error, e); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 2, scheduleDelays.size() ); - assertEquals( initialDelay, scheduleDelays.get( 0 ).intValue() ); - assertEquals( initialDelay * multiplier, scheduleDelays.get( 1 ).intValue() ); + assertEquals(2, scheduleDelays.size()); + assertEquals(initialDelay, scheduleDelays.get(0).intValue()); + assertEquals(initialDelay * multiplier, scheduleDelays.get(1).intValue()); - assertThat( executionCount.get(), equalTo( 3 ) ); + assertThat(executionCount.get(), equalTo(3)); } @Test - void sleepsOnServiceUnavailableException() throws Exception - { - Clock clock = mock( Clock.class ); - ExponentialBackoffRetryLogic logic = newRetryLogic( 1, 42, 1, 0, clock ); + void sleepsOnServiceUnavailableException() throws Exception { + Clock clock = mock(Clock.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 42, 1, 0, clock); Supplier workMock = newWorkMock(); ServiceUnavailableException error = serviceUnavailable(); - when( workMock.get() ).thenThrow( error ).thenReturn( null ); + when(workMock.get()).thenThrow(error).thenReturn(null); - assertNull( logic.retry( workMock ) ); + assertNull(logic.retry(workMock)); - verify( workMock, times( 2 ) ).get(); - verify( clock ).sleep( 42 ); + verify(workMock, times(2)).get(); + verify(clock).sleep(42); } @Test - void schedulesRetryOnServiceUnavailableExceptionAsync() - { + void schedulesRetryOnServiceUnavailableExceptionAsync() { String result = "The Result"; - Clock clock = mock( Clock.class ); + Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( 1, 42, 1, 0, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 42, 1, 0, clock); Supplier> workMock = newWorkMock(); ServiceUnavailableException error = serviceUnavailable(); - when( workMock.get() ).thenReturn( failedFuture( error ) ).thenReturn( completedFuture( result ) ); + when(workMock.get()).thenReturn(failedFuture(error)).thenReturn(completedFuture(result)); - assertEquals( result, await( retryLogic.retryAsync( workMock ) ) ); + assertEquals(result, await(retryLogic.retryAsync(workMock))); - verify( workMock, times( 2 ) ).get(); + verify(workMock, times(2)).get(); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 1, scheduleDelays.size() ); - assertEquals( 42, scheduleDelays.get( 0 ).intValue() ); + assertEquals(1, scheduleDelays.size()); + assertEquals(42, scheduleDelays.get(0).intValue()); } @Test - void sleepsOnSessionExpiredException() throws Exception - { - Clock clock = mock( Clock.class ); - ExponentialBackoffRetryLogic logic = newRetryLogic( 1, 4242, 1, 0, clock ); + void sleepsOnSessionExpiredException() throws Exception { + Clock clock = mock(Clock.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 4242, 1, 0, clock); Supplier workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); - when( workMock.get() ).thenThrow( error ).thenReturn( null ); + when(workMock.get()).thenThrow(error).thenReturn(null); - assertNull( logic.retry( workMock ) ); + assertNull(logic.retry(workMock)); - verify( workMock, times( 2 ) ).get(); - verify( clock ).sleep( 4242 ); + verify(workMock, times(2)).get(); + verify(clock).sleep(4242); } @Test - void schedulesRetryOnSessionExpiredExceptionAsync() - { + void schedulesRetryOnSessionExpiredExceptionAsync() { String result = "The Result"; - Clock clock = mock( Clock.class ); + Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( 1, 4242, 1, 0, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 4242, 1, 0, clock); Supplier> workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); - when( workMock.get() ).thenReturn( failedFuture( error ) ).thenReturn( completedFuture( result ) ); + when(workMock.get()).thenReturn(failedFuture(error)).thenReturn(completedFuture(result)); - assertEquals( result, await( retryLogic.retryAsync( workMock ) ) ); + assertEquals(result, await(retryLogic.retryAsync(workMock))); - verify( workMock, times( 2 ) ).get(); + verify(workMock, times(2)).get(); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 1, scheduleDelays.size() ); - assertEquals( 4242, scheduleDelays.get( 0 ).intValue() ); + assertEquals(1, scheduleDelays.size()); + assertEquals(4242, scheduleDelays.get(0).intValue()); } @Test - void sleepsOnTransientException() throws Exception - { - Clock clock = mock( Clock.class ); - ExponentialBackoffRetryLogic logic = newRetryLogic( 1, 23, 1, 0, clock ); + void sleepsOnTransientException() throws Exception { + Clock clock = mock(Clock.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 23, 1, 0, clock); Supplier workMock = newWorkMock(); TransientException error = transientException(); - when( workMock.get() ).thenThrow( error ).thenReturn( null ); + when(workMock.get()).thenThrow(error).thenReturn(null); - assertNull( logic.retry( workMock ) ); + assertNull(logic.retry(workMock)); - verify( workMock, times( 2 ) ).get(); - verify( clock ).sleep( 23 ); + verify(workMock, times(2)).get(); + verify(clock).sleep(23); } @Test - void schedulesRetryOnTransientExceptionAsync() - { + void schedulesRetryOnTransientExceptionAsync() { String result = "The Result"; - Clock clock = mock( Clock.class ); + Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( 1, 23, 1, 0, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 23, 1, 0, clock); Supplier> workMock = newWorkMock(); TransientException error = transientException(); - when( workMock.get() ).thenReturn( failedFuture( error ) ).thenReturn( completedFuture( result ) ); + when(workMock.get()).thenReturn(failedFuture(error)).thenReturn(completedFuture(result)); - assertEquals( result, await( retryLogic.retryAsync( workMock ) ) ); + assertEquals(result, await(retryLogic.retryAsync(workMock))); - verify( workMock, times( 2 ) ).get(); + verify(workMock, times(2)).get(); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 1, scheduleDelays.size() ); - assertEquals( 23, scheduleDelays.get( 0 ).intValue() ); + assertEquals(1, scheduleDelays.size()); + assertEquals(23, scheduleDelays.get(0).intValue()); } @Test - void throwsWhenUnknownError() throws Exception - { - Clock clock = mock( Clock.class ); - ExponentialBackoffRetryLogic logic = newRetryLogic( 1, 1, 1, 1, clock ); + void throwsWhenUnknownError() throws Exception { + Clock clock = mock(Clock.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 1, 1, 1, clock); Supplier workMock = newWorkMock(); IllegalStateException error = new IllegalStateException(); - when( workMock.get() ).thenThrow( error ); + when(workMock.get()).thenThrow(error); - Exception e = assertThrows( Exception.class, () -> logic.retry( workMock ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> logic.retry(workMock)); + assertEquals(error, e); - verify( workMock ).get(); - verify( clock, never() ).sleep( anyLong() ); + verify(workMock).get(); + verify(clock, never()).sleep(anyLong()); } @Test - void doesNotRetryOnUnknownErrorAsync() - { - Clock clock = mock( Clock.class ); + void doesNotRetryOnUnknownErrorAsync() { + Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( 1, 1, 1, 1, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 1, 1, 1, clock); Supplier> workMock = newWorkMock(); IllegalStateException error = new IllegalStateException(); - when( workMock.get() ).thenReturn( failedFuture( error ) ); + when(workMock.get()).thenReturn(failedFuture(error)); - Exception e = assertThrows( Exception.class, () -> await( retryLogic.retryAsync( workMock ) ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> await(retryLogic.retryAsync(workMock))); + assertEquals(error, e); - verify( workMock ).get(); - assertEquals( 0, eventExecutor.scheduleDelays().size() ); + verify(workMock).get(); + assertEquals(0, eventExecutor.scheduleDelays().size()); } @Test - void throwsWhenTransactionTerminatedError() throws Exception - { - Clock clock = mock( Clock.class ); - ExponentialBackoffRetryLogic logic = newRetryLogic( 1, 13, 1, 0, clock ); + void throwsWhenTransactionTerminatedError() throws Exception { + Clock clock = mock(Clock.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 13, 1, 0, clock); Supplier workMock = newWorkMock(); - TransientException error = new TransientException( "Neo.TransientError.Transaction.Terminated", "" ); - when( workMock.get() ).thenThrow( error ).thenReturn( null ); + TransientException error = new TransientException("Neo.TransientError.Transaction.Terminated", ""); + when(workMock.get()).thenThrow(error).thenReturn(null); - Exception e = assertThrows( Exception.class, () -> logic.retry( workMock ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> logic.retry(workMock)); + assertEquals(error, e); - verify( workMock ).get(); - verify( clock, never() ).sleep( 13 ); + verify(workMock).get(); + verify(clock, never()).sleep(13); } @Test - void doesNotRetryOnTransactionTerminatedErrorAsync() - { - Clock clock = mock( Clock.class ); + void doesNotRetryOnTransactionTerminatedErrorAsync() { + Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( 1, 13, 1, 0, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 13, 1, 0, clock); Supplier> workMock = newWorkMock(); - TransientException error = new TransientException( "Neo.TransientError.Transaction.Terminated", "" ); - when( workMock.get() ).thenReturn( failedFuture( error ) ); + TransientException error = new TransientException("Neo.TransientError.Transaction.Terminated", ""); + when(workMock.get()).thenReturn(failedFuture(error)); - Exception e = assertThrows( Exception.class, () -> await( retryLogic.retryAsync( workMock ) ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> await(retryLogic.retryAsync(workMock))); + assertEquals(error, e); - verify( workMock ).get(); - assertEquals( 0, eventExecutor.scheduleDelays().size() ); + verify(workMock).get(); + assertEquals(0, eventExecutor.scheduleDelays().size()); } @Test - void throwsWhenTransactionLockClientStoppedError() throws Exception - { - Clock clock = mock( Clock.class ); - ExponentialBackoffRetryLogic logic = newRetryLogic( 1, 13, 1, 0, clock ); + void throwsWhenTransactionLockClientStoppedError() throws Exception { + Clock clock = mock(Clock.class); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 13, 1, 0, clock); Supplier workMock = newWorkMock(); - TransientException error = new TransientException( "Neo.TransientError.Transaction.LockClientStopped", "" ); - when( workMock.get() ).thenThrow( error ).thenReturn( null ); + TransientException error = new TransientException("Neo.TransientError.Transaction.LockClientStopped", ""); + when(workMock.get()).thenThrow(error).thenReturn(null); - Exception e = assertThrows( Exception.class, () -> logic.retry( workMock ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> logic.retry(workMock)); + assertEquals(error, e); - verify( workMock ).get(); - verify( clock, never() ).sleep( 13 ); + verify(workMock).get(); + verify(clock, never()).sleep(13); } @Test - void doesNotRetryOnTransactionLockClientStoppedErrorAsync() - { - Clock clock = mock( Clock.class ); + void doesNotRetryOnTransactionLockClientStoppedErrorAsync() { + Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( 1, 15, 1, 0, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 15, 1, 0, clock); Supplier> workMock = newWorkMock(); - TransientException error = new TransientException( "Neo.TransientError.Transaction.LockClientStopped", "" ); - when( workMock.get() ).thenReturn( failedFuture( error ) ); + TransientException error = new TransientException("Neo.TransientError.Transaction.LockClientStopped", ""); + when(workMock.get()).thenReturn(failedFuture(error)); - Exception e = assertThrows( Exception.class, () -> await( retryLogic.retryAsync( workMock ) ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> await(retryLogic.retryAsync(workMock))); + assertEquals(error, e); - verify( workMock ).get(); - assertEquals( 0, eventExecutor.scheduleDelays().size() ); + verify(workMock).get(); + assertEquals(0, eventExecutor.scheduleDelays().size()); } @ParameterizedTest - @MethodSource( "canBeRetriedErrors" ) - void schedulesRetryOnErrorRx( Exception error ) - { + @MethodSource("canBeRetriedErrors") + void schedulesRetryOnErrorRx(Exception error) { String result = "The Result"; - Clock clock = mock( Clock.class ); + Clock clock = mock(Clock.class); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( 1, 4242, 1, 0, clock ); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 4242, 1, 0, clock); - Publisher publisher = createMono( result, error ); - Mono single = Flux.from( retryLogic.retryRx( publisher ) ).single(); + Publisher publisher = createMono(result, error); + Mono single = Flux.from(retryLogic.retryRx(publisher)).single(); - assertEquals( result, await( single ) ); + assertEquals(result, await(single)); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 1, scheduleDelays.size() ); - assertEquals( 4242, scheduleDelays.get( 0 ).intValue() ); + assertEquals(1, scheduleDelays.size()); + assertEquals(4242, scheduleDelays.get(0).intValue()); } @ParameterizedTest - @MethodSource( "cannotBeRetriedErrors" ) - void scheduleNoRetryOnErrorRx( Exception error ) - { - Clock clock = mock( Clock.class ); - ExponentialBackoffRetryLogic retryLogic = newRetryLogic( 1, 10, 1, 1, clock ); + @MethodSource("cannotBeRetriedErrors") + void scheduleNoRetryOnErrorRx(Exception error) { + Clock clock = mock(Clock.class); + ExponentialBackoffRetryLogic retryLogic = newRetryLogic(1, 10, 1, 1, clock); - Mono single = Flux.from( retryLogic.retryRx( Mono.error( error ) ) ).single(); + Mono single = Flux.from(retryLogic.retryRx(Mono.error(error))).single(); - Exception e = assertThrows( Exception.class, () -> await( single ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> await(single)); + assertEquals(error, e); - assertEquals( 0, eventExecutor.scheduleDelays().size() ); + assertEquals(0, eventExecutor.scheduleDelays().size()); } @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 ); + void throwsWhenSleepInterrupted() throws Exception { + Clock clock = mock(Clock.class); + doThrow(new InterruptedException()).when(clock).sleep(1); + ExponentialBackoffRetryLogic logic = newRetryLogic(1, 1, 1, 0, clock); Supplier workMock = newWorkMock(); - when( workMock.get() ).thenThrow( serviceUnavailable() ); + when(workMock.get()).thenThrow(serviceUnavailable()); - try - { - IllegalStateException e = assertThrows( IllegalStateException.class, () -> logic.retry( workMock ) ); - assertThat( e.getCause(), instanceOf( InterruptedException.class ) ); - } - finally - { + try { + IllegalStateException e = assertThrows(IllegalStateException.class, () -> logic.retry(workMock)); + assertThat(e.getCause(), instanceOf(InterruptedException.class)); + } finally { // Clear the interruption flag so all subsequent tests do not see this thread as interrupted Thread.interrupted(); } } @Test - void collectsSuppressedErrors() throws Exception - { + void collectsSuppressedErrors() throws Exception { 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 ); + Clock clock = mock(Clock.class); + when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(15L).thenReturn(25L); + ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); Supplier workMock = newWorkMock(); SessionExpiredException error1 = sessionExpired(); SessionExpiredException error2 = sessionExpired(); ServiceUnavailableException error3 = serviceUnavailable(); TransientException error4 = transientException(); - when( workMock.get() ).thenThrow( error1, error2, error3, error4 ).thenReturn( null ); + when(workMock.get()).thenThrow(error1, error2, error3, error4).thenReturn(null); - Exception e = assertThrows( Exception.class, () -> logic.retry( workMock ) ); - assertEquals( error4, e ); + Exception e = assertThrows(Exception.class, () -> logic.retry(workMock)); + assertEquals(error4, e); Throwable[] suppressed = e.getSuppressed(); - assertEquals( 3, suppressed.length ); - assertEquals( error1, suppressed[0] ); - assertEquals( error2, suppressed[1] ); - assertEquals( error3, suppressed[2] ); + assertEquals(3, suppressed.length); + assertEquals(error1, suppressed[0]); + assertEquals(error2, suppressed[1]); + assertEquals(error3, suppressed[2]); - verify( workMock, times( 4 ) ).get(); + 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(clock, times(3)).sleep(anyLong()); + verify(clock).sleep(initialDelay); + verify(clock).sleep(initialDelay * multiplier); + verify(clock).sleep(initialDelay * multiplier * multiplier); } @Test - void collectsSuppressedErrorsAsync() - { + void collectsSuppressedErrorsAsync() { String result = "The Result"; 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 ); + 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); Supplier> workMock = newWorkMock(); SessionExpiredException error1 = sessionExpired(); @@ -641,804 +614,731 @@ void collectsSuppressedErrorsAsync() ServiceUnavailableException error3 = serviceUnavailable(); TransientException error4 = transientException(); - when( workMock.get() ).thenReturn( failedFuture( error1 ) ) - .thenReturn( failedFuture( error2 ) ) - .thenReturn( failedFuture( error3 ) ) - .thenReturn( failedFuture( error4 ) ) - .thenReturn( completedFuture( result ) ); + when(workMock.get()) + .thenReturn(failedFuture(error1)) + .thenReturn(failedFuture(error2)) + .thenReturn(failedFuture(error3)) + .thenReturn(failedFuture(error4)) + .thenReturn(completedFuture(result)); - Exception e = assertThrows( Exception.class, () -> await( retryLogic.retryAsync( workMock ) ) ); - assertEquals( error4, e ); + Exception e = assertThrows(Exception.class, () -> await(retryLogic.retryAsync(workMock))); + assertEquals(error4, e); Throwable[] suppressed = e.getSuppressed(); - assertEquals( 3, suppressed.length ); - assertEquals( error1, suppressed[0] ); - assertEquals( error2, suppressed[1] ); - assertEquals( error3, suppressed[2] ); + assertEquals(3, suppressed.length); + assertEquals(error1, suppressed[0]); + assertEquals(error2, suppressed[1]); + assertEquals(error3, suppressed[2]); - verify( workMock, times( 4 ) ).get(); + verify(workMock, times(4)).get(); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 3, scheduleDelays.size() ); - assertEquals( initialDelay, scheduleDelays.get( 0 ).intValue() ); - assertEquals( initialDelay * multiplier, scheduleDelays.get( 1 ).intValue() ); - assertEquals( initialDelay * multiplier * multiplier, scheduleDelays.get( 2 ).intValue() ); + assertEquals(3, scheduleDelays.size()); + assertEquals(initialDelay, scheduleDelays.get(0).intValue()); + assertEquals(initialDelay * multiplier, scheduleDelays.get(1).intValue()); + assertEquals( + initialDelay * multiplier * multiplier, scheduleDelays.get(2).intValue()); } @Test - void collectsSuppressedErrorsRx() throws Exception - { + void collectsSuppressedErrorsRx() throws Exception { 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 ); + Clock clock = mock(Clock.class); + when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(15L).thenReturn(25L); + ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); SessionExpiredException error1 = sessionExpired(); SessionExpiredException error2 = sessionExpired(); ServiceUnavailableException error3 = serviceUnavailable(); TransientException error4 = transientException(); - Mono mono = createMono( "A result", error1, error2, error3, error4 ); - - StepVerifier.create( logic.retryRx( mono ) ).expectErrorSatisfies( e -> { - assertEquals( error4, e ); - Throwable[] suppressed = e.getSuppressed(); - assertEquals( 3, suppressed.length ); - assertEquals( error1, suppressed[0] ); - assertEquals( error2, suppressed[1] ); - assertEquals( error3, suppressed[2] ); - } ).verify(); + Mono mono = createMono("A result", error1, error2, error3, error4); + + StepVerifier.create(logic.retryRx(mono)) + .expectErrorSatisfies(e -> { + assertEquals(error4, e); + Throwable[] suppressed = e.getSuppressed(); + assertEquals(3, suppressed.length); + assertEquals(error1, suppressed[0]); + assertEquals(error2, suppressed[1]); + assertEquals(error3, suppressed[2]); + }) + .verify(); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 3, scheduleDelays.size() ); - assertEquals( initialDelay, scheduleDelays.get( 0 ).intValue() ); - assertEquals( initialDelay * multiplier, scheduleDelays.get( 1 ).intValue() ); - assertEquals( initialDelay * multiplier * multiplier, scheduleDelays.get( 2 ).intValue() ); } + assertEquals(3, scheduleDelays.size()); + assertEquals(initialDelay, scheduleDelays.get(0).intValue()); + assertEquals(initialDelay * multiplier, scheduleDelays.get(1).intValue()); + assertEquals( + initialDelay * multiplier * multiplier, scheduleDelays.get(2).intValue()); + } @Test - void doesNotCollectSuppressedErrorsWhenSameErrorIsThrown() throws Exception - { + void doesNotCollectSuppressedErrorsWhenSameErrorIsThrown() throws Exception { long maxRetryTime = 20; int initialDelay = 15; 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 ); + Clock clock = mock(Clock.class); + when(clock.millis()).thenReturn(0L).thenReturn(10L).thenReturn(25L); + ExponentialBackoffRetryLogic logic = newRetryLogic(maxRetryTime, initialDelay, multiplier, 0, clock); Supplier workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); - when( workMock.get() ).thenThrow( error ); + when(workMock.get()).thenThrow(error); - Exception e = assertThrows( Exception.class, () -> logic.retry( workMock ) ); - assertEquals( error, e ); - assertEquals( 0, e.getSuppressed().length ); + Exception e = assertThrows(Exception.class, () -> logic.retry(workMock)); + assertEquals(error, e); + assertEquals(0, e.getSuppressed().length); - verify( workMock, times( 3 ) ).get(); + verify(workMock, times(3)).get(); - verify( clock, times( 2 ) ).sleep( anyLong() ); - verify( clock ).sleep( initialDelay ); - verify( clock ).sleep( initialDelay * multiplier ); + verify(clock, times(2)).sleep(anyLong()); + verify(clock).sleep(initialDelay); + verify(clock).sleep(initialDelay * multiplier); } @Test - void doesNotCollectSuppressedErrorsWhenSameErrorIsThrownAsync() - { + void doesNotCollectSuppressedErrorsWhenSameErrorIsThrownAsync() { long maxRetryTime = 20; int initialDelay = 15; int multiplier = 2; - Clock clock = mock( Clock.class ); - when( clock.millis() ).thenReturn( 0L ).thenReturn( 10L ).thenReturn( 25L ); + 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); Supplier> workMock = newWorkMock(); SessionExpiredException error = sessionExpired(); - when( workMock.get() ).thenReturn( failedFuture( error ) ); + when(workMock.get()).thenReturn(failedFuture(error)); - Exception e = assertThrows( Exception.class, () -> await( retryLogic.retryAsync( workMock ) ) ); - assertEquals( error, e ); - assertEquals( 0, e.getSuppressed().length ); + Exception e = assertThrows(Exception.class, () -> await(retryLogic.retryAsync(workMock))); + assertEquals(error, e); + assertEquals(0, e.getSuppressed().length); - verify( workMock, times( 3 ) ).get(); + verify(workMock, times(3)).get(); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 2, scheduleDelays.size() ); - assertEquals( initialDelay, scheduleDelays.get( 0 ).intValue() ); - assertEquals( initialDelay * multiplier, scheduleDelays.get( 1 ).intValue() ); + assertEquals(2, scheduleDelays.size()); + assertEquals(initialDelay, scheduleDelays.get(0).intValue()); + assertEquals(initialDelay * multiplier, scheduleDelays.get(1).intValue()); } @Test - void doesNotCollectSuppressedErrorsWhenSameErrorIsThrownRx() - { + void doesNotCollectSuppressedErrorsWhenSameErrorIsThrownRx() { long maxRetryTime = 20; int initialDelay = 15; int multiplier = 2; - Clock clock = mock( Clock.class ); - when( clock.millis() ).thenReturn( 0L ).thenReturn( 10L ).thenReturn( 25L ); + 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); SessionExpiredException error = sessionExpired(); - StepVerifier.create( retryLogic.retryRx( Mono.error( error ) ) ).expectErrorSatisfies( e -> assertEquals( error, e ) ).verify(); + StepVerifier.create(retryLogic.retryRx(Mono.error(error))) + .expectErrorSatisfies(e -> assertEquals(error, e)) + .verify(); List scheduleDelays = eventExecutor.scheduleDelays(); - assertEquals( 2, scheduleDelays.size() ); - assertEquals( initialDelay, scheduleDelays.get( 0 ).intValue() ); - assertEquals( initialDelay * multiplier, scheduleDelays.get( 1 ).intValue() ); + assertEquals(2, scheduleDelays.size()); + assertEquals(initialDelay, scheduleDelays.get(0).intValue()); + assertEquals(initialDelay * multiplier, scheduleDelays.get(1).intValue()); } @Test - void doesRetryOnClientExceptionWithRetryableCause() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - String result = logic.retry( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw clientExceptionWithValidTerminationCause(); - } - return "Done"; - } ); - - assertEquals( "Done", result ); - } + void doesRetryOnClientExceptionWithRetryableCause() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + String result = logic.retry(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw clientExceptionWithValidTerminationCause(); + } + return "Done"; + }); - @Test - void doesRetryOnAuthorizationExpiredException() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - String result = logic.retry( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw authorizationExpiredException(); - } - return "Done"; - } ); - - assertEquals( "Done", result ); + assertEquals("Done", result); } @Test - void doesRetryOnConnectionReadTimeoutException() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - String result = logic.retry( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw ConnectionReadTimeoutException.INSTANCE; - } - return "Done"; - } ); - - assertEquals( "Done", result ); + void doesRetryOnAuthorizationExpiredException() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + String result = logic.retry(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw authorizationExpiredException(); + } + return "Done"; + }); + + assertEquals("Done", result); } @Test - void doesNotRetryOnRandomClientException() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( anyString() ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - ClientException exception = Assertions.assertThrows( ClientException.class, () -> logic.retry( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw randomClientException(); + void doesRetryOnConnectionReadTimeoutException() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + String result = logic.retry(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw ConnectionReadTimeoutException.INSTANCE; } return "Done"; - } ) ); + }); + + assertEquals("Done", result); + } + + @Test + void doesNotRetryOnRandomClientException() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(anyString())).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + ClientException exception = Assertions.assertThrows( + ClientException.class, + () -> logic.retry(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw randomClientException(); + } + return "Done"; + })); - assertEquals( "Meeh", exception.getMessage() ); + assertEquals("Meeh", exception.getMessage()); } @Test - void eachRetryIsLogged() - { + void eachRetryIsLogged() { int retries = 9; - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, - clock, logging ); + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); - retry( logic, retries ); + retry(logic, retries); - verify( logger, times( retries ) ).warn( - startsWith( "Transaction failed and will be retried" ), - any( ServiceUnavailableException.class ) - ); + verify(logger, times(retries)) + .warn(startsWith("Transaction failed and will be retried"), any(ServiceUnavailableException.class)); } @Test - void doesRetryOnClientExceptionWithRetryableCauseAsync() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - String result = await( logic.retryAsync( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { + void doesRetryOnClientExceptionWithRetryableCauseAsync() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + String result = await(logic.retryAsync(() -> { + if (exceptionThrown.compareAndSet(false, true)) { throw clientExceptionWithValidTerminationCause(); } - return CompletableFuture.completedFuture( "Done" ); - } ) ); + return CompletableFuture.completedFuture("Done"); + })); - assertEquals( "Done", result ); + assertEquals("Done", result); } @Test - void doesRetryOnAuthorizationExpiredExceptionAsync() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - String result = await( logic.retryAsync( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw authorizationExpiredException(); - } - return CompletableFuture.completedFuture( "Done" ); - } ) ); - - assertEquals( "Done", result ); + void doesRetryOnAuthorizationExpiredExceptionAsync() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + String result = await(logic.retryAsync(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw authorizationExpiredException(); + } + return CompletableFuture.completedFuture("Done"); + })); + + assertEquals("Done", result); } @Test - void doesNotRetryOnRandomClientExceptionAsync() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( anyString() ) ).thenReturn( logger ); - - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - ClientException exception = Assertions.assertThrows( ClientException.class, () -> await( logic.retryAsync( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw randomClientException(); - } - return CompletableFuture.completedFuture( "Done" ); - } ) ) ); + void doesNotRetryOnRandomClientExceptionAsync() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(anyString())).thenReturn(logger); + + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + ClientException exception = Assertions.assertThrows( + ClientException.class, + () -> await(logic.retryAsync(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw randomClientException(); + } + return CompletableFuture.completedFuture("Done"); + }))); - assertEquals( "Meeh", exception.getMessage() ); + assertEquals("Meeh", exception.getMessage()); } @Test - void eachRetryIsLoggedAsync() - { + void eachRetryIsLoggedAsync() { String result = "The Result"; int retries = 9; - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, - clock, logging ); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); - assertEquals( result, await( retryAsync( logic, retries, result ) ) ); + assertEquals(result, await(retryAsync(logic, retries, result))); - verify( logger, times( retries ) ).warn( - startsWith( "Async transaction failed and is scheduled to retry" ), - any( ServiceUnavailableException.class ) - ); + verify(logger, times(retries)) + .warn( + startsWith("Async transaction failed and is scheduled to retry"), + any(ServiceUnavailableException.class)); } @Test - void doesRetryOnClientExceptionWithRetryableCauseRx() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - String result = await( Mono.from( logic.retryRx( Mono.fromSupplier( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { + void doesRetryOnClientExceptionWithRetryableCauseRx() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + String result = await(Mono.from(logic.retryRx(Mono.fromSupplier(() -> { + if (exceptionThrown.compareAndSet(false, true)) { throw clientExceptionWithValidTerminationCause(); } return "Done"; - } ) ) ) ); + })))); - assertEquals( "Done", result ); + assertEquals("Done", result); } @Test - void doesRetryOnAuthorizationExpiredExceptionRx() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - String result = await( Mono.from( logic.retryRx( Mono.fromSupplier( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw authorizationExpiredException(); - } - return "Done"; - } ) ) ) ); - - assertEquals( "Done", result ); - } + void doesRetryOnAuthorizationExpiredExceptionRx() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + String result = await(Mono.from(logic.retryRx(Mono.fromSupplier(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw authorizationExpiredException(); + } + return "Done"; + })))); - @Test - void doesRetryOnAsyncResourceCleanupRuntimeExceptionRx() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - String result = await( Mono.from( logic.retryRx( Mono.fromSupplier( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw new RuntimeException( "Async resource cleanup failed after", - authorizationExpiredException() ); - } - return "Done"; - } ) ) ) ); - - assertEquals( "Done", result ); + assertEquals("Done", result); } @Test - void doesNotRetryOnRandomClientExceptionRx() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( anyString() ) ).thenReturn( logger ); - - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, clock, logging ); - - AtomicBoolean exceptionThrown = new AtomicBoolean( false ); - ClientException exception = Assertions.assertThrows( ClientException.class, () -> await( Mono.from( logic.retryRx( Mono.fromSupplier( () -> - { - if ( exceptionThrown.compareAndSet( false, true ) ) - { - throw randomClientException(); + void doesRetryOnAsyncResourceCleanupRuntimeExceptionRx() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + String result = await(Mono.from(logic.retryRx(Mono.fromSupplier(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw new RuntimeException("Async resource cleanup failed after", authorizationExpiredException()); } return "Done"; - } ) ) ) ) ); + })))); + + assertEquals("Done", result); + } + + @Test + void doesNotRetryOnRandomClientExceptionRx() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(anyString())).thenReturn(logger); + + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); + + AtomicBoolean exceptionThrown = new AtomicBoolean(false); + ClientException exception = Assertions.assertThrows( + ClientException.class, + () -> await(Mono.from(logic.retryRx(Mono.fromSupplier(() -> { + if (exceptionThrown.compareAndSet(false, true)) { + throw randomClientException(); + } + return "Done"; + }))))); - assertEquals( "Meeh", exception.getMessage() ); + assertEquals("Meeh", exception.getMessage()); } @Test - void eachRetryIsLoggedRx() - { + void eachRetryIsLoggedRx() { String result = "The Result"; int retries = 9; - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, - clock, logging ); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, clock, logging); - assertEquals( result, await( Flux.from( retryRx( logic, retries, result ) ).single() ) ); + assertEquals(result, await(Flux.from(retryRx(logic, retries, result)).single())); - verify( logger, times( retries ) ).warn( - startsWith( "Reactive transaction failed and is scheduled to retry" ), - any( ServiceUnavailableException.class ) - ); + verify(logger, times(retries)) + .warn( + startsWith("Reactive transaction failed and is scheduled to retry"), + any(ServiceUnavailableException.class)); } @Test - void nothingIsLoggedOnFatalFailure() - { - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( anyString() ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, - mock( Clock.class ), logging ); - - RuntimeException error = assertThrows( RuntimeException.class, () -> - logic.retry( () -> - { - throw new RuntimeException( "Fatal blocking" ); - } ) ); - assertEquals( "Fatal blocking", error.getMessage() ); - verifyNoInteractions( logger ); + void nothingIsLoggedOnFatalFailure() { + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(anyString())).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, mock(Clock.class), logging); + + RuntimeException error = assertThrows( + RuntimeException.class, + () -> logic.retry(() -> { + throw new RuntimeException("Fatal blocking"); + })); + assertEquals("Fatal blocking", error.getMessage()); + verifyNoInteractions(logger); } @Test - void nothingIsLoggedOnFatalFailureAsync() - { - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( anyString() ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, - mock( Clock.class ), logging ); + void nothingIsLoggedOnFatalFailureAsync() { + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(anyString())).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, mock(Clock.class), logging); - RuntimeException error = assertThrows( RuntimeException.class, () -> - await( logic.retryAsync( () -> failedFuture( new RuntimeException( "Fatal async" ) ) ) ) ); + RuntimeException error = assertThrows( + RuntimeException.class, + () -> await(logic.retryAsync(() -> failedFuture(new RuntimeException("Fatal async"))))); - assertEquals( "Fatal async", error.getMessage() ); - verifyNoInteractions( logger ); + assertEquals("Fatal async", error.getMessage()); + verifyNoInteractions(logger); } @Test - void nothingIsLoggedOnFatalFailureRx() - { - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( anyString() ) ).thenReturn( logger ); - ExponentialBackoffRetryLogic logic = new ExponentialBackoffRetryLogic( RetrySettings.DEFAULT, eventExecutor, - mock( Clock.class ), logging ); + void nothingIsLoggedOnFatalFailureRx() { + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(anyString())).thenReturn(logger); + ExponentialBackoffRetryLogic logic = + new ExponentialBackoffRetryLogic(RetrySettings.DEFAULT, eventExecutor, mock(Clock.class), logging); - Publisher retryRx = logic.retryRx( Mono.error( new RuntimeException( "Fatal rx" ) ) ); - RuntimeException error = assertThrows( RuntimeException.class, () -> await( retryRx ) ); + Publisher retryRx = logic.retryRx(Mono.error(new RuntimeException("Fatal rx"))); + RuntimeException error = assertThrows(RuntimeException.class, () -> await(retryRx)); - assertEquals( "Fatal rx", error.getMessage() ); - verifyNoInteractions( logger ); + assertEquals("Fatal rx", error.getMessage()); + verifyNoInteractions(logger); } @Test - void correctNumberOfRetiesAreLoggedOnFailure() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + void correctNumberOfRetiesAreLoggedOnFailure() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); RetrySettings settings = RetrySettings.DEFAULT; - RetryLogic logic = new ExponentialBackoffRetryLogic( settings, eventExecutor, clock, logging ); + RetryLogic logic = new ExponentialBackoffRetryLogic(settings, eventExecutor, clock, logging); - ServiceUnavailableException error = assertThrows( ServiceUnavailableException.class, () -> - logic.retry( new Supplier() - { + ServiceUnavailableException error = assertThrows( + ServiceUnavailableException.class, + () -> logic.retry(new Supplier() { boolean invoked; @Override - public Long get() - { + public Long get() { // work that always fails and moves clock forward after the first failure - if ( invoked ) - { + if (invoked) { // move clock forward to stop retries - when( clock.millis() ).thenReturn( settings.maxRetryTimeMs() + 42 ); - } - else - { + when(clock.millis()).thenReturn(settings.maxRetryTimeMs() + 42); + } else { invoked = true; } - throw new ServiceUnavailableException( "Error" ); + throw new ServiceUnavailableException("Error"); } - } ) ); - assertEquals( "Error", error.getMessage() ); - verify( logger ).warn( - startsWith( "Transaction failed and will be retried" ), - any( ServiceUnavailableException.class ) - ); + })); + assertEquals("Error", error.getMessage()); + verify(logger) + .warn(startsWith("Transaction failed and will be retried"), any(ServiceUnavailableException.class)); } @Test - void correctNumberOfRetiesAreLoggedOnFailureAsync() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + void correctNumberOfRetiesAreLoggedOnFailureAsync() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); RetrySettings settings = RetrySettings.DEFAULT; - RetryLogic logic = new ExponentialBackoffRetryLogic( settings, eventExecutor, clock, logging ); + RetryLogic logic = new ExponentialBackoffRetryLogic(settings, eventExecutor, clock, logging); - SessionExpiredException error = assertThrows( SessionExpiredException.class, () -> - await( logic.retryAsync( new Supplier>() - { + SessionExpiredException error = assertThrows( + SessionExpiredException.class, + () -> await(logic.retryAsync(new Supplier>() { volatile boolean invoked; @Override - public CompletionStage get() - { + public CompletionStage get() { // work that always returns failed future and moves clock forward after the first failure - if ( invoked ) - { + if (invoked) { // move clock forward to stop retries - when( clock.millis() ).thenReturn( settings.maxRetryTimeMs() + 42 ); - } - else - { + when(clock.millis()).thenReturn(settings.maxRetryTimeMs() + 42); + } else { invoked = true; } - return failedFuture( new SessionExpiredException( "Session no longer valid" ) ); + return failedFuture(new SessionExpiredException("Session no longer valid")); } - } ) ) ); - assertEquals( "Session no longer valid", error.getMessage() ); - verify( logger ).warn( - startsWith( "Async transaction failed and is scheduled to retry" ), - any( SessionExpiredException.class ) - ); + }))); + assertEquals("Session no longer valid", error.getMessage()); + verify(logger) + .warn( + startsWith("Async transaction failed and is scheduled to retry"), + any(SessionExpiredException.class)); } @Test - void correctNumberOfRetiesAreLoggedOnFailureRx() - { - Clock clock = mock( Clock.class ); - Logging logging = mock( Logging.class ); - Logger logger = mock( Logger.class ); - when( logging.getLog( any( Class.class ) ) ).thenReturn( logger ); + void correctNumberOfRetiesAreLoggedOnFailureRx() { + Clock clock = mock(Clock.class); + Logging logging = mock(Logging.class); + Logger logger = mock(Logger.class); + when(logging.getLog(any(Class.class))).thenReturn(logger); RetrySettings settings = RetrySettings.DEFAULT; - RetryLogic logic = new ExponentialBackoffRetryLogic( settings, eventExecutor, clock, logging ); + RetryLogic logic = new ExponentialBackoffRetryLogic(settings, eventExecutor, clock, logging); - AtomicBoolean invoked = new AtomicBoolean( false ); - SessionExpiredException error = assertThrows( SessionExpiredException.class, () -> - await( logic.retryRx( Mono.create( e -> { - if ( invoked.get() ) - { + AtomicBoolean invoked = new AtomicBoolean(false); + SessionExpiredException error = assertThrows( + SessionExpiredException.class, + () -> await(logic.retryRx(Mono.create(e -> { + if (invoked.get()) { // move clock forward to stop retries - when( clock.millis() ).thenReturn( settings.maxRetryTimeMs() + 42 ); - } - else - { - invoked.set( true ); + when(clock.millis()).thenReturn(settings.maxRetryTimeMs() + 42); + } else { + invoked.set(true); } - e.error( new SessionExpiredException( "Session no longer valid" ) ); - } ) ) ) ); - assertEquals( "Session no longer valid", error.getMessage() ); - verify( logger ).warn( - startsWith( "Reactive transaction failed and is scheduled to retry" ), - any( SessionExpiredException.class ) - ); + e.error(new SessionExpiredException("Session no longer valid")); + })))); + assertEquals("Session no longer valid", error.getMessage()); + verify(logger) + .warn( + startsWith("Reactive transaction failed and is scheduled to retry"), + any(SessionExpiredException.class)); } @Test - 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 ); - - Flux source = Flux.concat( Flux.range( 0, 2 ), Flux.error( exception ) ); - Flux retriedSource = Flux.from( retryLogic.retryRx( source ) ); - StepVerifier.create( retriedSource ) - .expectNext( 0, 1 ) // first run - .expectNext( 0, 1, 0, 1, 0, 1, 0, 1 ) //4 retry attempts - .verifyErrorSatisfies( e -> assertThat( e, equalTo( exception ) ) ); + 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); + + Flux source = Flux.concat(Flux.range(0, 2), Flux.error(exception)); + Flux retriedSource = Flux.from(retryLogic.retryRx(source)); + StepVerifier.create(retriedSource) + .expectNext(0, 1) // first run + .expectNext(0, 1, 0, 1, 0, 1, 0, 1) // 4 retry attempts + .verifyErrorSatisfies(e -> assertThat(e, equalTo(exception))); List delays = eventExecutor.scheduleDelays(); - assertThat( delays.size(), equalTo( 4 ) ); - assertThat( delays, contains( 100L, 200L, 400L, 800L ) ); + assertThat(delays.size(), equalTo(4)); + assertThat(delays, contains(100L, 200L, 400L, 800L)); } @Test - 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 ); - - Flux source = Flux.concat( Flux.range( 0, 2 ), Flux.error( exception ) ); - Flux retriedSource = Flux.from( retryLogic.retryRx( source ) ); - StepVerifier.create( retriedSource ) - .expectNext( 0, 1 ) // first run - .expectNext( 0, 1, 0, 1, 0, 1, 0, 1 ) // 4 retry attempts - .verifyErrorSatisfies( e -> assertThat( e, equalTo( exception ) ) ); + 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); + + Flux source = Flux.concat(Flux.range(0, 2), Flux.error(exception)); + Flux retriedSource = Flux.from(retryLogic.retryRx(source)); + StepVerifier.create(retriedSource) + .expectNext(0, 1) // first run + .expectNext(0, 1, 0, 1, 0, 1, 0, 1) // 4 retry attempts + .verifyErrorSatisfies(e -> assertThat(e, equalTo(exception))); List delays = eventExecutor.scheduleDelays(); - assertThat( delays.size(), equalTo( 4 ) ); - assertThat( delays.get( 0 ), allOf( greaterThanOrEqualTo( 90L ), lessThanOrEqualTo( 110L ) ) ); - assertThat( delays.get( 1 ), allOf( greaterThanOrEqualTo( 180L ), lessThanOrEqualTo( 220L ) ) ); - assertThat( delays.get( 2 ), allOf( greaterThanOrEqualTo( 260L ), lessThanOrEqualTo( 440L ) ) ); - assertThat( delays.get( 3 ), allOf( greaterThanOrEqualTo( 720L ), lessThanOrEqualTo( 880L ) ) ); + assertThat(delays.size(), equalTo(4)); + assertThat(delays.get(0), allOf(greaterThanOrEqualTo(90L), lessThanOrEqualTo(110L))); + assertThat(delays.get(1), allOf(greaterThanOrEqualTo(180L), lessThanOrEqualTo(220L))); + assertThat(delays.get(2), allOf(greaterThanOrEqualTo(260L), lessThanOrEqualTo(440L))); + assertThat(delays.get(3), allOf(greaterThanOrEqualTo(720L), lessThanOrEqualTo(880L))); } - private static void retry( ExponentialBackoffRetryLogic retryLogic, final int times ) - { - retryLogic.retry( new Supplier() - { + private static void retry(ExponentialBackoffRetryLogic retryLogic, final int times) { + retryLogic.retry(new Supplier() { int invoked; @Override - public Void get() - { - if ( invoked < times ) - { + public Void get() { + if (invoked < times) { invoked++; throw serviceUnavailable(); } return null; } - } ); + }); } - private CompletionStage retryAsync( ExponentialBackoffRetryLogic retryLogic, int times, Object result ) - { - return retryLogic.retryAsync( new Supplier>() - { + private CompletionStage retryAsync(ExponentialBackoffRetryLogic retryLogic, int times, Object result) { + return retryLogic.retryAsync(new Supplier>() { int invoked; @Override - public CompletionStage get() - { - if ( invoked < times ) - { + public CompletionStage get() { + if (invoked < times) { invoked++; - return failedFuture( serviceUnavailable() ); + return failedFuture(serviceUnavailable()); } - return completedFuture( result ); + return completedFuture(result); } - } ); + }); } - private Publisher retryRx( ExponentialBackoffRetryLogic retryLogic, int times, Object result ) - { + private Publisher retryRx(ExponentialBackoffRetryLogic retryLogic, int times, Object result) { AtomicInteger invoked = new AtomicInteger(); - return retryLogic.retryRx( Mono.create( e -> { - if ( invoked.get() < times ) - { + return retryLogic.retryRx(Mono.create(e -> { + if (invoked.get() < times) { invoked.getAndIncrement(); - e.error( serviceUnavailable() ); + e.error(serviceUnavailable()); + } else { + e.success(result); } - else - { - e.success( result ); - } - } ) ); + })); } - private static List delaysWithoutJitter( long initialDelay, double multiplier, int count ) - { + private static List delaysWithoutJitter(long initialDelay, double multiplier, int count) { List values = new ArrayList<>(); long delay = initialDelay; - do - { - values.add( delay ); + do { + values.add(delay); delay *= multiplier; - } - while ( --count > 0 ); + } while (--count > 0); return values; } - private static List sleepValues( Clock clockMock, int expectedCount ) throws InterruptedException - { - ArgumentCaptor captor = ArgumentCaptor.forClass( long.class ); - verify( clockMock, times( expectedCount ) ).sleep( captor.capture() ); + private static List sleepValues(Clock clockMock, int expectedCount) throws InterruptedException { + ArgumentCaptor captor = ArgumentCaptor.forClass(long.class); + verify(clockMock, times(expectedCount)).sleep(captor.capture()); return captor.getAllValues(); } - private ExponentialBackoffRetryLogic newRetryLogic( long maxRetryTimeMs, long initialRetryDelayMs, - double multiplier, double jitterFactor, Clock clock ) - { - return new ExponentialBackoffRetryLogic( maxRetryTimeMs, initialRetryDelayMs, multiplier, jitterFactor, - eventExecutor, clock, DEV_NULL_LOGGING ); + private ExponentialBackoffRetryLogic newRetryLogic( + long maxRetryTimeMs, long initialRetryDelayMs, double multiplier, double jitterFactor, Clock clock) { + return new ExponentialBackoffRetryLogic( + maxRetryTimeMs, initialRetryDelayMs, multiplier, jitterFactor, eventExecutor, clock, DEV_NULL_LOGGING); } - private static ServiceUnavailableException serviceUnavailable() - { - return new ServiceUnavailableException( "" ); + private static ServiceUnavailableException serviceUnavailable() { + return new ServiceUnavailableException(""); } - private static RuntimeException clientExceptionWithValidTerminationCause() - { - return new ClientException( "¯\\_(ツ)_/¯", serviceUnavailable() ); + private static RuntimeException clientExceptionWithValidTerminationCause() { + return new ClientException("¯\\_(ツ)_/¯", serviceUnavailable()); } - private static RuntimeException randomClientException() - { - return new ClientException( "Meeh" ); + private static RuntimeException randomClientException() { + return new ClientException("Meeh"); } - private static SessionExpiredException sessionExpired() - { - return new SessionExpiredException( "" ); + private static SessionExpiredException sessionExpired() { + return new SessionExpiredException(""); } - private static TransientException transientException() - { - return new TransientException( "", "" ); + private static TransientException transientException() { + return new TransientException("", ""); } - private static AuthorizationExpiredException authorizationExpiredException() - { - return new AuthorizationExpiredException( "", "" ); + private static AuthorizationExpiredException authorizationExpiredException() { + return new AuthorizationExpiredException("", ""); } - @SuppressWarnings( "unchecked" ) - private static Supplier newWorkMock() - { - return mock( Supplier.class ); + @SuppressWarnings("unchecked") + private static Supplier newWorkMock() { + return mock(Supplier.class); } - private static void assertDelaysApproximatelyEqual( List expectedDelays, List actualDelays, - double delta ) - { - assertEquals( expectedDelays.size(), actualDelays.size() ); + private static void assertDelaysApproximatelyEqual( + List expectedDelays, List actualDelays, double delta) { + assertEquals(expectedDelays.size(), actualDelays.size()); - for ( int i = 0; i < actualDelays.size(); i++ ) - { - double actualValue = actualDelays.get( i ).doubleValue(); - long expectedValue = expectedDelays.get( i ); + for (int i = 0; i < actualDelays.size(); i++) { + double actualValue = actualDelays.get(i).doubleValue(); + long expectedValue = expectedDelays.get(i); - assertThat( actualValue, closeTo( expectedValue, expectedValue * delta ) ); + assertThat(actualValue, closeTo(expectedValue, expectedValue * delta)); } } - private Mono createMono( T result, Exception... errors ) - { + private Mono createMono(T result, Exception... errors) { AtomicInteger executionCount = new AtomicInteger(); - Iterator iterator = Arrays.asList( errors ).iterator(); - return Mono.create( (Consumer>) e -> { - if ( iterator.hasNext() ) - { - e.error( iterator.next() ); - } - else - { - e.success( result ); - } - } ).doOnTerminate( executionCount::getAndIncrement ); + Iterator iterator = Arrays.asList(errors).iterator(); + return Mono.create((Consumer>) e -> { + if (iterator.hasNext()) { + e.error(iterator.next()); + } else { + e.success(result); + } + }) + .doOnTerminate(executionCount::getAndIncrement); } - private static Stream canBeRetriedErrors() - { - return Stream.of( - transientException(), - sessionExpired(), - serviceUnavailable() - ); + private static Stream canBeRetriedErrors() { + return Stream.of(transientException(), sessionExpired(), serviceUnavailable()); } - private static Stream cannotBeRetriedErrors() - { + private static Stream cannotBeRetriedErrors() { return Stream.of( new IllegalStateException(), - new TransientException( "Neo.TransientError.Transaction.Terminated", "" ), - new TransientException( "Neo.TransientError.Transaction.LockClientStopped", "" ) - ); + new TransientException("Neo.TransientError.Transaction.Terminated", ""), + new TransientException("Neo.TransientError.Transaction.LockClientStopped", "")); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/summary/InternalInputPositionTest.java b/driver/src/test/java/org/neo4j/driver/internal/summary/InternalInputPositionTest.java index fa9269976b..d9838f9e9e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/summary/InternalInputPositionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/summary/InternalInputPositionTest.java @@ -18,24 +18,21 @@ */ package org.neo4j.driver.internal.summary; -import org.junit.jupiter.api.Test; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; -class InternalInputPositionTest -{ +import org.junit.jupiter.api.Test; + +class InternalInputPositionTest { @Test - void shouldBehaveAsExpected() - { + void shouldBehaveAsExpected() { // GIVEN, WHEN - InternalInputPosition position = new InternalInputPosition( 0, 2, 1 ); + InternalInputPosition position = new InternalInputPosition(0, 2, 1); // THEN - assertThat( position.offset(), equalTo( 0 ) ); - assertThat( position.column(), equalTo( 1 ) ); - assertThat( position.line(), equalTo( 2 ) ); - assertThat( position.toString(), equalTo( "offset=0, line=2, column=1" ) ); + assertThat(position.offset(), equalTo(0)); + assertThat(position.column(), equalTo(1)); + assertThat(position.line(), equalTo(2)); + assertThat(position.toString(), equalTo("offset=0, line=2, column=1")); } - } diff --git a/driver/src/test/java/org/neo4j/driver/internal/summary/InternalNotificationTest.java b/driver/src/test/java/org/neo4j/driver/internal/summary/InternalNotificationTest.java index d229f78949..06ef2e9ee7 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/summary/InternalNotificationTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/summary/InternalNotificationTest.java @@ -18,71 +18,66 @@ */ package org.neo4j.driver.internal.summary; -import org.junit.jupiter.api.Test; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.nullValue; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.value.IntegerValue; import org.neo4j.driver.internal.value.MapValue; import org.neo4j.driver.internal.value.StringValue; -import org.neo4j.driver.Value; import org.neo4j.driver.summary.InputPosition; import org.neo4j.driver.summary.Notification; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.nullValue; - -class InternalNotificationTest -{ +class InternalNotificationTest { @Test - void shouldHandleNotificationWithPosition() - { + void shouldHandleNotificationWithPosition() { // GIVEN - Map map = new HashMap<>(); - map.put( "description", new StringValue( "A description" ) ); - map.put( "code", new StringValue( "Neo.DummyNotification" ) ); - map.put( "title", new StringValue( "A title" ) ); - map.put( "severity", new StringValue( "WARNING" ) ); - Map position = new HashMap<>(); - position.put( "offset", new IntegerValue( 0 ) ); - position.put( "column", new IntegerValue( 1 ) ); - position.put( "line", new IntegerValue( 2 ) ); - map.put( "position", new MapValue( position ) ); - Value value = new MapValue( map ); + Map map = new HashMap<>(); + map.put("description", new StringValue("A description")); + map.put("code", new StringValue("Neo.DummyNotification")); + map.put("title", new StringValue("A title")); + map.put("severity", new StringValue("WARNING")); + Map position = new HashMap<>(); + position.put("offset", new IntegerValue(0)); + position.put("column", new IntegerValue(1)); + position.put("line", new IntegerValue(2)); + map.put("position", new MapValue(position)); + Value value = new MapValue(map); // WHEN - Notification notification = InternalNotification.VALUE_TO_NOTIFICATION.apply( value ); + Notification notification = InternalNotification.VALUE_TO_NOTIFICATION.apply(value); // THEN - assertThat( notification.description(), equalTo( "A description" ) ); - assertThat( notification.code(), equalTo( "Neo.DummyNotification" ) ); - assertThat( notification.title(), equalTo( "A title" ) ); - assertThat( notification.severity(), equalTo( "WARNING" ) ); + assertThat(notification.description(), equalTo("A description")); + assertThat(notification.code(), equalTo("Neo.DummyNotification")); + assertThat(notification.title(), equalTo("A title")); + assertThat(notification.severity(), equalTo("WARNING")); InputPosition pos = notification.position(); - assertThat( pos.offset(), equalTo( 0 ) ); - assertThat( pos.column(), equalTo( 1 ) ); - assertThat( pos.line(), equalTo( 2 ) ); + assertThat(pos.offset(), equalTo(0)); + assertThat(pos.column(), equalTo(1)); + assertThat(pos.line(), equalTo(2)); } @Test - void shouldHandleNotificationWithoutPosition() - { + void shouldHandleNotificationWithoutPosition() { // GIVEN - Map map = new HashMap<>(); - map.put( "description", new StringValue( "A description" ) ); - map.put( "code", new StringValue( "Neo.DummyNotification" ) ); - map.put( "title", new StringValue( "A title" ) ); - Value value = new MapValue( map ); + Map map = new HashMap<>(); + map.put("description", new StringValue("A description")); + map.put("code", new StringValue("Neo.DummyNotification")); + map.put("title", new StringValue("A title")); + Value value = new MapValue(map); // WHEN - Notification notification = InternalNotification.VALUE_TO_NOTIFICATION.apply( value ); + Notification notification = InternalNotification.VALUE_TO_NOTIFICATION.apply(value); // THEN - assertThat( notification.description(), equalTo( "A description" ) ); - assertThat( notification.code(), equalTo( "Neo.DummyNotification" ) ); - assertThat( notification.title(), equalTo( "A title" ) ); - assertThat( notification.position(), nullValue()); + assertThat(notification.description(), equalTo("A description")); + assertThat(notification.code(), equalTo("Neo.DummyNotification")); + assertThat(notification.title(), equalTo("A title")); + assertThat(notification.position(), nullValue()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/summary/InternalPlanTest.java b/driver/src/test/java/org/neo4j/driver/internal/summary/InternalPlanTest.java index 4897f1c738..56d25ae94f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/summary/InternalPlanTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/summary/InternalPlanTest.java @@ -18,14 +18,6 @@ */ package org.neo4j.driver.internal.summary; -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.List; - -import org.neo4j.driver.Value; -import org.neo4j.driver.summary.Plan; - import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.neo4j.driver.Values.ofValue; @@ -33,69 +25,65 @@ import static org.neo4j.driver.Values.value; import static org.neo4j.driver.Values.values; -class InternalPlanTest -{ +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.summary.Plan; + +class InternalPlanTest { @Test - void shouldConvertFromEmptyMapValue() - { + void shouldConvertFromEmptyMapValue() { // Given - Value value = value( parameters( "operatorType", "X" ) ); + Value value = value(parameters("operatorType", "X")); // When - Plan plan = InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply( value ); + Plan plan = InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply(value); // Then - assertThat( plan.operatorType(), equalTo( "X") ); - assertThat( plan.arguments(), equalTo( parameters().asMap( ofValue()) ) ); - assertThat( plan.identifiers(), equalTo( Collections.emptyList() ) ); - assertThat( plan.children(), equalTo( Collections.emptyList() ) ); + assertThat(plan.operatorType(), equalTo("X")); + assertThat(plan.arguments(), equalTo(parameters().asMap(ofValue()))); + assertThat(plan.identifiers(), equalTo(Collections.emptyList())); + assertThat(plan.children(), equalTo(Collections.emptyList())); } @Test - void shouldConvertFromSimpleMapValue() - { + void shouldConvertFromSimpleMapValue() { // Given - Value value = value( parameters( - "operatorType", "X", - "args", parameters( "a", 1 ), - "identifiers", values(), - "children", values() - ) ); + Value value = value(parameters( + "operatorType", "X", + "args", parameters("a", 1), + "identifiers", values(), + "children", values())); // When - Plan plan = InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply( value ); + Plan plan = InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply(value); // Then - assertThat( plan.operatorType(), equalTo( "X") ); - assertThat( plan.arguments(), equalTo( parameters( "a", 1 ).asMap( ofValue()) ) ); - assertThat( plan.identifiers(), equalTo( Collections.emptyList() ) ); - assertThat( plan.children(), equalTo( Collections.emptyList() ) ); + assertThat(plan.operatorType(), equalTo("X")); + assertThat(plan.arguments(), equalTo(parameters("a", 1).asMap(ofValue()))); + assertThat(plan.identifiers(), equalTo(Collections.emptyList())); + assertThat(plan.children(), equalTo(Collections.emptyList())); } @Test - void shouldConvertFromNestedMapValue() - { + void shouldConvertFromNestedMapValue() { // Given - Value value = value( parameters( + Value value = value(parameters( "operatorType", "X", - "args", parameters( "a", 1 ), + "args", parameters("a", 1), "identifiers", values(), - "children", values( - parameters( - "operatorType", "Y" - ) - ) - ) ); + "children", values(parameters("operatorType", "Y")))); // When - Plan plan = InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply( value ); + Plan plan = InternalPlan.EXPLAIN_PLAN_FROM_VALUE.apply(value); // Then - assertThat( plan.operatorType(), equalTo( "X") ); - assertThat( plan.arguments(), equalTo( parameters( "a", 1 ).asMap( ofValue() ) ) ); - assertThat( plan.identifiers(), equalTo( Collections.emptyList() ) ); + assertThat(plan.operatorType(), equalTo("X")); + assertThat(plan.arguments(), equalTo(parameters("a", 1).asMap(ofValue()))); + assertThat(plan.identifiers(), equalTo(Collections.emptyList())); List children = plan.children(); - assertThat( children.size(), equalTo( 1 ) ); - assertThat( children.get( 0 ).operatorType(), equalTo( "Y" ) ); + assertThat(children.size(), equalTo(1)); + assertThat(children.get(0).operatorType(), equalTo("Y")); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/summary/InternalProfiledPlanTest.java b/driver/src/test/java/org/neo4j/driver/internal/summary/InternalProfiledPlanTest.java index 43c10e1e3d..2d2b57d3f5 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/summary/InternalProfiledPlanTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/summary/InternalProfiledPlanTest.java @@ -18,89 +18,81 @@ */ package org.neo4j.driver.internal.summary; -import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.HashMap; import java.util.Map; - +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.value.FloatValue; import org.neo4j.driver.internal.value.IntegerValue; import org.neo4j.driver.internal.value.ListValue; import org.neo4j.driver.internal.value.MapValue; import org.neo4j.driver.internal.value.StringValue; -import org.neo4j.driver.Value; import org.neo4j.driver.summary.ProfiledPlan; -import static java.util.Arrays.asList; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.hasItem; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class InternalProfiledPlanTest -{ +class InternalProfiledPlanTest { @Test - void shouldHandlePlanWithNoChildren() - { + void shouldHandlePlanWithNoChildren() { // GIVEN - Value value = new MapValue( createPlanMap() ); + Value value = new MapValue(createPlanMap()); // WHEN - ProfiledPlan plan = InternalProfiledPlan.PROFILED_PLAN_FROM_VALUE.apply( value ); + ProfiledPlan plan = InternalProfiledPlan.PROFILED_PLAN_FROM_VALUE.apply(value); // THEN - verifyPlan( plan ); + verifyPlan(plan); } @Test - void shouldHandlePlanWithChildren() - { + void shouldHandlePlanWithChildren() { // GIVEN - Map planMap = createPlanMap(); - planMap.put( "children", new ListValue( new MapValue( createPlanMap() ), new MapValue( createPlanMap() ) ) ); - Value value = new MapValue( planMap ); + Map planMap = createPlanMap(); + planMap.put("children", new ListValue(new MapValue(createPlanMap()), new MapValue(createPlanMap()))); + Value value = new MapValue(planMap); // WHEN - ProfiledPlan plan = InternalProfiledPlan.PROFILED_PLAN_FROM_VALUE.apply( value ); + ProfiledPlan plan = InternalProfiledPlan.PROFILED_PLAN_FROM_VALUE.apply(value); // THEN - for ( ProfiledPlan child : plan.children() ) - { - verifyPlan( child ); + for (ProfiledPlan child : plan.children()) { + verifyPlan(child); } } - private Map createPlanMap() - { - Map map = new HashMap<>(); - map.put( "operatorType", new StringValue( "AwesomeOperator" ) ); - map.put( "rows", new IntegerValue( 1337L ) ); - map.put( "dbHits", new IntegerValue( 42 ) ); - map.put( "pageCacheHits", new IntegerValue( 1234 ) ); - map.put( "pageCacheMisses", new IntegerValue( 3456 ) ); - map.put( "pageCacheHitRatio", new FloatValue( 0.123 ) ); - map.put( "time", new IntegerValue( 999 ) ); - map.put( "identifiers", new ListValue( new StringValue( "n1" ), new StringValue( "n2" ) ) ); - Map args = new HashMap<>(); - args.put( "version", new StringValue( "CYPHER 1337" ) ); - map.put( "args", new MapValue( args ) ); + private Map createPlanMap() { + Map map = new HashMap<>(); + map.put("operatorType", new StringValue("AwesomeOperator")); + map.put("rows", new IntegerValue(1337L)); + map.put("dbHits", new IntegerValue(42)); + map.put("pageCacheHits", new IntegerValue(1234)); + map.put("pageCacheMisses", new IntegerValue(3456)); + map.put("pageCacheHitRatio", new FloatValue(0.123)); + map.put("time", new IntegerValue(999)); + map.put("identifiers", new ListValue(new StringValue("n1"), new StringValue("n2"))); + Map args = new HashMap<>(); + args.put("version", new StringValue("CYPHER 1337")); + map.put("args", new MapValue(args)); return map; } - private void verifyPlan( ProfiledPlan plan ) - { - assertThat( plan.dbHits(), equalTo( 42L ) ); - assertThat( plan.records(), equalTo( 1337L ) ); - assertTrue( plan.hasPageCacheStats() ); - assertThat( plan.pageCacheHits(), equalTo( 1234L ) ); - assertThat( plan.pageCacheMisses(), equalTo( 3456L ) ); - assertThat( plan.pageCacheHitRatio(), equalTo( 0.123 ) ); - assertThat( plan.time(), equalTo( 999L ) ); - assertThat( plan.operatorType(), equalTo( "AwesomeOperator" ) ); - assertThat( plan.identifiers(), equalTo( asList( "n1", "n2" ) ) ); - assertThat( plan.arguments().values(), hasItem( new StringValue( "CYPHER 1337" ) ) ); - assertThat( plan.children(), empty() ); + private void verifyPlan(ProfiledPlan plan) { + assertThat(plan.dbHits(), equalTo(42L)); + assertThat(plan.records(), equalTo(1337L)); + assertTrue(plan.hasPageCacheStats()); + assertThat(plan.pageCacheHits(), equalTo(1234L)); + assertThat(plan.pageCacheMisses(), equalTo(3456L)); + assertThat(plan.pageCacheHitRatio(), equalTo(0.123)); + assertThat(plan.time(), equalTo(999L)); + assertThat(plan.operatorType(), equalTo("AwesomeOperator")); + assertThat(plan.identifiers(), equalTo(asList("n1", "n2"))); + assertThat(plan.arguments().values(), hasItem(new StringValue("CYPHER 1337"))); + assertThat(plan.children(), empty()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/BookmarkUtil.java b/driver/src/test/java/org/neo4j/driver/internal/util/BookmarkUtil.java index e042f0eadf..2985aef268 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/BookmarkUtil.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/BookmarkUtil.java @@ -18,14 +18,6 @@ */ package org.neo4j.driver.internal.util; -import org.hamcrest.Matcher; - -import java.util.HashSet; -import java.util.List; - -import org.neo4j.driver.Bookmark; -import org.neo4j.driver.internal.InternalBookmark; - import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.core.IsInstanceOf.instanceOf; @@ -36,75 +28,73 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.neo4j.driver.internal.util.Iterables.asList; -public class BookmarkUtil -{ +import java.util.HashSet; +import java.util.List; +import org.hamcrest.Matcher; +import org.neo4j.driver.Bookmark; +import org.neo4j.driver.internal.InternalBookmark; + +public class BookmarkUtil { /** * Bookmark is empty. */ - public static void assertBookmarkIsEmpty( Bookmark bookmark ) - { - assertNotNull( bookmark ); - assertThat( bookmark, instanceOf( InternalBookmark.class ) ); - assertTrue( ((InternalBookmark) bookmark).isEmpty() ); + public static void assertBookmarkIsEmpty(Bookmark bookmark) { + assertNotNull(bookmark); + assertThat(bookmark, instanceOf(InternalBookmark.class)); + assertTrue(((InternalBookmark) bookmark).isEmpty()); } /** * Bookmark is not empty but I do not care what value it has. */ - public static void assertBookmarkIsNotEmpty( Bookmark bookmark ) - { - assertNotNull( bookmark ); - assertThat( bookmark, instanceOf( InternalBookmark.class ) ); - assertFalse( ((InternalBookmark) bookmark).isEmpty() ); + public static void assertBookmarkIsNotEmpty(Bookmark bookmark) { + assertNotNull(bookmark); + assertThat(bookmark, instanceOf(InternalBookmark.class)); + assertFalse(((InternalBookmark) bookmark).isEmpty()); } /** * Bookmark contains one single value */ - public static void assertBookmarkContainsSingleValue( Bookmark bookmark ) - { - assertBookmarkContainsSingleValue( bookmark, notNullValue( String.class ) ); + public static void assertBookmarkContainsSingleValue(Bookmark bookmark) { + assertBookmarkContainsSingleValue(bookmark, notNullValue(String.class)); } /** * Bookmark contains one single value and the value matches the requirement set by matcher. */ - public static void assertBookmarkContainsSingleValue( Bookmark bookmark, Matcher matcher ) - { - assertNotNull( bookmark ); - assertThat( bookmark, instanceOf( InternalBookmark.class ) ); + public static void assertBookmarkContainsSingleValue(Bookmark bookmark, Matcher matcher) { + assertNotNull(bookmark); + assertThat(bookmark, instanceOf(InternalBookmark.class)); - List values = asList( ((InternalBookmark) bookmark).values() ); - assertThat( values.size(), equalTo( 1 ) ); - assertThat( values.get( 0 ), matcher ); + List values = asList(((InternalBookmark) bookmark).values()); + assertThat(values.size(), equalTo(1)); + assertThat(values.get(0), matcher); } /** * Bookmark contains values matching the requirement set by matcher. */ - public static void assertBookmarkContainsValues( Bookmark bookmark, Matcher> matcher ) - { - assertNotNull( bookmark ); - assertThat( bookmark, instanceOf( InternalBookmark.class ) ); + public static void assertBookmarkContainsValues(Bookmark bookmark, Matcher> matcher) { + assertNotNull(bookmark); + assertThat(bookmark, instanceOf(InternalBookmark.class)); - List values = asList( ((InternalBookmark) bookmark).values() ); - assertThat( values, matcher ); + List values = asList(((InternalBookmark) bookmark).values()); + assertThat(values, matcher); } /** * Each bookmark contains one single value and the values are all different from each other. */ - public static void assertBookmarksContainsSingleUniqueValues( Bookmark... bookmarks ) - { + public static void assertBookmarksContainsSingleUniqueValues(Bookmark... bookmarks) { int count = bookmarks.length; HashSet bookmarkStrings = new HashSet<>(); - for ( Bookmark bookmark : bookmarks ) - { - assertBookmarkContainsSingleValue( bookmark ); - List values = asList( ((InternalBookmark) bookmark).values() ); - bookmarkStrings.addAll( values ); + for (Bookmark bookmark : bookmarks) { + assertBookmarkContainsSingleValue(bookmark); + List values = asList(((InternalBookmark) bookmark).values()); + bookmarkStrings.addAll(values); } - assertEquals( count, bookmarkStrings.size() ); + assertEquals(count, bookmarkStrings.size()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ClusterCompositionUtil.java b/driver/src/test/java/org/neo4j/driver/internal/util/ClusterCompositionUtil.java index aabbfb44bd..1984a2ccf5 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ClusterCompositionUtil.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ClusterCompositionUtil.java @@ -23,52 +23,45 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.cluster.ClusterComposition; -public final class ClusterCompositionUtil -{ - private ClusterCompositionUtil() - { - } +public final class ClusterCompositionUtil { + private ClusterCompositionUtil() {} - public static final long NEVER_EXPIRE = System.currentTimeMillis() + TimeUnit.HOURS.toMillis( 1 ); + public static final long NEVER_EXPIRE = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1); - public static final BoltServerAddress A = new BoltServerAddress( "192.168.100.100:11" ); - public static final BoltServerAddress B = new BoltServerAddress( "192.168.100.101:22" ); - public static final BoltServerAddress C = new BoltServerAddress( "192.168.100.102:33" ); - public static final BoltServerAddress D = new BoltServerAddress( "192.168.100.103:44" ); - public static final BoltServerAddress E = new BoltServerAddress( "192.168.100.104:55" ); - public static final BoltServerAddress F = new BoltServerAddress( "192.168.100.105:66" ); + public static final BoltServerAddress A = new BoltServerAddress("192.168.100.100:11"); + public static final BoltServerAddress B = new BoltServerAddress("192.168.100.101:22"); + public static final BoltServerAddress C = new BoltServerAddress("192.168.100.102:33"); + public static final BoltServerAddress D = new BoltServerAddress("192.168.100.103:44"); + public static final BoltServerAddress E = new BoltServerAddress("192.168.100.104:55"); + public static final BoltServerAddress F = new BoltServerAddress("192.168.100.105:66"); public static final List EMPTY = new ArrayList<>(); @SafeVarargs - public static ClusterComposition createClusterComposition( List... servers ) - { - return createClusterComposition( NEVER_EXPIRE, servers ); + public static ClusterComposition createClusterComposition(List... servers) { + return createClusterComposition(NEVER_EXPIRE, servers); } @SafeVarargs - public static ClusterComposition createClusterComposition( long expirationTimestamp, List... - servers ) - { + public static ClusterComposition createClusterComposition( + long expirationTimestamp, List... servers) { Set routers = new LinkedHashSet<>(); Set writers = new LinkedHashSet<>(); Set readers = new LinkedHashSet<>(); - switch( servers.length ) - { - case 3: - readers.addAll( servers[2] ); - // no break on purpose - case 2: - writers.addAll( servers[1] ); - // no break on purpose - case 1: - routers.addAll( servers[0] ); + switch (servers.length) { + case 3: + readers.addAll(servers[2]); + // no break on purpose + case 2: + writers.addAll(servers[1]); + // no break on purpose + case 1: + routers.addAll(servers[0]); } - return new ClusterComposition( expirationTimestamp, readers, writers, routers, null ); + return new ClusterComposition(expirationTimestamp, readers, writers, routers, null); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/DisabledOnNeo4jWith.java b/driver/src/test/java/org/neo4j/driver/internal/util/DisabledOnNeo4jWith.java index 4973c34a3f..a12642a34b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/DisabledOnNeo4jWith.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/DisabledOnNeo4jWith.java @@ -18,19 +18,17 @@ */ package org.neo4j.driver.internal.util; -import org.junit.jupiter.api.extension.ExtendWith; - import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ExtendWith; -@Target( {ElementType.TYPE, ElementType.METHOD} ) -@Retention( RetentionPolicy.RUNTIME ) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) @Documented -@ExtendWith( Neo4jWithFeatureCondition.class ) -public @interface DisabledOnNeo4jWith -{ +@ExtendWith(Neo4jWithFeatureCondition.class) +public @interface DisabledOnNeo4jWith { Neo4jFeature value(); } 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 62bee886e0..8a3f07fccc 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 @@ -20,18 +20,15 @@ import org.neo4j.driver.internal.DriverFactory; -public class DriverFactoryWithClock extends DriverFactory -{ +public class DriverFactoryWithClock extends DriverFactory { private final Clock clock; - public DriverFactoryWithClock( Clock clock ) - { + public DriverFactoryWithClock(Clock clock) { this.clock = clock; } @Override - protected Clock createClock() - { + protected Clock createClock() { return clock; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithFixedRetryLogic.java b/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithFixedRetryLogic.java index ae6fe70486..dec57cbafd 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithFixedRetryLogic.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithFixedRetryLogic.java @@ -19,25 +19,21 @@ package org.neo4j.driver.internal.util; import io.netty.util.concurrent.EventExecutorGroup; - +import org.neo4j.driver.Logging; import org.neo4j.driver.internal.DriverFactory; import org.neo4j.driver.internal.retry.RetryLogic; import org.neo4j.driver.internal.retry.RetrySettings; -import org.neo4j.driver.Logging; -public class DriverFactoryWithFixedRetryLogic extends DriverFactory -{ +public class DriverFactoryWithFixedRetryLogic extends DriverFactory { private final int retryCount; - public DriverFactoryWithFixedRetryLogic( int retryCount ) - { + public DriverFactoryWithFixedRetryLogic(int retryCount) { this.retryCount = retryCount; } @Override - protected RetryLogic createRetryLogic( RetrySettings settings, EventExecutorGroup eventExecutorGroup, - Logging logging ) - { - return new FixedRetryLogic( retryCount ); + protected RetryLogic createRetryLogic( + RetrySettings settings, EventExecutorGroup eventExecutorGroup, Logging logging) { + return new FixedRetryLogic(retryCount); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/EnabledOnNeo4jWith.java b/driver/src/test/java/org/neo4j/driver/internal/util/EnabledOnNeo4jWith.java index 3229f0d1c4..b4054c5c85 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/EnabledOnNeo4jWith.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/EnabledOnNeo4jWith.java @@ -18,20 +18,18 @@ */ package org.neo4j.driver.internal.util; -import org.junit.jupiter.api.extension.ExtendWith; - import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ExtendWith; -@Target( {ElementType.TYPE, ElementType.METHOD} ) -@Retention( RetentionPolicy.RUNTIME ) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) @Documented -@ExtendWith( Neo4jWithFeatureCondition.class ) -public @interface EnabledOnNeo4jWith -{ +@ExtendWith(Neo4jWithFeatureCondition.class) +public @interface EnabledOnNeo4jWith { Neo4jFeature value(); Neo4jEdition edition() default Neo4jEdition.UNDEFINED; diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ErrorUtilTest.java b/driver/src/test/java/org/neo4j/driver/internal/util/ErrorUtilTest.java index 25d0c5caae..bf2ca2d8e7 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ErrorUtilTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ErrorUtilTest.java @@ -18,19 +18,6 @@ */ package org.neo4j.driver.internal.util; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import org.neo4j.driver.exceptions.AuthenticationException; -import org.neo4j.driver.exceptions.AuthorizationExpiredException; -import org.neo4j.driver.exceptions.ClientException; -import org.neo4j.driver.exceptions.DatabaseException; -import org.neo4j.driver.exceptions.Neo4jException; -import org.neo4j.driver.exceptions.ServiceUnavailableException; -import org.neo4j.driver.exceptions.TokenExpiredException; -import org.neo4j.driver.exceptions.TransientException; - import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.startsWith; @@ -42,151 +29,146 @@ import static org.neo4j.driver.internal.util.ErrorUtil.newConnectionTerminatedError; import static org.neo4j.driver.internal.util.ErrorUtil.newNeo4jError; -class ErrorUtilTest -{ +import java.io.IOException; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.AuthenticationException; +import org.neo4j.driver.exceptions.AuthorizationExpiredException; +import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.exceptions.DatabaseException; +import org.neo4j.driver.exceptions.Neo4jException; +import org.neo4j.driver.exceptions.ServiceUnavailableException; +import org.neo4j.driver.exceptions.TokenExpiredException; +import org.neo4j.driver.exceptions.TransientException; + +class ErrorUtilTest { @Test - void shouldCreateAuthenticationException() - { + void shouldCreateAuthenticationException() { String code = "Neo.ClientError.Security.Unauthorized"; String message = "Wrong credentials"; - Neo4jException error = newNeo4jError( code, message ); + Neo4jException error = newNeo4jError(code, message); - assertThat( error, instanceOf( AuthenticationException.class ) ); - assertEquals( code, error.code() ); - assertEquals( message, error.getMessage() ); + assertThat(error, instanceOf(AuthenticationException.class)); + assertEquals(code, error.code()); + assertEquals(message, error.getMessage()); } @Test - void shouldCreateClientException() - { + void shouldCreateClientException() { String code = "Neo.ClientError.Transaction.InvalidBookmark"; String message = "Wrong bookmark"; - Neo4jException error = newNeo4jError( code, message ); + Neo4jException error = newNeo4jError(code, message); - assertThat( error, instanceOf( ClientException.class ) ); - assertEquals( code, error.code() ); - assertEquals( message, error.getMessage() ); + assertThat(error, instanceOf(ClientException.class)); + assertEquals(code, error.code()); + assertEquals(message, error.getMessage()); } @Test - void shouldCreateTransientException() - { + void shouldCreateTransientException() { String code = "Neo.TransientError.Transaction.DeadlockDetected"; String message = "Deadlock occurred"; - Neo4jException error = newNeo4jError( code, message ); + Neo4jException error = newNeo4jError(code, message); - assertThat( error, instanceOf( TransientException.class ) ); - assertEquals( code, error.code() ); - assertEquals( message, error.getMessage() ); + assertThat(error, instanceOf(TransientException.class)); + assertEquals(code, error.code()); + assertEquals(message, error.getMessage()); } @Test - void shouldCreateDatabaseException() - { + void shouldCreateDatabaseException() { String code = "Neo.DatabaseError.Transaction.TransactionLogError"; String message = "Failed to write the transaction log"; - Neo4jException error = newNeo4jError( code, message ); + Neo4jException error = newNeo4jError(code, message); - assertThat( error, instanceOf( DatabaseException.class ) ); - assertEquals( code, error.code() ); - assertEquals( message, error.getMessage() ); + assertThat(error, instanceOf(DatabaseException.class)); + assertEquals(code, error.code()); + assertEquals(message, error.getMessage()); } @Test - void shouldCreateDatabaseExceptionWhenErrorCodeIsWrong() - { + void shouldCreateDatabaseExceptionWhenErrorCodeIsWrong() { String code = "WrongErrorCode"; String message = "Some really strange error"; - Neo4jException error = newNeo4jError( code, message ); + Neo4jException error = newNeo4jError(code, message); - assertThat( error, instanceOf( DatabaseException.class ) ); - assertEquals( code, error.code() ); - assertEquals( message, error.getMessage() ); + assertThat(error, instanceOf(DatabaseException.class)); + assertEquals(code, error.code()); + assertEquals(message, error.getMessage()); } @Test - void shouldTreatNotNeo4jExceptionAsFatal() - { - assertTrue( isFatal( new IOException( "IO failed!" ) ) ); + void shouldTreatNotNeo4jExceptionAsFatal() { + assertTrue(isFatal(new IOException("IO failed!"))); } @Test - void shouldTreatProtocolErrorAsFatal() - { - assertTrue( isFatal( new ClientException( "Neo.ClientError.Request.Invalid", "Illegal request" ) ) ); - assertTrue( isFatal( new ClientException( "Neo.ClientError.Request.InvalidFormat", "Wrong format" ) ) ); - assertTrue( isFatal( new ClientException( "Neo.ClientError.Request.TransactionRequired", "No tx!" ) ) ); + void shouldTreatProtocolErrorAsFatal() { + assertTrue(isFatal(new ClientException("Neo.ClientError.Request.Invalid", "Illegal request"))); + assertTrue(isFatal(new ClientException("Neo.ClientError.Request.InvalidFormat", "Wrong format"))); + assertTrue(isFatal(new ClientException("Neo.ClientError.Request.TransactionRequired", "No tx!"))); } @Test - void shouldTreatAuthenticationExceptionAsNonFatal() - { - assertFalse( isFatal( new AuthenticationException( "Neo.ClientError.Security.Unauthorized", "" ) ) ); + void shouldTreatAuthenticationExceptionAsNonFatal() { + assertFalse(isFatal(new AuthenticationException("Neo.ClientError.Security.Unauthorized", ""))); } @Test - void shouldTreatClientExceptionAsNonFatal() - { - assertFalse( isFatal( new ClientException( "Neo.ClientError.Transaction.ConstraintsChanged", "" ) ) ); + void shouldTreatClientExceptionAsNonFatal() { + assertFalse(isFatal(new ClientException("Neo.ClientError.Transaction.ConstraintsChanged", ""))); } @Test - void shouldTreatDatabaseExceptionAsFatal() - { - assertTrue( isFatal( new ClientException( "Neo.DatabaseError.Schema.ConstraintCreationFailed", "" ) ) ); + void shouldTreatDatabaseExceptionAsFatal() { + assertTrue(isFatal(new ClientException("Neo.DatabaseError.Schema.ConstraintCreationFailed", ""))); } @Test - void shouldCreateConnectionTerminatedError() - { + void shouldCreateConnectionTerminatedError() { ServiceUnavailableException error = newConnectionTerminatedError(); - assertThat( error.getMessage(), startsWith( "Connection to the database terminated" ) ); + assertThat(error.getMessage(), startsWith("Connection to the database terminated")); } @Test - void shouldCreateConnectionTerminatedErrorWithNullReason() - { - ServiceUnavailableException error = newConnectionTerminatedError( null ); - assertThat( error.getMessage(), startsWith( "Connection to the database terminated" ) ); + void shouldCreateConnectionTerminatedErrorWithNullReason() { + ServiceUnavailableException error = newConnectionTerminatedError(null); + assertThat(error.getMessage(), startsWith("Connection to the database terminated")); } @Test - void shouldCreateConnectionTerminatedErrorWithReason() - { + void shouldCreateConnectionTerminatedErrorWithReason() { String reason = "Thread interrupted"; - ServiceUnavailableException error = newConnectionTerminatedError( reason ); - assertThat( error.getMessage(), startsWith( "Connection to the database terminated" ) ); - assertThat( error.getMessage(), containsString( reason ) ); + ServiceUnavailableException error = newConnectionTerminatedError(reason); + assertThat(error.getMessage(), startsWith("Connection to the database terminated")); + assertThat(error.getMessage(), containsString(reason)); } @Test - void shouldCreateAuthorizationExpiredException() - { + void shouldCreateAuthorizationExpiredException() { String code = "Neo.ClientError.Security.AuthorizationExpired"; String message = "Expired authorization info"; - Neo4jException error = newNeo4jError( code, message ); + Neo4jException error = newNeo4jError(code, message); - assertThat( error, instanceOf( AuthorizationExpiredException.class ) ); - assertEquals( code, error.code() ); - assertEquals( message, error.getMessage() ); + assertThat(error, instanceOf(AuthorizationExpiredException.class)); + assertEquals(code, error.code()); + assertEquals(message, error.getMessage()); } @Test - void shouldCreateTokenExpiredException() - { + void shouldCreateTokenExpiredException() { String code = "Neo.ClientError.Security.TokenExpired"; String message = "message"; - Neo4jException error = newNeo4jError( code, message ); + Neo4jException error = newNeo4jError(code, message); - assertThat( error, instanceOf( TokenExpiredException.class ) ); - assertEquals( code, error.code() ); - assertEquals( message, error.getMessage() ); + assertThat(error, instanceOf(TokenExpiredException.class)); + assertEquals(code, error.code()); + assertEquals(message, error.getMessage()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/FailingConnectionDriverFactory.java b/driver/src/test/java/org/neo4j/driver/internal/util/FailingConnectionDriverFactory.java index a9790538a9..986411d26e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/FailingConnectionDriverFactory.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/FailingConnectionDriverFactory.java @@ -19,236 +19,201 @@ package org.neo4j.driver.internal.util; import io.netty.bootstrap.Bootstrap; - import java.util.Set; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.Config; -import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DriverFactory; import org.neo4j.driver.internal.cluster.RoutingContext; import org.neo4j.driver.internal.messaging.BoltProtocol; import org.neo4j.driver.internal.messaging.Message; +import org.neo4j.driver.internal.metrics.MetricsProvider; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.net.ServerAddress; -public class FailingConnectionDriverFactory extends DriverFactory -{ +public class FailingConnectionDriverFactory extends DriverFactory { private final AtomicReference nextRunFailure = new AtomicReference<>(); @Override - protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, - MetricsProvider metricsProvider, Config config, boolean ownsEventLoopGroup, - RoutingContext routingContext ) - { - ConnectionPool pool = super.createConnectionPool( authToken, securityPlan, bootstrap, metricsProvider, config, - ownsEventLoopGroup, routingContext ); - return new ConnectionPoolWithFailingConnections( pool, nextRunFailure ); + protected ConnectionPool createConnectionPool( + AuthToken authToken, + SecurityPlan securityPlan, + Bootstrap bootstrap, + MetricsProvider metricsProvider, + Config config, + boolean ownsEventLoopGroup, + RoutingContext routingContext) { + ConnectionPool pool = super.createConnectionPool( + authToken, securityPlan, bootstrap, metricsProvider, config, ownsEventLoopGroup, routingContext); + return new ConnectionPoolWithFailingConnections(pool, nextRunFailure); } - public void setNextRunFailure( Throwable failure ) - { - nextRunFailure.set( failure ); + public void setNextRunFailure(Throwable failure) { + nextRunFailure.set(failure); } - private static class ConnectionPoolWithFailingConnections implements ConnectionPool - { + private static class ConnectionPoolWithFailingConnections implements ConnectionPool { final ConnectionPool delegate; final AtomicReference nextRunFailure; - ConnectionPoolWithFailingConnections( ConnectionPool delegate, AtomicReference nextRunFailure ) - { + ConnectionPoolWithFailingConnections(ConnectionPool delegate, AtomicReference nextRunFailure) { this.delegate = delegate; this.nextRunFailure = nextRunFailure; } @Override - public CompletionStage acquire( BoltServerAddress address ) - { - return delegate.acquire( address ) - .thenApply( connection -> new FailingConnection( connection, nextRunFailure ) ); + public CompletionStage acquire(BoltServerAddress address) { + return delegate.acquire(address).thenApply(connection -> new FailingConnection(connection, nextRunFailure)); } @Override - public void retainAll( Set addressesToRetain ) - { - delegate.retainAll( addressesToRetain ); + public void retainAll(Set addressesToRetain) { + delegate.retainAll(addressesToRetain); } @Override - public int inUseConnections( ServerAddress address ) - { - return delegate.inUseConnections( address ); + public int inUseConnections(ServerAddress address) { + return delegate.inUseConnections(address); } @Override - public int idleConnections( ServerAddress address ) - { - return delegate.idleConnections( address ); + public int idleConnections(ServerAddress address) { + return delegate.idleConnections(address); } @Override - public CompletionStage close() - { + public CompletionStage close() { return delegate.close(); } @Override - public boolean isOpen( BoltServerAddress address ) - { - return delegate.isOpen( address ); + public boolean isOpen(BoltServerAddress address) { + return delegate.isOpen(address); } } - private static class FailingConnection implements Connection - { + private static class FailingConnection implements Connection { final Connection delegate; final AtomicReference nextRunFailure; - final AtomicInteger count = new AtomicInteger( 2 ); // one failure for run, one failure for pull + final AtomicInteger count = new AtomicInteger(2); // one failure for run, one failure for pull - FailingConnection( Connection delegate, AtomicReference nextRunFailure ) - { + FailingConnection(Connection delegate, AtomicReference nextRunFailure) { this.delegate = delegate; this.nextRunFailure = nextRunFailure; } @Override - public boolean isOpen() - { + public boolean isOpen() { return delegate.isOpen(); } @Override - public void enableAutoRead() - { + public void enableAutoRead() { delegate.enableAutoRead(); } @Override - public void disableAutoRead() - { + public void disableAutoRead() { delegate.disableAutoRead(); } @Override - public void write( Message message, ResponseHandler handler ) - { - if ( tryFail( handler, null ) ) - { + public void write(Message message, ResponseHandler handler) { + if (tryFail(handler, null)) { return; } - delegate.write( message, handler ); + delegate.write(message, handler); } @Override - public void write( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ) - { - if ( tryFail( handler1, handler2 ) ) - { + public void write(Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2) { + if (tryFail(handler1, handler2)) { return; } - delegate.write( message1, handler1, message2, handler2 ); + delegate.write(message1, handler1, message2, handler2); } @Override - public void writeAndFlush( Message message, ResponseHandler handler ) - { - if ( tryFail( handler, null ) ) - { + public void writeAndFlush(Message message, ResponseHandler handler) { + if (tryFail(handler, null)) { return; } - delegate.writeAndFlush( message, handler ); + delegate.writeAndFlush(message, handler); } @Override - public void writeAndFlush( Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2 ) - { - if ( tryFail( handler1, handler2 ) ) - { + public void writeAndFlush( + Message message1, ResponseHandler handler1, Message message2, ResponseHandler handler2) { + if (tryFail(handler1, handler2)) { return; } - delegate.writeAndFlush( message1, handler1, message2, handler2 ); + delegate.writeAndFlush(message1, handler1, message2, handler2); } @Override - public CompletionStage reset() - { + public CompletionStage reset() { return delegate.reset(); } @Override - public CompletionStage release() - { + public CompletionStage release() { return delegate.release(); } @Override - public void terminateAndRelease( String reason ) - { - delegate.terminateAndRelease( reason ); + public void terminateAndRelease(String reason) { + delegate.terminateAndRelease(reason); } @Override - public String serverAgent() - { + public String serverAgent() { return delegate.serverAgent(); } @Override - public BoltServerAddress serverAddress() - { + public BoltServerAddress serverAddress() { return delegate.serverAddress(); } @Override - public ServerVersion serverVersion() - { + public ServerVersion serverVersion() { return delegate.serverVersion(); } @Override - public BoltProtocol protocol() - { + public BoltProtocol protocol() { return delegate.protocol(); } @Override - public void flush() - { - if ( tryFail( null, null ) ) - { + public void flush() { + if (tryFail(null, null)) { return; } delegate.flush(); } - private boolean tryFail( ResponseHandler handler1, ResponseHandler handler2 ) - { - Throwable failure = nextRunFailure.getAndSet( null ); - if ( failure != null ) - { + private boolean tryFail(ResponseHandler handler1, ResponseHandler handler2) { + Throwable failure = nextRunFailure.getAndSet(null); + if (failure != null) { int reportCount = count.get(); - if ( handler1 != null ) - { - handler1.onFailure( failure ); + if (handler1 != null) { + handler1.onFailure(failure); reportCount = count.decrementAndGet(); } - if ( handler2 != null ) - { - handler2.onFailure( failure ); + if (handler2 != null) { + handler2.onFailure(failure); reportCount = count.decrementAndGet(); } - if ( reportCount > 0 ) - { - nextRunFailure.compareAndSet( null, failure ); + if (reportCount > 0) { + nextRunFailure.compareAndSet(null, failure); } return true; } @@ -256,4 +221,3 @@ private boolean tryFail( ResponseHandler handler1, ResponseHandler handler2 ) } } } - diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/FailingMessageFormat.java b/driver/src/test/java/org/neo4j/driver/internal/util/FailingMessageFormat.java index 07be92cd38..a4fbcec3b8 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/FailingMessageFormat.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/FailingMessageFormat.java @@ -19,10 +19,8 @@ package org.neo4j.driver.internal.util; import io.netty.util.internal.PlatformDependent; - import java.io.IOException; import java.util.concurrent.atomic.AtomicReference; - import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.ResponseMessageHandler; @@ -30,103 +28,85 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackOutput; -public class FailingMessageFormat implements MessageFormat -{ +public class FailingMessageFormat implements MessageFormat { private final MessageFormat delegate; private final AtomicReference writerThrowableRef = new AtomicReference<>(); private final AtomicReference readerThrowableRef = new AtomicReference<>(); private final AtomicReference readerFailureRef = new AtomicReference<>(); - public FailingMessageFormat( MessageFormat delegate ) - { + public FailingMessageFormat(MessageFormat delegate) { this.delegate = delegate; } - public void makeWriterThrow( Throwable error ) - { - writerThrowableRef.set( error ); + public void makeWriterThrow(Throwable error) { + writerThrowableRef.set(error); } - public void makeReaderThrow( Throwable error ) - { - readerThrowableRef.set( error ); + public void makeReaderThrow(Throwable error) { + readerThrowableRef.set(error); } - public void makeReaderFail( FailureMessage failureMsg ) - { - readerFailureRef.set( failureMsg ); + public void makeReaderFail(FailureMessage failureMsg) { + readerFailureRef.set(failureMsg); } @Override - public Writer newWriter( PackOutput output ) - { - return new ThrowingWriter( delegate.newWriter( output ), writerThrowableRef ); + public Writer newWriter(PackOutput output) { + return new ThrowingWriter(delegate.newWriter(output), writerThrowableRef); } @Override - public Reader newReader( PackInput input ) - { - return new ThrowingReader( delegate.newReader( input ), readerThrowableRef, readerFailureRef ); + public Reader newReader(PackInput input) { + return new ThrowingReader(delegate.newReader(input), readerThrowableRef, readerFailureRef); } - private static class ThrowingWriter implements MessageFormat.Writer - { + private static class ThrowingWriter implements MessageFormat.Writer { final MessageFormat.Writer delegate; final AtomicReference throwableRef; - ThrowingWriter( Writer delegate, AtomicReference throwableRef ) - { + ThrowingWriter(Writer delegate, AtomicReference throwableRef) { this.delegate = delegate; this.throwableRef = throwableRef; } @Override - public void write( Message msg ) throws IOException - { - Throwable error = throwableRef.getAndSet( null ); - if ( error != null ) - { - PlatformDependent.throwException( error ); - } - else - { - delegate.write( msg ); + public void write(Message msg) throws IOException { + Throwable error = throwableRef.getAndSet(null); + if (error != null) { + PlatformDependent.throwException(error); + } else { + delegate.write(msg); } } } - private static class ThrowingReader implements MessageFormat.Reader - { + private static class ThrowingReader implements MessageFormat.Reader { final MessageFormat.Reader delegate; final AtomicReference throwableRef; final AtomicReference failureRef; - ThrowingReader( Reader delegate, AtomicReference throwableRef, - AtomicReference failureRef ) - { + ThrowingReader( + Reader delegate, AtomicReference throwableRef, AtomicReference failureRef) { this.delegate = delegate; this.throwableRef = throwableRef; this.failureRef = failureRef; } @Override - public void read( ResponseMessageHandler handler ) throws IOException - { - Throwable error = throwableRef.getAndSet( null ); - if ( error != null ) - { - PlatformDependent.throwException( error ); + public void read(ResponseMessageHandler handler) throws IOException { + Throwable error = throwableRef.getAndSet(null); + if (error != null) { + PlatformDependent.throwException(error); return; } - FailureMessage failureMsg = failureRef.getAndSet( null ); - if ( failureMsg != null ) - { - handler.handleFailureMessage( failureMsg.code(), failureMsg.message() ); + FailureMessage failureMsg = failureRef.getAndSet(null); + if (failureMsg != null) { + handler.handleFailureMessage(failureMsg.code(), failureMsg.message()); return; } - delegate.read( handler ); + delegate.read(handler); } } } 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 feefdee141..e01a99841b 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 @@ -23,85 +23,67 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.LockSupport; -public class FakeClock implements Clock -{ +public class FakeClock implements Clock { private final AtomicLong timestamp = new AtomicLong(); private final PriorityBlockingQueue threads; - public FakeClock() - { - this( false ); + public FakeClock() { + this(false); } - private FakeClock( boolean progressOnSleep ) - { + private FakeClock(boolean progressOnSleep) { this.threads = progressOnSleep ? null : new PriorityBlockingQueue(); } @Override - public long millis() - { + public long millis() { return timestamp.get(); } @Override - public void sleep( long millis ) - { - if ( millis <= 0 ) - { + public void sleep(long millis) { + if (millis <= 0) { return; } long target = timestamp.get() + millis; - if ( threads == null ) - { - progress( millis ); - } - else - { + 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 ); + 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 ) ); + LockSupport.parkNanos(this, TimeUnit.MILLISECONDS.toNanos(millis)); } } } - public void progress( long millis ) - { - if ( millis < 0 ) - { - throw new IllegalArgumentException( "time can only progress forwards" ); + public void progress(long millis) { + if (millis < 0) { + throw new IllegalArgumentException("time can only progress forwards"); } - timestamp.addAndGet( millis ); - if ( threads != null ) - { + 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 ); + for (WaitingThread thread; (thread = threads.peek()) != null; ) { + if (thread.timestamp < timestamp.get()) { + threads.remove(thread); + LockSupport.unpark(thread.thread); } } } } - private static class WaitingThread - { + private static class WaitingThread { final Thread thread; final long timestamp; - private WaitingThread( Thread thread, 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 70c9a39ee1..13dcd22584 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 @@ -18,32 +18,27 @@ */ package org.neo4j.driver.internal.util; -import io.netty.util.concurrent.EventExecutorGroup; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import io.netty.util.concurrent.EventExecutorGroup; import org.neo4j.driver.internal.retry.ExponentialBackoffRetryLogic; import org.neo4j.driver.internal.retry.RetrySettings; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; - -public class FixedRetryLogic extends ExponentialBackoffRetryLogic -{ +public class FixedRetryLogic extends ExponentialBackoffRetryLogic { private final int retryCount; private int invocationCount; - public FixedRetryLogic( int retryCount ) - { - this( retryCount, new ImmediateSchedulingEventExecutor() ); + public FixedRetryLogic(int retryCount) { + this(retryCount, new ImmediateSchedulingEventExecutor()); } - public FixedRetryLogic( int retryCount, EventExecutorGroup eventExecutorGroup ) - { - super( new RetrySettings( Long.MAX_VALUE ), eventExecutorGroup, new SleeplessClock(), DEV_NULL_LOGGING ); + public FixedRetryLogic(int retryCount, EventExecutorGroup eventExecutorGroup) { + super(new RetrySettings(Long.MAX_VALUE), eventExecutorGroup, new SleeplessClock(), DEV_NULL_LOGGING); this.retryCount = retryCount; } @Override - protected boolean canRetryOn( Throwable error ) - { + protected boolean canRetryOn(Throwable error) { return invocationCount++ < retryCount; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/FuturesTest.java b/driver/src/test/java/org/neo4j/driver/internal/util/FuturesTest.java index 44b0f4e62f..b6256e2c77 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/FuturesTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/FuturesTest.java @@ -18,14 +18,24 @@ */ package org.neo4j.driver.internal.util; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.internal.util.Matchers.blockingOperationInEventLoopError; +import static org.neo4j.driver.util.DaemonThreadFactory.daemon; +import static org.neo4j.driver.util.TestUtil.sleep; + import io.netty.channel.EventLoopGroup; import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.FailedFuture; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.ImmediateEventExecutor; import io.netty.util.concurrent.SucceededFuture; -import org.junit.jupiter.api.Test; - import java.io.IOException; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; @@ -33,306 +43,261 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.async.connection.EventLoopGroupFactory; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.internal.util.Matchers.blockingOperationInEventLoopError; -import static org.neo4j.driver.util.DaemonThreadFactory.daemon; -import static org.neo4j.driver.util.TestUtil.sleep; - -class FuturesTest -{ +class FuturesTest { @Test - void shouldConvertCanceledNettyFutureToCompletionStage() throws Exception - { - DefaultPromise promise = new DefaultPromise<>( ImmediateEventExecutor.INSTANCE ); - promise.cancel( true ); + void shouldConvertCanceledNettyFutureToCompletionStage() throws Exception { + DefaultPromise promise = new DefaultPromise<>(ImmediateEventExecutor.INSTANCE); + promise.cancel(true); - CompletableFuture future = Futures.asCompletionStage( promise ).toCompletableFuture(); + CompletableFuture future = Futures.asCompletionStage(promise).toCompletableFuture(); - assertTrue( future.isCancelled() ); - assertTrue( future.isCompletedExceptionally() ); - assertThrows( CancellationException.class, future::get ); + assertTrue(future.isCancelled()); + assertTrue(future.isCompletedExceptionally()); + assertThrows(CancellationException.class, future::get); } @Test - void shouldConvertSucceededNettyFutureToCompletionStage() throws Exception - { - SucceededFuture nettyFuture = new SucceededFuture<>( ImmediateEventExecutor.INSTANCE, "Hello" ); + void shouldConvertSucceededNettyFutureToCompletionStage() throws Exception { + SucceededFuture nettyFuture = new SucceededFuture<>(ImmediateEventExecutor.INSTANCE, "Hello"); - CompletableFuture future = Futures.asCompletionStage( nettyFuture ).toCompletableFuture(); + CompletableFuture future = + Futures.asCompletionStage(nettyFuture).toCompletableFuture(); - assertTrue( future.isDone() ); - assertFalse( future.isCompletedExceptionally() ); - assertEquals( "Hello", future.get() ); + assertTrue(future.isDone()); + assertFalse(future.isCompletedExceptionally()); + assertEquals("Hello", future.get()); } @Test - void shouldConvertFailedNettyFutureToCompletionStage() throws Exception - { - RuntimeException error = new RuntimeException( "Hello" ); - FailedFuture nettyFuture = new FailedFuture<>( ImmediateEventExecutor.INSTANCE, error ); + void shouldConvertFailedNettyFutureToCompletionStage() throws Exception { + RuntimeException error = new RuntimeException("Hello"); + FailedFuture nettyFuture = new FailedFuture<>(ImmediateEventExecutor.INSTANCE, error); - CompletableFuture future = Futures.asCompletionStage( nettyFuture ).toCompletableFuture(); + CompletableFuture future = + Futures.asCompletionStage(nettyFuture).toCompletableFuture(); - assertTrue( future.isCompletedExceptionally() ); - ExecutionException e = assertThrows( ExecutionException.class, future::get ); - assertEquals( error, e.getCause() ); + assertTrue(future.isCompletedExceptionally()); + ExecutionException e = assertThrows(ExecutionException.class, future::get); + assertEquals(error, e.getCause()); } @Test - void shouldConvertRunningNettyFutureToCompletionStageWhenFutureCanceled() throws Exception - { - DefaultPromise promise = new DefaultPromise<>( ImmediateEventExecutor.INSTANCE ); + void shouldConvertRunningNettyFutureToCompletionStageWhenFutureCanceled() throws Exception { + DefaultPromise promise = new DefaultPromise<>(ImmediateEventExecutor.INSTANCE); - CompletableFuture future = Futures.asCompletionStage( promise ).toCompletableFuture(); + CompletableFuture future = Futures.asCompletionStage(promise).toCompletableFuture(); - assertFalse( future.isDone() ); - promise.cancel( true ); + assertFalse(future.isDone()); + promise.cancel(true); - assertTrue( future.isCancelled() ); - assertTrue( future.isCompletedExceptionally() ); - assertThrows( CancellationException.class, future::get ); + assertTrue(future.isCancelled()); + assertTrue(future.isCompletedExceptionally()); + assertThrows(CancellationException.class, future::get); } @Test - void shouldConvertRunningNettyFutureToCompletionStageWhenFutureSucceeded() throws Exception - { - DefaultPromise promise = new DefaultPromise<>( ImmediateEventExecutor.INSTANCE ); + void shouldConvertRunningNettyFutureToCompletionStageWhenFutureSucceeded() throws Exception { + DefaultPromise promise = new DefaultPromise<>(ImmediateEventExecutor.INSTANCE); - CompletableFuture future = Futures.asCompletionStage( promise ).toCompletableFuture(); + CompletableFuture future = Futures.asCompletionStage(promise).toCompletableFuture(); - assertFalse( future.isDone() ); - promise.setSuccess( "Hello" ); + assertFalse(future.isDone()); + promise.setSuccess("Hello"); - assertTrue( future.isDone() ); - assertFalse( future.isCompletedExceptionally() ); - assertEquals( "Hello", future.get() ); + assertTrue(future.isDone()); + assertFalse(future.isCompletedExceptionally()); + assertEquals("Hello", future.get()); } @Test - void shouldConvertRunningNettyFutureToCompletionStageWhenFutureFailed() throws Exception - { - RuntimeException error = new RuntimeException( "Hello" ); - DefaultPromise promise = new DefaultPromise<>( ImmediateEventExecutor.INSTANCE ); + void shouldConvertRunningNettyFutureToCompletionStageWhenFutureFailed() throws Exception { + RuntimeException error = new RuntimeException("Hello"); + DefaultPromise promise = new DefaultPromise<>(ImmediateEventExecutor.INSTANCE); - CompletableFuture future = Futures.asCompletionStage( promise ).toCompletableFuture(); + CompletableFuture future = Futures.asCompletionStage(promise).toCompletableFuture(); - assertFalse( future.isDone() ); - promise.setFailure( error ); + assertFalse(future.isDone()); + promise.setFailure(error); - assertTrue( future.isCompletedExceptionally() ); - ExecutionException e = assertThrows( ExecutionException.class, future::get ); - assertEquals( error, e.getCause() ); + assertTrue(future.isCompletedExceptionally()); + ExecutionException e = assertThrows(ExecutionException.class, future::get); + assertEquals(error, e.getCause()); } @Test - void shouldCreateFailedFutureWithUncheckedException() throws Exception - { - RuntimeException error = new RuntimeException( "Hello" ); - CompletableFuture future = Futures.failedFuture( error ).toCompletableFuture(); - assertTrue( future.isCompletedExceptionally() ); - ExecutionException e = assertThrows( ExecutionException.class, future::get ); - assertEquals( error, e.getCause() ); + void shouldCreateFailedFutureWithUncheckedException() throws Exception { + RuntimeException error = new RuntimeException("Hello"); + CompletableFuture future = Futures.failedFuture(error).toCompletableFuture(); + assertTrue(future.isCompletedExceptionally()); + ExecutionException e = assertThrows(ExecutionException.class, future::get); + assertEquals(error, e.getCause()); } @Test - void shouldCreateFailedFutureWithCheckedException() throws Exception - { - IOException error = new IOException( "Hello" ); - CompletableFuture future = Futures.failedFuture( error ).toCompletableFuture(); - assertTrue( future.isCompletedExceptionally() ); - ExecutionException e = assertThrows( ExecutionException.class, future::get ); - assertEquals( error, e.getCause() ); + void shouldCreateFailedFutureWithCheckedException() throws Exception { + IOException error = new IOException("Hello"); + CompletableFuture future = Futures.failedFuture(error).toCompletableFuture(); + assertTrue(future.isCompletedExceptionally()); + ExecutionException e = assertThrows(ExecutionException.class, future::get); + assertEquals(error, e.getCause()); } @Test - void shouldFailBlockingGetInEventLoopThread() throws Exception - { - EventLoopGroup eventExecutor = EventLoopGroupFactory.newEventLoopGroup( 1 ); - try - { + void shouldFailBlockingGetInEventLoopThread() throws Exception { + EventLoopGroup eventExecutor = EventLoopGroupFactory.newEventLoopGroup(1); + try { CompletableFuture future = new CompletableFuture<>(); - Future result = eventExecutor.submit( () -> Futures.blockingGet( future ) ); + Future result = eventExecutor.submit(() -> Futures.blockingGet(future)); - ExecutionException e = assertThrows( ExecutionException.class, result::get ); - assertThat( e.getCause(), is( blockingOperationInEventLoopError() ) ); - } - finally - { + ExecutionException e = assertThrows(ExecutionException.class, result::get); + assertThat(e.getCause(), is(blockingOperationInEventLoopError())); + } finally { eventExecutor.shutdownGracefully(); } } @Test - void shouldThrowInBlockingGetWhenFutureThrowsUncheckedException() - { - RuntimeException error = new RuntimeException( "Hello" ); + void shouldThrowInBlockingGetWhenFutureThrowsUncheckedException() { + RuntimeException error = new RuntimeException("Hello"); CompletableFuture future = new CompletableFuture<>(); - future.completeExceptionally( error ); + future.completeExceptionally(error); - Exception e = assertThrows( Exception.class, () -> Futures.blockingGet( future ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> Futures.blockingGet(future)); + assertEquals(error, e); } @Test - void shouldThrowInBlockingGetWhenFutureThrowsCheckedException() - { - IOException error = new IOException( "Hello" ); + void shouldThrowInBlockingGetWhenFutureThrowsCheckedException() { + IOException error = new IOException("Hello"); CompletableFuture future = new CompletableFuture<>(); - future.completeExceptionally( error ); + future.completeExceptionally(error); - Exception e = assertThrows( Exception.class, () -> Futures.blockingGet( future ) ); - assertEquals( error, e ); + Exception e = assertThrows(Exception.class, () -> Futures.blockingGet(future)); + assertEquals(error, e); } @Test - void shouldReturnFromBlockingGetWhenFutureCompletes() - { + void shouldReturnFromBlockingGetWhenFutureCompletes() { CompletableFuture future = new CompletableFuture<>(); - future.complete( "Hello" ); + future.complete("Hello"); - assertEquals( "Hello", Futures.blockingGet( future ) ); + assertEquals("Hello", Futures.blockingGet(future)); } @Test - void shouldWaitForFutureInBlockingGetEvenWhenInterrupted() - { - ExecutorService executor = Executors.newSingleThreadExecutor( daemon( "InterruptThread" ) ); - try - { + void shouldWaitForFutureInBlockingGetEvenWhenInterrupted() { + ExecutorService executor = Executors.newSingleThreadExecutor(daemon("InterruptThread")); + try { CompletableFuture future = new CompletableFuture<>(); Thread.currentThread().interrupt(); - executor.submit( () -> - { - sleep( 1_000 ); - future.complete( "Hello" ); - } ); - - assertEquals( "Hello", Futures.blockingGet( future ) ); - assertTrue( Thread.currentThread().isInterrupted() ); - } - finally - { + executor.submit(() -> { + sleep(1_000); + future.complete("Hello"); + }); + + assertEquals("Hello", Futures.blockingGet(future)); + assertTrue(Thread.currentThread().isInterrupted()); + } finally { Thread.interrupted(); // clear interruption status executor.shutdown(); } } @Test - void shouldHandleInterruptsInBlockingGet() - { - try - { + void shouldHandleInterruptsInBlockingGet() { + try { CompletableFuture future = new CompletableFuture<>(); Thread.currentThread().interrupt(); - Runnable interruptHandler = () -> future.complete( "Hello" ); - assertEquals( "Hello", Futures.blockingGet( future, interruptHandler ) ); - assertTrue( Thread.currentThread().isInterrupted() ); - } - finally - { + Runnable interruptHandler = () -> future.complete("Hello"); + assertEquals("Hello", Futures.blockingGet(future, interruptHandler)); + assertTrue(Thread.currentThread().isInterrupted()); + } finally { Thread.interrupted(); // clear interruption status } } @Test - void shouldGetNowWhenFutureDone() - { + void shouldGetNowWhenFutureDone() { CompletableFuture future = new CompletableFuture<>(); - future.complete( "Hello" ); + future.complete("Hello"); - assertEquals( "Hello", Futures.getNow( future ) ); + assertEquals("Hello", Futures.getNow(future)); } @Test - void shouldGetNowWhenFutureNotDone() - { + void shouldGetNowWhenFutureNotDone() { CompletableFuture future = new CompletableFuture<>(); - assertNull( Futures.getNow( future ) ); + assertNull(Futures.getNow(future)); } @Test - void shouldGetCauseFromCompletionException() - { - RuntimeException error = new RuntimeException( "Hello" ); - CompletionException completionException = new CompletionException( error ); + void shouldGetCauseFromCompletionException() { + RuntimeException error = new RuntimeException("Hello"); + CompletionException completionException = new CompletionException(error); - assertEquals( error, Futures.completionExceptionCause( completionException ) ); + assertEquals(error, Futures.completionExceptionCause(completionException)); } @Test - void shouldReturnSameExceptionWhenItIsNotCompletionException() - { - RuntimeException error = new RuntimeException( "Hello" ); + void shouldReturnSameExceptionWhenItIsNotCompletionException() { + RuntimeException error = new RuntimeException("Hello"); - assertEquals( error, Futures.completionExceptionCause( error ) ); + assertEquals(error, Futures.completionExceptionCause(error)); } @Test - void shouldWrapWithCompletionException() - { - RuntimeException error = new RuntimeException( "Hello" ); - CompletionException completionException = Futures.asCompletionException( error ); - assertEquals( error, completionException.getCause() ); + void shouldWrapWithCompletionException() { + RuntimeException error = new RuntimeException("Hello"); + CompletionException completionException = Futures.asCompletionException(error); + assertEquals(error, completionException.getCause()); } @Test - void shouldKeepCompletionExceptionAsIs() - { - CompletionException error = new CompletionException( new RuntimeException( "Hello" ) ); - assertEquals( error, Futures.asCompletionException( error ) ); + void shouldKeepCompletionExceptionAsIs() { + CompletionException error = new CompletionException(new RuntimeException("Hello")); + assertEquals(error, Futures.asCompletionException(error)); } @Test - void shouldCombineTwoErrors() - { - RuntimeException error1 = new RuntimeException( "Error1" ); - RuntimeException error2Cause = new RuntimeException( "Error2" ); - CompletionException error2 = new CompletionException( error2Cause ); + void shouldCombineTwoErrors() { + RuntimeException error1 = new RuntimeException("Error1"); + RuntimeException error2Cause = new RuntimeException("Error2"); + CompletionException error2 = new CompletionException(error2Cause); - CompletionException combined = Futures.combineErrors( error1, error2 ); + CompletionException combined = Futures.combineErrors(error1, error2); - assertEquals( error1, combined.getCause() ); - assertArrayEquals( new Throwable[]{error2Cause}, combined.getCause().getSuppressed() ); + assertEquals(error1, combined.getCause()); + assertArrayEquals(new Throwable[] {error2Cause}, combined.getCause().getSuppressed()); } @Test - void shouldCombineErrorAndNull() - { - RuntimeException error1 = new RuntimeException( "Error1" ); + void shouldCombineErrorAndNull() { + RuntimeException error1 = new RuntimeException("Error1"); - CompletionException combined = Futures.combineErrors( error1, null ); + CompletionException combined = Futures.combineErrors(error1, null); - assertEquals( error1, combined.getCause() ); + assertEquals(error1, combined.getCause()); } @Test - void shouldCombineNullAndError() - { - RuntimeException error2 = new RuntimeException( "Error2" ); + void shouldCombineNullAndError() { + RuntimeException error2 = new RuntimeException("Error2"); - CompletionException combined = Futures.combineErrors( null, error2 ); + CompletionException combined = Futures.combineErrors(null, error2); - assertEquals( error2, combined.getCause() ); + assertEquals(error2, combined.getCause()); } @Test - void shouldCombineNullAndNullErrors() - { - assertNull( Futures.combineErrors( null, null ) ); + void shouldCombineNullAndNullErrors() { + assertNull(Futures.combineErrors(null, null)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ImmediateSchedulingEventExecutor.java b/driver/src/test/java/org/neo4j/driver/internal/util/ImmediateSchedulingEventExecutor.java index 53a50c0928..af9d6406e8 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ImmediateSchedulingEventExecutor.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ImmediateSchedulingEventExecutor.java @@ -18,6 +18,9 @@ */ package org.neo4j.driver.internal.util; +import static java.util.Collections.unmodifiableList; +import static org.mockito.Mockito.mock; + import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutorGroup; import io.netty.util.concurrent.Future; @@ -25,7 +28,6 @@ import io.netty.util.concurrent.ProgressivePromise; import io.netty.util.concurrent.Promise; import io.netty.util.concurrent.ScheduledFuture; - import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -35,218 +37,179 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import static java.util.Collections.unmodifiableList; -import static org.mockito.Mockito.mock; - -public class ImmediateSchedulingEventExecutor implements EventExecutor -{ +public class ImmediateSchedulingEventExecutor implements EventExecutor { private final EventExecutor delegate; private final List scheduleDelays; - public ImmediateSchedulingEventExecutor() - { - this( GlobalEventExecutor.INSTANCE ); + public ImmediateSchedulingEventExecutor() { + this(GlobalEventExecutor.INSTANCE); } - public ImmediateSchedulingEventExecutor( EventExecutor delegate ) - { + public ImmediateSchedulingEventExecutor(EventExecutor delegate) { this.delegate = delegate; this.scheduleDelays = new CopyOnWriteArrayList<>(); } - public List scheduleDelays() - { - return unmodifiableList( scheduleDelays ); + public List scheduleDelays() { + return unmodifiableList(scheduleDelays); } @Override - public EventExecutor next() - { + public EventExecutor next() { return this; } @Override - public EventExecutorGroup parent() - { + public EventExecutorGroup parent() { return this; } @Override - public boolean inEventLoop() - { + public boolean inEventLoop() { return delegate.inEventLoop(); } @Override - public boolean inEventLoop( Thread thread ) - { - return delegate.inEventLoop( thread ); + public boolean inEventLoop(Thread thread) { + return delegate.inEventLoop(thread); } @Override - public Promise newPromise() - { + public Promise newPromise() { return delegate.newPromise(); } @Override - public ProgressivePromise newProgressivePromise() - { + public ProgressivePromise newProgressivePromise() { return delegate.newProgressivePromise(); } @Override - public Future newSucceededFuture( V result ) - { - return delegate.newSucceededFuture( result ); + public Future newSucceededFuture(V result) { + return delegate.newSucceededFuture(result); } @Override - public Future newFailedFuture( Throwable cause ) - { - return delegate.newFailedFuture( cause ); + public Future newFailedFuture(Throwable cause) { + return delegate.newFailedFuture(cause); } @Override - public boolean isShuttingDown() - { + public boolean isShuttingDown() { return delegate.isShuttingDown(); } @Override - public Future shutdownGracefully() - { + public Future shutdownGracefully() { return delegate.shutdownGracefully(); } @Override - public Future shutdownGracefully( long quietPeriod, long timeout, TimeUnit unit ) - { - return delegate.shutdownGracefully( quietPeriod, timeout, unit ); + public Future shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) { + return delegate.shutdownGracefully(quietPeriod, timeout, unit); } @Override - public Future terminationFuture() - { + public Future terminationFuture() { return delegate.terminationFuture(); } @Override @Deprecated - public void shutdown() - { + public void shutdown() { delegate.shutdown(); } @Override @Deprecated - public List shutdownNow() - { + public List shutdownNow() { return delegate.shutdownNow(); } @Override - public Iterator iterator() - { + public Iterator iterator() { return delegate.iterator(); } @Override - public Future submit( Runnable task ) - { - return delegate.submit( task ); + public Future submit(Runnable task) { + return delegate.submit(task); } @Override - public Future submit( Runnable task, T result ) - { - return delegate.submit( task, result ); + public Future submit(Runnable task, T result) { + return delegate.submit(task, result); } @Override - public Future submit( Callable task ) - { - return delegate.submit( task ); + public Future submit(Callable task) { + return delegate.submit(task); } @Override - public ScheduledFuture schedule( Runnable command, long delay, TimeUnit unit ) - { - scheduleDelays.add( unit.toMillis( delay ) ); - delegate.execute( command ); - return mock( ScheduledFuture.class ); + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + scheduleDelays.add(unit.toMillis(delay)); + delegate.execute(command); + return mock(ScheduledFuture.class); } @Override - public ScheduledFuture schedule( Callable callable, long delay, TimeUnit unit ) - { - scheduleDelays.add( unit.toMillis( delay ) ); - delegate.submit( callable ); - return mock( ScheduledFuture.class ); + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + scheduleDelays.add(unit.toMillis(delay)); + delegate.submit(callable); + return mock(ScheduledFuture.class); } @Override - public ScheduledFuture scheduleAtFixedRate( Runnable command, long initialDelay, long period, - TimeUnit unit ) - { + public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { throw new UnsupportedOperationException(); } @Override - public ScheduledFuture scheduleWithFixedDelay( Runnable command, long initialDelay, long delay, - TimeUnit unit ) - { + public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { throw new UnsupportedOperationException(); } @Override - public boolean isShutdown() - { + public boolean isShutdown() { return delegate.isShutdown(); } @Override - public boolean isTerminated() - { + public boolean isTerminated() { return delegate.isTerminated(); } @Override - public boolean awaitTermination( long timeout, TimeUnit unit ) throws InterruptedException - { - return delegate.awaitTermination( timeout, unit ); + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + return delegate.awaitTermination(timeout, unit); } @Override - public List> invokeAll( Collection> tasks ) - throws InterruptedException - { - return delegate.invokeAll( tasks ); + public List> invokeAll(Collection> tasks) + throws InterruptedException { + return delegate.invokeAll(tasks); } @Override - public List> invokeAll( Collection> tasks, long timeout, - TimeUnit unit ) throws InterruptedException - { - return delegate.invokeAll( tasks, timeout, unit ); + public List> invokeAll( + Collection> tasks, long timeout, TimeUnit unit) throws InterruptedException { + return delegate.invokeAll(tasks, timeout, unit); } @Override - public T invokeAny( Collection> tasks ) throws InterruptedException, ExecutionException - { - return delegate.invokeAny( tasks ); + public T invokeAny(Collection> tasks) throws InterruptedException, ExecutionException { + return delegate.invokeAny(tasks); } @Override - public T invokeAny( Collection> tasks, long timeout, TimeUnit unit ) - throws InterruptedException, ExecutionException, TimeoutException - { - return delegate.invokeAny( tasks, timeout, unit ); + public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return delegate.invokeAny(tasks, timeout, unit); } @Override - public void execute( Runnable command ) - { - delegate.execute( command ); + public void execute(Runnable command) { + delegate.execute(command); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/IterablesTest.java b/driver/src/test/java/org/neo4j/driver/internal/util/IterablesTest.java index 6fd0f0279f..2a73fd0ae3 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/IterablesTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/IterablesTest.java @@ -18,10 +18,6 @@ */ package org.neo4j.driver.internal.util; -import org.junit.jupiter.api.Test; - -import java.util.Queue; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -29,48 +25,44 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -class IterablesTest -{ +import java.util.Queue; +import org.junit.jupiter.api.Test; + +class IterablesTest { @Test - void shouldCreateHashMapWithExpectedSize() - { - assertNotNull( Iterables.newHashMapWithSize( 42 ) ); + void shouldCreateHashMapWithExpectedSize() { + assertNotNull(Iterables.newHashMapWithSize(42)); } @Test - void shouldCreateLinkedHashMapWithExpectedSize() - { - assertNotNull( Iterables.newLinkedHashMapWithSize( 42 ) ); + void shouldCreateLinkedHashMapWithExpectedSize() { + assertNotNull(Iterables.newLinkedHashMapWithSize(42)); } @Test - void shouldThrowWhenNegativeHashMapSizeGiven() - { - assertThrows( IllegalArgumentException.class, () -> Iterables.newHashMapWithSize( -42 ) ); + void shouldThrowWhenNegativeHashMapSizeGiven() { + assertThrows(IllegalArgumentException.class, () -> Iterables.newHashMapWithSize(-42)); } @Test - void shouldThrowWhenNegativeLinkedHashMapSizeGiven() - { - assertThrows( IllegalArgumentException.class, () -> Iterables.newLinkedHashMapWithSize( -42 ) ); + void shouldThrowWhenNegativeLinkedHashMapSizeGiven() { + assertThrows(IllegalArgumentException.class, () -> Iterables.newLinkedHashMapWithSize(-42)); } @Test - void shouldReturnEmptyQueue() - { + void shouldReturnEmptyQueue() { Queue queue = Iterables.emptyQueue(); - assertEquals( 0, queue.size() ); - assertTrue( queue.isEmpty() ); - assertNull( queue.peek() ); - assertNull( queue.poll() ); + assertEquals(0, queue.size()); + assertTrue(queue.isEmpty()); + assertNull(queue.peek()); + assertNull(queue.poll()); - assertThrows( UnsupportedOperationException.class, () -> queue.add( "Hello" ) ); - assertThrows( UnsupportedOperationException.class, () -> queue.offer( "World" ) ); + assertThrows(UnsupportedOperationException.class, () -> queue.add("Hello")); + assertThrows(UnsupportedOperationException.class, () -> queue.offer("World")); } @Test - void shouldReturnSameEmptyQueue() - { - assertSame( Iterables.emptyQueue(), Iterables.emptyQueue() ); + void shouldReturnSameEmptyQueue() { + assertSame(Iterables.emptyQueue(), Iterables.emptyQueue()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/MatcherFactory.java b/driver/src/test/java/org/neo4j/driver/internal/util/MatcherFactory.java index 3c5e1d7b15..b6c01c2792 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/MatcherFactory.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/MatcherFactory.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; - import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; @@ -30,8 +29,7 @@ import org.hamcrest.TypeSafeDiagnosingMatcher; import org.hamcrest.TypeSafeMatcher; -public abstract class MatcherFactory implements SelfDescribing -{ +public abstract class MatcherFactory implements SelfDescribing { public abstract Matcher createMatcher(); /** @@ -45,37 +43,34 @@ public abstract class MatcherFactory implements SelfDescribing * The type of elements in the collection. * @return A matcher for a collection. */ - public static Matcher> count( final Matcher matcher, final Matcher count ) - { - return new TypeSafeDiagnosingMatcher>() - { + public static Matcher> count(final Matcher matcher, final Matcher count) { + return new TypeSafeDiagnosingMatcher>() { @Override - protected boolean matchesSafely( Iterable collection, Description mismatchDescription ) - { + protected boolean matchesSafely(Iterable collection, Description mismatchDescription) { int matches = 0; - for ( T item : collection ) - { - if ( matcher.matches( item ) ) - { + for (T item : collection) { + if (matcher.matches(item)) { matches++; } } - if ( count.matches( matches ) ) - { + if (count.matches(matches)) { return true; } - mismatchDescription.appendText( "actual number of matches was " ).appendValue( matches ) - .appendText( " in " ).appendValue( collection ); + mismatchDescription + .appendText("actual number of matches was ") + .appendValue(matches) + .appendText(" in ") + .appendValue(collection); return false; } @Override - public void describeTo( Description description ) - { - description.appendText( "collection containing " ) - .appendDescriptionOf( count ) - .appendText( " occurences of " ) - .appendDescriptionOf( matcher ); + public void describeTo(Description description) { + description + .appendText("collection containing ") + .appendDescriptionOf(count) + .appendText(" occurences of ") + .appendDescriptionOf(matcher); } }; } @@ -91,40 +86,31 @@ public void describeTo( Description description ) * @return A matcher for a collection. */ @SafeVarargs - public static Matcher> containsAtLeast( final Matcher... matchers ) - { - @SuppressWarnings( "unchecked" ) + public static Matcher> containsAtLeast(final Matcher... matchers) { + @SuppressWarnings("unchecked") MatcherFactory[] factories = new MatcherFactory[matchers.length]; - for ( int i = 0; i < factories.length; i++ ) - { - factories[i] = matches( matchers[i] ); + for (int i = 0; i < factories.length; i++) { + factories[i] = matches(matchers[i]); } - return containsAtLeast( factories ); + return containsAtLeast(factories); } @SafeVarargs - public static Matcher> containsAtLeast( final MatcherFactory... matcherFactories ) - { - return new TypeSafeMatcher>() - { + public static Matcher> containsAtLeast(final MatcherFactory... matcherFactories) { + return new TypeSafeMatcher>() { @Override - protected boolean matchesSafely( Iterable collection ) - { - @SuppressWarnings( "unchecked" ) + protected boolean matchesSafely(Iterable collection) { + @SuppressWarnings("unchecked") Matcher[] matchers = new Matcher[matcherFactories.length]; - for ( int i = 0; i < matchers.length; i++ ) - { + for (int i = 0; i < matchers.length; i++) { matchers[i] = matcherFactories[i].createMatcher(); } int i = 0; - for ( T item : collection ) - { - if ( i >= matchers.length ) - { + for (T item : collection) { + if (i >= matchers.length) { return true; } - if ( matchers[i].matches( item ) ) - { + if (matchers[i].matches(item)) { i++; } } @@ -132,48 +118,35 @@ protected boolean matchesSafely( Iterable collection ) } @Override - public void describeTo( Description description ) - { - description.appendText( "collection containing at least " ); - for ( int i = 0; i < matcherFactories.length; i++ ) - { - if ( i != 0 ) - { - if ( i == matcherFactories.length - 1 ) - { - description.appendText( " and " ); - } - else - { - description.appendText( ", " ); + public void describeTo(Description description) { + description.appendText("collection containing at least "); + for (int i = 0; i < matcherFactories.length; i++) { + if (i != 0) { + if (i == matcherFactories.length - 1) { + description.appendText(" and "); + } else { + description.appendText(", "); } } - description.appendDescriptionOf( matcherFactories[i] ); + description.appendDescriptionOf(matcherFactories[i]); } - description.appendText( " (in that order) " ); + description.appendText(" (in that order) "); } }; } @SafeVarargs - public static MatcherFactory inAnyOrder( final Matcher... matchers ) - { - return new MatcherFactory() - { + public static MatcherFactory inAnyOrder(final Matcher... matchers) { + return new MatcherFactory() { @Override - public Matcher createMatcher() - { - final List> remaining = new ArrayList<>( matchers.length ); - Collections.addAll( remaining, matchers ); - return new BaseMatcher() - { + public Matcher createMatcher() { + final List> remaining = new ArrayList<>(matchers.length); + Collections.addAll(remaining, matchers); + return new BaseMatcher() { @Override - public boolean matches( Object item ) - { - for ( Iterator> matcher = remaining.iterator(); matcher.hasNext(); ) - { - if ( matcher.next().matches( item ) ) - { + public boolean matches(Object item) { + for (Iterator> matcher = remaining.iterator(); matcher.hasNext(); ) { + if (matcher.next().matches(item)) { matcher.remove(); return remaining.isEmpty(); } @@ -182,48 +155,40 @@ public boolean matches( Object item ) } @Override - public void describeTo( Description description ) - { - describe( description ); + public void describeTo(Description description) { + describe(description); } }; } @Override - public void describeTo( Description description ) - { - describe( description ); + public void describeTo(Description description) { + describe(description); } - private void describe( Description description ) - { - description.appendText( "in any order" ); + private void describe(Description description) { + description.appendText("in any order"); String sep = " {"; - for ( Matcher matcher : matchers ) - { - description.appendText( sep ); - description.appendDescriptionOf( matcher ); + for (Matcher matcher : matchers) { + description.appendText(sep); + description.appendDescriptionOf(matcher); sep = ", "; } - description.appendText( "}" ); + description.appendText("}"); } }; } - public static MatcherFactory matches( final Matcher matcher ) - { - return new MatcherFactory() - { + public static MatcherFactory matches(final Matcher matcher) { + return new MatcherFactory() { @Override - public Matcher createMatcher() - { + public Matcher createMatcher() { return matcher; } @Override - public void describeTo( Description description ) - { - matcher.describeTo( description ); + public void describeTo(Description description) { + matcher.describeTo(description); } }; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/Matchers.java b/driver/src/test/java/org/neo4j/driver/internal/util/Matchers.java index 33c3897f42..2021e33c0c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/Matchers.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/Matchers.java @@ -18,13 +18,11 @@ */ package org.neo4j.driver.internal.util; +import java.util.Objects; +import java.util.concurrent.TimeUnit; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; - -import java.util.Objects; -import java.util.concurrent.TimeUnit; - import org.neo4j.driver.Driver; import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.BoltServerAddress; @@ -36,194 +34,152 @@ import org.neo4j.driver.internal.spi.ConnectionProvider; import org.neo4j.driver.summary.ResultSummary; -public final class Matchers -{ - private Matchers() - { - } +public final class Matchers { + private Matchers() {} - public static Matcher directDriver() - { - return new TypeSafeMatcher() - { + public static Matcher directDriver() { + return new TypeSafeMatcher() { @Override - protected boolean matchesSafely( Driver driver ) - { - return hasConnectionProvider( driver, DirectConnectionProvider.class ); + protected boolean matchesSafely(Driver driver) { + return hasConnectionProvider(driver, DirectConnectionProvider.class); } @Override - public void describeTo( Description description ) - { - description.appendText( "direct 'bolt://' driver " ); + public void describeTo(Description description) { + description.appendText("direct 'bolt://' driver "); } }; } - public static Matcher directDriverWithAddress( final BoltServerAddress address ) - { - return new TypeSafeMatcher() - { + public static Matcher directDriverWithAddress(final BoltServerAddress address) { + return new TypeSafeMatcher() { @Override - protected boolean matchesSafely( Driver driver ) - { - DirectConnectionProvider provider = extractConnectionProvider( driver, DirectConnectionProvider.class ); - return provider != null && Objects.equals( provider.getAddress(), address ); + protected boolean matchesSafely(Driver driver) { + DirectConnectionProvider provider = extractConnectionProvider(driver, DirectConnectionProvider.class); + return provider != null && Objects.equals(provider.getAddress(), address); } @Override - public void describeTo( Description description ) - { - description.appendText( "direct driver with address bolt://" ).appendValue( address ); + public void describeTo(Description description) { + description.appendText("direct driver with address bolt://").appendValue(address); } }; } - public static Matcher clusterDriver() - { - return new TypeSafeMatcher() - { + public static Matcher clusterDriver() { + return new TypeSafeMatcher() { @Override - protected boolean matchesSafely( Driver driver ) - { - return hasConnectionProvider( driver, LoadBalancer.class ); + protected boolean matchesSafely(Driver driver) { + return hasConnectionProvider(driver, LoadBalancer.class); } @Override - public void describeTo( Description description ) - { - description.appendText( "cluster 'neo4j://' driver " ); + public void describeTo(Description description) { + description.appendText("cluster 'neo4j://' driver "); } }; } - public static Matcher containsResultAvailableAfterAndResultConsumedAfter() - { - return new TypeSafeMatcher() - { + public static Matcher containsResultAvailableAfterAndResultConsumedAfter() { + return new TypeSafeMatcher() { @Override - protected boolean matchesSafely( ResultSummary summary ) - { - return summary.resultAvailableAfter( TimeUnit.MILLISECONDS ) >= 0L && - summary.resultConsumedAfter( TimeUnit.MILLISECONDS ) >= 0L; + protected boolean matchesSafely(ResultSummary summary) { + return summary.resultAvailableAfter(TimeUnit.MILLISECONDS) >= 0L + && summary.resultConsumedAfter(TimeUnit.MILLISECONDS) >= 0L; } @Override - public void describeTo( Description description ) - { - description.appendText( "resultAvailableAfter and resultConsumedAfter " ); + public void describeTo(Description description) { + description.appendText("resultAvailableAfter and resultConsumedAfter "); } }; } - public static Matcher arithmeticError() - { - return new TypeSafeMatcher() - { + public static Matcher arithmeticError() { + return new TypeSafeMatcher() { @Override - protected boolean matchesSafely( Throwable error ) - { - return error instanceof ClientException && - ((ClientException) error).code().contains( "ArithmeticError" ); + protected boolean matchesSafely(Throwable error) { + return error instanceof ClientException + && ((ClientException) error).code().contains("ArithmeticError"); } @Override - public void describeTo( Description description ) - { - description.appendText( "client error with code 'ArithmeticError' " ); + public void describeTo(Description description) { + description.appendText("client error with code 'ArithmeticError' "); } }; } - public static Matcher syntaxError() - { - return syntaxError( null ); + public static Matcher syntaxError() { + return syntaxError(null); } - public static Matcher syntaxError( String messagePrefix ) - { - return new TypeSafeMatcher() - { + public static Matcher syntaxError(String messagePrefix) { + return new TypeSafeMatcher() { @Override - protected boolean matchesSafely( Throwable error ) - { - if ( error instanceof ClientException ) - { + protected boolean matchesSafely(Throwable error) { + if (error instanceof ClientException) { ClientException clientError = (ClientException) error; - return clientError.code().contains( "SyntaxError" ) && - (messagePrefix == null || clientError.getMessage().startsWith( messagePrefix )); + return clientError.code().contains("SyntaxError") + && (messagePrefix == null + || clientError.getMessage().startsWith(messagePrefix)); } return false; } @Override - public void describeTo( Description description ) - { - description.appendText( "client error with code 'SyntaxError' and prefix '" + messagePrefix + "' " ); + public void describeTo(Description description) { + description.appendText("client error with code 'SyntaxError' and prefix '" + messagePrefix + "' "); } }; } - public static Matcher connectionAcquisitionTimeoutError( int timeoutMillis ) - { - return new TypeSafeMatcher() - { - @Override - protected boolean matchesSafely( Throwable error ) - { - if ( error instanceof ClientException ) - { - String expectedMessage = "Unable to acquire connection from the pool within " + - "configured maximum time of " + timeoutMillis + "ms"; - return expectedMessage.equals( error.getMessage() ); + public static Matcher connectionAcquisitionTimeoutError(int timeoutMillis) { + return new TypeSafeMatcher() { + @Override + protected boolean matchesSafely(Throwable error) { + if (error instanceof ClientException) { + String expectedMessage = "Unable to acquire connection from the pool within " + + "configured maximum time of " + timeoutMillis + "ms"; + return expectedMessage.equals(error.getMessage()); } return false; } @Override - public void describeTo( Description description ) - { - description.appendText( "acquisition timeout error with " + timeoutMillis + "ms" ); + public void describeTo(Description description) { + description.appendText("acquisition timeout error with " + timeoutMillis + "ms"); } }; } - public static Matcher blockingOperationInEventLoopError() - { - return new TypeSafeMatcher() - { + public static Matcher blockingOperationInEventLoopError() { + return new TypeSafeMatcher() { @Override - protected boolean matchesSafely( Throwable error ) - { - return error instanceof IllegalStateException && - error.getMessage() != null && - error.getMessage().startsWith( "Blocking operation can't be executed in IO thread" ); + protected boolean matchesSafely(Throwable error) { + return error instanceof IllegalStateException + && error.getMessage() != null + && error.getMessage().startsWith("Blocking operation can't be executed in IO thread"); } @Override - public void describeTo( Description description ) - { - description.appendText( "IllegalStateException about blocking operation in event loop thread " ); + public void describeTo(Description description) { + description.appendText("IllegalStateException about blocking operation in event loop thread "); } }; } - private static boolean hasConnectionProvider( Driver driver, Class providerClass ) - { - return extractConnectionProvider( driver, providerClass ) != null; + private static boolean hasConnectionProvider(Driver driver, Class providerClass) { + return extractConnectionProvider(driver, providerClass) != null; } - private static T extractConnectionProvider( Driver driver, Class providerClass ) - { - if ( driver instanceof InternalDriver ) - { + private static T extractConnectionProvider(Driver driver, Class providerClass) { + if (driver instanceof InternalDriver) { SessionFactory sessionFactory = ((InternalDriver) driver).getSessionFactory(); - if ( sessionFactory instanceof SessionFactoryImpl ) - { + if (sessionFactory instanceof SessionFactoryImpl) { ConnectionProvider provider = ((SessionFactoryImpl) sessionFactory).getConnectionProvider(); - if ( providerClass.isInstance( provider ) ) - { - return providerClass.cast( provider ); + if (providerClass.isInstance(provider)) { + return providerClass.cast(provider); } } } 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 9be58dea1b..f88b6e12f3 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,12 +22,10 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.MessageToMessageEncoder; - import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; - import org.neo4j.driver.Config; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.ConnectionSettings; @@ -43,42 +41,49 @@ import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.security.SecurityPlan; -public class MessageRecordingDriverFactory extends DriverFactory -{ - private final Map> messagesByChannel = new ConcurrentHashMap<>(); +public class MessageRecordingDriverFactory extends DriverFactory { + private final Map> messagesByChannel = new ConcurrentHashMap<>(); - public Map> getMessagesByChannel() - { + public Map> getMessagesByChannel() { return messagesByChannel; } @Override - protected ChannelConnector createConnector( ConnectionSettings settings, SecurityPlan securityPlan, Config config, Clock clock, - RoutingContext routingContext ) - { + protected ChannelConnector createConnector( + ConnectionSettings settings, + SecurityPlan securityPlan, + Config config, + Clock clock, + RoutingContext routingContext) { ChannelPipelineBuilder pipelineBuilder = new MessageRecordingChannelPipelineBuilder(); - return new ChannelConnectorImpl( settings, securityPlan, pipelineBuilder, config.logging(), clock, routingContext, - DefaultDomainNameResolver.getInstance() ); + return new ChannelConnectorImpl( + settings, + securityPlan, + pipelineBuilder, + config.logging(), + clock, + routingContext, + DefaultDomainNameResolver.getInstance()); } - private class MessageRecordingChannelPipelineBuilder extends ChannelPipelineBuilderImpl - { + private class MessageRecordingChannelPipelineBuilder extends ChannelPipelineBuilderImpl { @Override - public void build( MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging ) - { - super.build( messageFormat, pipeline, logging ); - pipeline.addAfter( OutboundMessageHandler.NAME, MessageRecordingHandler.class.getSimpleName(), new MessageRecordingHandler() ); + public void build(MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging) { + super.build(messageFormat, pipeline, logging); + pipeline.addAfter( + OutboundMessageHandler.NAME, + MessageRecordingHandler.class.getSimpleName(), + new MessageRecordingHandler()); } } - private class MessageRecordingHandler extends MessageToMessageEncoder - { + private class MessageRecordingHandler extends MessageToMessageEncoder { @Override - protected void encode( ChannelHandlerContext ctx, Message msg, List out ) - { - List messages = messagesByChannel.computeIfAbsent( ctx.channel(), ignore -> new CopyOnWriteArrayList<>() ); - messages.add( msg ); - out.add( msg ); + protected void encode(ChannelHandlerContext ctx, Message msg, List out) { + List messages = + messagesByChannel.computeIfAbsent(ctx.channel(), ignore -> new CopyOnWriteArrayList<>()); + messages.add(msg); + out.add(msg); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/MetadataExtractorTest.java b/driver/src/test/java/org/neo4j/driver/internal/util/MetadataExtractorTest.java index afbc7c5dd2..651a89ac7b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/MetadataExtractorTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/MetadataExtractorTest.java @@ -18,30 +18,6 @@ */ package org.neo4j.driver.internal.util; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.neo4j.driver.Bookmark; -import org.neo4j.driver.Query; -import org.neo4j.driver.Value; -import org.neo4j.driver.Values; -import org.neo4j.driver.exceptions.UntrustedServerException; -import org.neo4j.driver.exceptions.value.Uncoercible; -import org.neo4j.driver.internal.BoltServerAddress; -import org.neo4j.driver.internal.InternalBookmark; -import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43; -import org.neo4j.driver.internal.spi.Connection; -import org.neo4j.driver.internal.summary.InternalInputPosition; -import org.neo4j.driver.summary.DatabaseInfo; -import org.neo4j.driver.summary.Notification; -import org.neo4j.driver.summary.Plan; -import org.neo4j.driver.summary.ProfiledPlan; -import org.neo4j.driver.summary.ResultSummary; - import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; @@ -69,438 +45,421 @@ import static org.neo4j.driver.summary.QueryType.WRITE_ONLY; import static org.neo4j.driver.util.TestUtil.anyServerVersion; -class MetadataExtractorTest -{ +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Bookmark; +import org.neo4j.driver.Query; +import org.neo4j.driver.Value; +import org.neo4j.driver.Values; +import org.neo4j.driver.exceptions.UntrustedServerException; +import org.neo4j.driver.exceptions.value.Uncoercible; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.internal.InternalBookmark; +import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43; +import org.neo4j.driver.internal.spi.Connection; +import org.neo4j.driver.internal.summary.InternalInputPosition; +import org.neo4j.driver.summary.DatabaseInfo; +import org.neo4j.driver.summary.Notification; +import org.neo4j.driver.summary.Plan; +import org.neo4j.driver.summary.ProfiledPlan; +import org.neo4j.driver.summary.ResultSummary; + +class MetadataExtractorTest { private static final String RESULT_AVAILABLE_AFTER_KEY = "available_after"; private static final String RESULT_CONSUMED_AFTER_KEY = "consumed_after"; - private final MetadataExtractor extractor = new MetadataExtractor( RESULT_AVAILABLE_AFTER_KEY, RESULT_CONSUMED_AFTER_KEY ); + private final MetadataExtractor extractor = + new MetadataExtractor(RESULT_AVAILABLE_AFTER_KEY, RESULT_CONSUMED_AFTER_KEY); @Test - void shouldExtractQueryKeys() - { - List keys = asList( "hello", " ", "world", "!" ); - Map keyIndex = new HashMap<>(); - keyIndex.put( "hello", 0 ); - keyIndex.put( " ", 1 ); - keyIndex.put( "world", 2 ); - keyIndex.put( "!", 3 ); + void shouldExtractQueryKeys() { + List keys = asList("hello", " ", "world", "!"); + Map keyIndex = new HashMap<>(); + keyIndex.put("hello", 0); + keyIndex.put(" ", 1); + keyIndex.put("world", 2); + keyIndex.put("!", 3); - QueryKeys extracted = extractor.extractQueryKeys( singletonMap( "fields", value( keys ) ) ); - assertEquals( keys, extracted.keys() ); - assertEquals( keyIndex, extracted.keyIndex() ); + QueryKeys extracted = extractor.extractQueryKeys(singletonMap("fields", value(keys))); + assertEquals(keys, extracted.keys()); + assertEquals(keyIndex, extracted.keyIndex()); } @Test - void shouldExtractEmptyQueryKeysWhenNoneInMetadata() - { - QueryKeys extracted = extractor.extractQueryKeys( emptyMap() ); - assertEquals( emptyList(), extracted.keys() ); - assertEquals( emptyMap(), extracted.keyIndex() ); + void shouldExtractEmptyQueryKeysWhenNoneInMetadata() { + QueryKeys extracted = extractor.extractQueryKeys(emptyMap()); + assertEquals(emptyList(), extracted.keys()); + assertEquals(emptyMap(), extracted.keyIndex()); } @Test - void shouldExtractResultAvailableAfter() - { - Map metadata = singletonMap( RESULT_AVAILABLE_AFTER_KEY, value( 424242 ) ); - long extractedResultAvailableAfter = extractor.extractResultAvailableAfter( metadata ); - assertEquals( 424242L, extractedResultAvailableAfter ); + void shouldExtractResultAvailableAfter() { + Map metadata = singletonMap(RESULT_AVAILABLE_AFTER_KEY, value(424242)); + long extractedResultAvailableAfter = extractor.extractResultAvailableAfter(metadata); + assertEquals(424242L, extractedResultAvailableAfter); } @Test - void shouldExtractNoResultAvailableAfterWhenNoneInMetadata() - { - long extractedResultAvailableAfter = extractor.extractResultAvailableAfter( emptyMap() ); - assertEquals( -1, extractedResultAvailableAfter ); + void shouldExtractNoResultAvailableAfterWhenNoneInMetadata() { + long extractedResultAvailableAfter = extractor.extractResultAvailableAfter(emptyMap()); + assertEquals(-1, extractedResultAvailableAfter); } @Test - void shouldBuildResultSummaryWithQuery() - { - Query query = new Query( "UNWIND range(10, 100) AS x CREATE (:Node {name: $name, x: x})", - singletonMap( "name", "Apa" ) ); + void shouldBuildResultSummaryWithQuery() { + Query query = + new Query("UNWIND range(10, 100) AS x CREATE (:Node {name: $name, x: x})", singletonMap("name", "Apa")); - ResultSummary summary = extractor.extractSummary( query, connectionMock(), 42, emptyMap() ); + ResultSummary summary = extractor.extractSummary(query, connectionMock(), 42, emptyMap()); - assertEquals( query, summary.query() ); + assertEquals(query, summary.query()); } @Test - void shouldBuildResultSummaryWithServerInfo() - { - Connection connection = connectionMock( new BoltServerAddress( "server:42" ), v4_0_0 ); + void shouldBuildResultSummaryWithServerInfo() { + Connection connection = connectionMock(new BoltServerAddress("server:42"), v4_0_0); - ResultSummary summary = extractor.extractSummary( query(), connection, 42, emptyMap() ); + ResultSummary summary = extractor.extractSummary(query(), connection, 42, emptyMap()); - assertEquals( "server:42", summary.server().address() ); - assertEquals( "Neo4j/4.0.0", summary.server().version() ); + assertEquals("server:42", summary.server().address()); + assertEquals("Neo4j/4.0.0", summary.server().version()); } @Test - void shouldBuildResultSummaryWithQueryType() - { - assertEquals( READ_ONLY, createWithQueryType( value( "r" ) ).queryType() ); - assertEquals( READ_WRITE, createWithQueryType( value( "rw" ) ).queryType() ); - assertEquals( WRITE_ONLY, createWithQueryType( value( "w" ) ).queryType() ); - assertEquals( SCHEMA_WRITE, createWithQueryType( value( "s" ) ).queryType() ); + void shouldBuildResultSummaryWithQueryType() { + assertEquals(READ_ONLY, createWithQueryType(value("r")).queryType()); + assertEquals(READ_WRITE, createWithQueryType(value("rw")).queryType()); + assertEquals(WRITE_ONLY, createWithQueryType(value("w")).queryType()); + assertEquals(SCHEMA_WRITE, createWithQueryType(value("s")).queryType()); - assertNull( createWithQueryType( null ).queryType() ); + assertNull(createWithQueryType(null).queryType()); } @Test - void shouldBuildResultSummaryWithCounters() - { + void shouldBuildResultSummaryWithCounters() { Value stats = parameters( - "nodes-created", value( 42 ), - "nodes-deleted", value( 4242 ), - "relationships-created", value( 24 ), - "relationships-deleted", value( 24 ), + "nodes-created", value(42), + "nodes-deleted", value(4242), + "relationships-created", value(24), + "relationships-deleted", value(24), "properties-set", null, - "labels-added", value( 5 ), - "labels-removed", value( 10 ), + "labels-added", value(5), + "labels-removed", value(10), "indexes-added", null, - "indexes-removed", value( 0 ), + "indexes-removed", value(0), "constraints-added", null, - "constraints-removed", value( 2 ) - ); + "constraints-removed", value(2)); - Map metadata = singletonMap( "stats", stats ); + Map metadata = singletonMap("stats", stats); - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, metadata ); + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, metadata); - assertEquals( 42, summary.counters().nodesCreated() ); - assertEquals( 4242, summary.counters().nodesDeleted() ); - assertEquals( 24, summary.counters().relationshipsCreated() ); - assertEquals( 24, summary.counters().relationshipsDeleted() ); - assertEquals( 0, summary.counters().propertiesSet() ); - assertEquals( 5, summary.counters().labelsAdded() ); - assertEquals( 10, summary.counters().labelsRemoved() ); - assertEquals( 0, summary.counters().indexesAdded() ); - assertEquals( 0, summary.counters().indexesRemoved() ); - assertEquals( 0, summary.counters().constraintsAdded() ); - assertEquals( 2, summary.counters().constraintsRemoved() ); + assertEquals(42, summary.counters().nodesCreated()); + assertEquals(4242, summary.counters().nodesDeleted()); + assertEquals(24, summary.counters().relationshipsCreated()); + assertEquals(24, summary.counters().relationshipsDeleted()); + assertEquals(0, summary.counters().propertiesSet()); + assertEquals(5, summary.counters().labelsAdded()); + assertEquals(10, summary.counters().labelsRemoved()); + assertEquals(0, summary.counters().indexesAdded()); + assertEquals(0, summary.counters().indexesRemoved()); + assertEquals(0, summary.counters().constraintsAdded()); + assertEquals(2, summary.counters().constraintsRemoved()); } @Test - void shouldBuildResultSummaryWithoutCounters() - { - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, emptyMap() ); - assertEquals( EMPTY_STATS, summary.counters() ); + void shouldBuildResultSummaryWithoutCounters() { + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, emptyMap()); + assertEquals(EMPTY_STATS, summary.counters()); } @Test - void shouldBuildResultSummaryWithPlan() - { - Value plan = value( parameters( + void shouldBuildResultSummaryWithPlan() { + Value plan = value(parameters( "operatorType", "Projection", - "args", parameters( "n", 42 ), - "identifiers", values( "a", "b" ), - "children", values( - parameters( + "args", parameters("n", 42), + "identifiers", values("a", "b"), + "children", + values(parameters( "operatorType", "AllNodeScan", - "args", parameters( "x", 4242 ), - "identifiers", values( "n", "t", "f" ) - ) - ) - ) ); - Map metadata = singletonMap( "plan", plan ); + "args", parameters("x", 4242), + "identifiers", values("n", "t", "f"))))); + Map metadata = singletonMap("plan", plan); - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, metadata ); + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, metadata); - assertTrue( summary.hasPlan() ); - assertEquals( "Projection", summary.plan().operatorType() ); - assertEquals( singletonMap( "n", value( 42 ) ), summary.plan().arguments() ); - assertEquals( asList( "a", "b" ), summary.plan().identifiers() ); + assertTrue(summary.hasPlan()); + assertEquals("Projection", summary.plan().operatorType()); + assertEquals(singletonMap("n", value(42)), summary.plan().arguments()); + assertEquals(asList("a", "b"), summary.plan().identifiers()); List children = summary.plan().children(); - assertEquals( 1, children.size() ); - Plan child = children.get( 0 ); + assertEquals(1, children.size()); + Plan child = children.get(0); - assertEquals( "AllNodeScan", child.operatorType() ); - assertEquals( singletonMap( "x", value( 4242 ) ), child.arguments() ); - assertEquals( asList( "n", "t", "f" ), child.identifiers() ); - assertEquals( 0, child.children().size() ); + assertEquals("AllNodeScan", child.operatorType()); + assertEquals(singletonMap("x", value(4242)), child.arguments()); + assertEquals(asList("n", "t", "f"), child.identifiers()); + assertEquals(0, child.children().size()); } @Test - void shouldBuildResultSummaryWithoutPlan() - { - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, emptyMap() ); - assertFalse( summary.hasPlan() ); - assertNull( summary.plan() ); + void shouldBuildResultSummaryWithoutPlan() { + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, emptyMap()); + assertFalse(summary.hasPlan()); + assertNull(summary.plan()); } @Test - void shouldBuildResultSummaryWithProfiledPlan() - { - Value profile = value( parameters( + void shouldBuildResultSummaryWithProfiledPlan() { + Value profile = value(parameters( "operatorType", "ProduceResult", - "args", parameters( "a", 42 ), - "identifiers", values( "a", "b" ), - "rows", value( 424242 ), - "dbHits", value( 242424 ), - "time", value( 999 ), - "children", values( - parameters( + "args", parameters("a", 42), + "identifiers", values("a", "b"), + "rows", value(424242), + "dbHits", value(242424), + "time", value(999), + "children", + values(parameters( "operatorType", "LabelScan", - "args", parameters( "x", 1 ), - "identifiers", values( "y", "z" ), - "rows", value( 2 ), - "dbHits", value( 4 ) - ) - ) - ) ); - Map metadata = singletonMap( "profile", profile ); - - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, metadata ); - - assertTrue( summary.hasPlan() ); - assertTrue( summary.hasProfile() ); - assertEquals( "ProduceResult", summary.profile().operatorType() ); - assertEquals( singletonMap( "a", value( 42 ) ), summary.profile().arguments() ); - assertEquals( asList( "a", "b" ), summary.profile().identifiers() ); - assertEquals( 424242, summary.profile().records() ); - assertEquals( 242424, summary.profile().dbHits() ); - assertEquals( 999, summary.profile().time() ); - assertFalse( summary.profile().hasPageCacheStats() ); - assertEquals( 0, summary.profile().pageCacheHitRatio() ); - assertEquals( 0, summary.profile().pageCacheMisses() ); - assertEquals( 0, summary.profile().pageCacheHits() ); + "args", parameters("x", 1), + "identifiers", values("y", "z"), + "rows", value(2), + "dbHits", value(4))))); + Map metadata = singletonMap("profile", profile); + + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, metadata); + + assertTrue(summary.hasPlan()); + assertTrue(summary.hasProfile()); + assertEquals("ProduceResult", summary.profile().operatorType()); + assertEquals(singletonMap("a", value(42)), summary.profile().arguments()); + assertEquals(asList("a", "b"), summary.profile().identifiers()); + assertEquals(424242, summary.profile().records()); + assertEquals(242424, summary.profile().dbHits()); + assertEquals(999, summary.profile().time()); + assertFalse(summary.profile().hasPageCacheStats()); + assertEquals(0, summary.profile().pageCacheHitRatio()); + assertEquals(0, summary.profile().pageCacheMisses()); + assertEquals(0, summary.profile().pageCacheHits()); List children = summary.profile().children(); - assertEquals( 1, children.size() ); - ProfiledPlan child = children.get( 0 ); + assertEquals(1, children.size()); + ProfiledPlan child = children.get(0); - assertEquals( "LabelScan", child.operatorType() ); - assertEquals( singletonMap( "x", value( 1 ) ), child.arguments() ); - assertEquals( asList( "y", "z" ), child.identifiers() ); - assertEquals( 2, child.records() ); - assertEquals( 4, child.dbHits() ); + assertEquals("LabelScan", child.operatorType()); + assertEquals(singletonMap("x", value(1)), child.arguments()); + assertEquals(asList("y", "z"), child.identifiers()); + assertEquals(2, child.records()); + assertEquals(4, child.dbHits()); } @Test - void shouldBuildResultSummaryWithoutProfiledPlan() - { - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, emptyMap() ); - assertFalse( summary.hasProfile() ); - assertNull( summary.profile() ); + void shouldBuildResultSummaryWithoutProfiledPlan() { + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, emptyMap()); + assertFalse(summary.hasProfile()); + assertNull(summary.profile()); } @Test - void shouldBuildResultSummaryWithNotifications() - { + void shouldBuildResultSummaryWithNotifications() { Value notification1 = parameters( "description", "Almost bad thing", "code", "Neo.DummyNotification", "title", "A title", "severity", "WARNING", - "position", parameters( - "offset", 42, - "line", 4242, - "column", 424242 - ) - ); + "position", + parameters( + "offset", 42, + "line", 4242, + "column", 424242)); Value notification2 = parameters( "description", "Almost good thing", "code", "Neo.GoodNotification", "title", "Good", "severity", "INFO", - "position", parameters( - "offset", 1, - "line", 2, - "column", 3 - ) - ); - Value notifications = value( notification1, notification2 ); - Map metadata = singletonMap( "notifications", notifications ); - - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, metadata ); - - assertEquals( 2, summary.notifications().size() ); - Notification firstNotification = summary.notifications().get( 0 ); - Notification secondNotification = summary.notifications().get( 1 ); - - assertEquals( "Almost bad thing", firstNotification.description() ); - assertEquals( "Neo.DummyNotification", firstNotification.code() ); - assertEquals( "A title", firstNotification.title() ); - assertEquals( "WARNING", firstNotification.severity() ); - assertEquals( new InternalInputPosition( 42, 4242, 424242 ), firstNotification.position() ); - - assertEquals( "Almost good thing", secondNotification.description() ); - assertEquals( "Neo.GoodNotification", secondNotification.code() ); - assertEquals( "Good", secondNotification.title() ); - assertEquals( "INFO", secondNotification.severity() ); - assertEquals( new InternalInputPosition( 1, 2, 3 ), secondNotification.position() ); + "position", + parameters( + "offset", 1, + "line", 2, + "column", 3)); + Value notifications = value(notification1, notification2); + Map metadata = singletonMap("notifications", notifications); + + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, metadata); + + assertEquals(2, summary.notifications().size()); + Notification firstNotification = summary.notifications().get(0); + Notification secondNotification = summary.notifications().get(1); + + assertEquals("Almost bad thing", firstNotification.description()); + assertEquals("Neo.DummyNotification", firstNotification.code()); + assertEquals("A title", firstNotification.title()); + assertEquals("WARNING", firstNotification.severity()); + assertEquals(new InternalInputPosition(42, 4242, 424242), firstNotification.position()); + + assertEquals("Almost good thing", secondNotification.description()); + assertEquals("Neo.GoodNotification", secondNotification.code()); + assertEquals("Good", secondNotification.title()); + assertEquals("INFO", secondNotification.severity()); + assertEquals(new InternalInputPosition(1, 2, 3), secondNotification.position()); } @Test - void shouldBuildResultSummaryWithoutNotifications() - { - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, emptyMap() ); - assertEquals( 0, summary.notifications().size() ); + void shouldBuildResultSummaryWithoutNotifications() { + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, emptyMap()); + assertEquals(0, summary.notifications().size()); } @Test - void shouldBuildResultSummaryWithResultAvailableAfter() - { + void shouldBuildResultSummaryWithResultAvailableAfter() { int value = 42_000; - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), value, emptyMap() ); + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), value, emptyMap()); - assertEquals( 42, summary.resultAvailableAfter( TimeUnit.SECONDS ) ); - assertEquals( value, summary.resultAvailableAfter( TimeUnit.MILLISECONDS ) ); + assertEquals(42, summary.resultAvailableAfter(TimeUnit.SECONDS)); + assertEquals(value, summary.resultAvailableAfter(TimeUnit.MILLISECONDS)); } @Test - void shouldBuildResultSummaryWithResultConsumedAfter() - { + void shouldBuildResultSummaryWithResultConsumedAfter() { int value = 42_000; - Map metadata = singletonMap( RESULT_CONSUMED_AFTER_KEY, value( value ) ); + Map metadata = singletonMap(RESULT_CONSUMED_AFTER_KEY, value(value)); - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, metadata ); + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, metadata); - assertEquals( 42, summary.resultConsumedAfter( TimeUnit.SECONDS ) ); - assertEquals( value, summary.resultConsumedAfter( TimeUnit.MILLISECONDS ) ); + assertEquals(42, summary.resultConsumedAfter(TimeUnit.SECONDS)); + assertEquals(value, summary.resultConsumedAfter(TimeUnit.MILLISECONDS)); } @Test - void shouldBuildResultSummaryWithoutResultConsumedAfter() - { - ResultSummary summary = extractor.extractSummary( query(), connectionMock(), 42, emptyMap() ); - assertEquals( -1, summary.resultConsumedAfter( TimeUnit.SECONDS ) ); - assertEquals( -1, summary.resultConsumedAfter( TimeUnit.MILLISECONDS ) ); + void shouldBuildResultSummaryWithoutResultConsumedAfter() { + ResultSummary summary = extractor.extractSummary(query(), connectionMock(), 42, emptyMap()); + assertEquals(-1, summary.resultConsumedAfter(TimeUnit.SECONDS)); + assertEquals(-1, summary.resultConsumedAfter(TimeUnit.MILLISECONDS)); } @Test - void shouldExtractBookmark() - { + void shouldExtractBookmark() { String bookmarkValue = "neo4j:bookmark:v1:tx123456"; - Bookmark bookmark = extractor.extractBookmarks( singletonMap( "bookmark", value( bookmarkValue ) ) ); + Bookmark bookmark = extractor.extractBookmarks(singletonMap("bookmark", value(bookmarkValue))); - assertEquals( InternalBookmark.parse( bookmarkValue ), bookmark ); + assertEquals(InternalBookmark.parse(bookmarkValue), bookmark); } @Test - void shouldExtractNoBookmarkWhenMetadataContainsNull() - { - Bookmark bookmark = extractor.extractBookmarks( singletonMap( "bookmark", null ) ); + void shouldExtractNoBookmarkWhenMetadataContainsNull() { + Bookmark bookmark = extractor.extractBookmarks(singletonMap("bookmark", null)); - assertEquals( InternalBookmark.empty(), bookmark ); + assertEquals(InternalBookmark.empty(), bookmark); } @Test - void shouldExtractNoBookmarkWhenMetadataContainsNullValue() - { - Bookmark bookmark = extractor.extractBookmarks( singletonMap( "bookmark", Values.NULL ) ); + void shouldExtractNoBookmarkWhenMetadataContainsNullValue() { + Bookmark bookmark = extractor.extractBookmarks(singletonMap("bookmark", Values.NULL)); - assertEquals( InternalBookmark.empty(), bookmark ); + assertEquals(InternalBookmark.empty(), bookmark); } @Test - void shouldExtractNoBookmarkWhenMetadataContainsValueOfIncorrectType() - { - Bookmark bookmark = extractor.extractBookmarks( singletonMap( "bookmark", value( 42 ) ) ); + void shouldExtractNoBookmarkWhenMetadataContainsValueOfIncorrectType() { + Bookmark bookmark = extractor.extractBookmarks(singletonMap("bookmark", value(42))); - assertEquals( InternalBookmark.empty(), bookmark ); + assertEquals(InternalBookmark.empty(), bookmark); } @Test - void shouldExtractServerVersion() - { - Map metadata = singletonMap( "server", value( "Neo4j/3.5.0" ) ); + void shouldExtractServerVersion() { + Map metadata = singletonMap("server", value("Neo4j/3.5.0")); - ServerVersion version = extractNeo4jServerVersion( metadata ); + ServerVersion version = extractNeo4jServerVersion(metadata); - assertEquals( ServerVersion.v3_5_0, version ); + assertEquals(ServerVersion.v3_5_0, version); } @Test - void shouldExtractServer() - { + void shouldExtractServer() { String agent = "Neo4j/3.5.0"; - Map metadata = singletonMap( "server", value( agent ) ); + Map metadata = singletonMap("server", value(agent)); - Value serverValue = extractServer( metadata ); + Value serverValue = extractServer(metadata); - assertEquals( agent, serverValue.asString() ); + assertEquals(agent, serverValue.asString()); } @Test - void shouldExtractDatabase() - { + void shouldExtractDatabase() { // Given - Map metadata = singletonMap( "db", value( "MyAwesomeDatabase" ) ); + Map metadata = singletonMap("db", value("MyAwesomeDatabase")); // When - DatabaseInfo db = extractDatabaseInfo( metadata ); + DatabaseInfo db = extractDatabaseInfo(metadata); // Then - assertEquals( "MyAwesomeDatabase", db.name() ); + assertEquals("MyAwesomeDatabase", db.name()); } @Test - void shouldDefaultToNullDatabaseName() - { + void shouldDefaultToNullDatabaseName() { // Given - Map metadata = singletonMap( "no_db", value( "no_db" ) ); + Map metadata = singletonMap("no_db", value("no_db")); // When - DatabaseInfo db = extractDatabaseInfo( metadata ); + DatabaseInfo db = extractDatabaseInfo(metadata); // Then - assertNull( db.name() ); + assertNull(db.name()); } @Test - void shouldErrorWhenTypeIsWrong() - { + void shouldErrorWhenTypeIsWrong() { // Given - Map metadata = singletonMap( "db", value( 10L ) ); + Map metadata = singletonMap("db", value(10L)); // When - Uncoercible error = assertThrows( Uncoercible.class, () -> extractDatabaseInfo( metadata ) ); + Uncoercible error = assertThrows(Uncoercible.class, () -> extractDatabaseInfo(metadata)); // Then - assertThat( error.getMessage(), startsWith( "Cannot coerce INTEGER to Java String" ) ); + assertThat(error.getMessage(), startsWith("Cannot coerce INTEGER to Java String")); } @Test - void shouldFailToExtractServerVersionWhenMetadataDoesNotContainIt() - { - assertThrows( UntrustedServerException.class, () -> extractNeo4jServerVersion( singletonMap( "server", Values.NULL ) ) ); - assertThrows( UntrustedServerException.class, () -> extractNeo4jServerVersion( singletonMap( "server", null ) ) ); + void shouldFailToExtractServerVersionWhenMetadataDoesNotContainIt() { + assertThrows( + UntrustedServerException.class, () -> extractNeo4jServerVersion(singletonMap("server", Values.NULL))); + assertThrows(UntrustedServerException.class, () -> extractNeo4jServerVersion(singletonMap("server", null))); } @Test - void shouldFailToExtractServerVersionFromNonNeo4jProduct() - { - assertThrows( UntrustedServerException.class, () -> extractNeo4jServerVersion( singletonMap( "server", value( "NotNeo4j/1.2.3" ) ) ) ); + void shouldFailToExtractServerVersionFromNonNeo4jProduct() { + assertThrows( + UntrustedServerException.class, + () -> extractNeo4jServerVersion(singletonMap("server", value("NotNeo4j/1.2.3")))); } - private ResultSummary createWithQueryType( Value typeValue ) - { - Map metadata = singletonMap( "type", typeValue ); - return extractor.extractSummary( query(), connectionMock(), 42, metadata ); + private ResultSummary createWithQueryType(Value typeValue) { + Map metadata = singletonMap("type", typeValue); + return extractor.extractSummary(query(), connectionMock(), 42, metadata); } - private static Query query() - { - return new Query( "RETURN 1" ); + private static Query query() { + return new Query("RETURN 1"); } - private static Connection connectionMock() - { - return connectionMock( BoltServerAddress.LOCAL_DEFAULT, anyServerVersion() ); + private static Connection connectionMock() { + return connectionMock(BoltServerAddress.LOCAL_DEFAULT, anyServerVersion()); } - private static Connection connectionMock( BoltServerAddress address, ServerVersion version ) - { - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( address ); - when( connection.serverVersion() ).thenReturn( version ); - when( connection.protocol() ).thenReturn( BoltProtocolV43.INSTANCE ); - when( connection.serverAgent() ).thenReturn( "Neo4j/4.2.5" ); + private static Connection connectionMock(BoltServerAddress address, ServerVersion version) { + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(address); + when(connection.serverVersion()).thenReturn(version); + when(connection.protocol()).thenReturn(BoltProtocolV43.INSTANCE); + when(connection.serverAgent()).thenReturn("Neo4j/4.2.5"); return connection; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jEdition.java b/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jEdition.java index 4cf7bbe31a..8bde49a21b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jEdition.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jEdition.java @@ -18,28 +18,22 @@ */ package org.neo4j.driver.internal.util; -public enum Neo4jEdition -{ - UNDEFINED( "n/a" ), - COMMUNITY( "community" ), - ENTERPRISE( "enterprise" ); +public enum Neo4jEdition { + UNDEFINED("n/a"), + COMMUNITY("community"), + ENTERPRISE("enterprise"); private final String value; - Neo4jEdition( String value ) - { + Neo4jEdition(String value) { this.value = value; } - public boolean matches( String otherValue ) - { - if ( this == UNDEFINED ) - { + public boolean matches(String otherValue) { + if (this == UNDEFINED) { return true; - } - else - { - return this.value.equals( otherValue ); + } else { + return this.value.equals(otherValue); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jFeature.java b/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jFeature.java index 8cb197d449..c2b5f5560c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jFeature.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jFeature.java @@ -23,22 +23,19 @@ import static org.neo4j.driver.internal.util.ServerVersion.v3_5_0; import static org.neo4j.driver.internal.util.ServerVersion.v4_0_0; -public enum Neo4jFeature -{ - SPATIAL_TYPES( v3_4_0 ), - TEMPORAL_TYPES( v3_4_0 ), - BOLT_V3( v3_5_0 ), - BOLT_V4( v4_0_0 ); +public enum Neo4jFeature { + SPATIAL_TYPES(v3_4_0), + TEMPORAL_TYPES(v3_4_0), + BOLT_V3(v3_5_0), + BOLT_V4(v4_0_0); private final ServerVersion availableFromVersion; - Neo4jFeature( ServerVersion availableFromVersion ) - { - this.availableFromVersion = requireNonNull( availableFromVersion ); + Neo4jFeature(ServerVersion availableFromVersion) { + this.availableFromVersion = requireNonNull(availableFromVersion); } - public boolean availableIn( ServerVersion version ) - { - return version.greaterThanOrEqual( availableFromVersion ); + public boolean availableIn(ServerVersion version) { + return version.greaterThanOrEqual(availableFromVersion); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jWithFeatureCondition.java b/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jWithFeatureCondition.java index 6d85c4e006..0fb5f737b3 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jWithFeatureCondition.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/Neo4jWithFeatureCondition.java @@ -18,112 +18,105 @@ */ package org.neo4j.driver.internal.util; -import org.junit.jupiter.api.extension.ConditionEvaluationResult; -import org.junit.jupiter.api.extension.ExecutionCondition; -import org.junit.jupiter.api.extension.ExtensionContext; +import static org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled; +import static org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled; import java.lang.reflect.AnnotatedElement; import java.util.Optional; - +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtensionContext; import org.neo4j.driver.Driver; import org.neo4j.driver.Session; import org.neo4j.driver.util.Neo4jRunner; import org.neo4j.driver.util.Neo4jSettings; -import static org.junit.jupiter.api.extension.ConditionEvaluationResult.disabled; -import static org.junit.jupiter.api.extension.ConditionEvaluationResult.enabled; - -public class Neo4jWithFeatureCondition implements ExecutionCondition -{ - private static final ConditionEvaluationResult ENABLED_NOT_ANNOTATED = enabled( "Neither @EnabledOnNeo4jWith nor @DisabledOnNeo4jWith is present" ); - private static final ConditionEvaluationResult ENABLED_UNKNOWN_DB_VERSION = enabled( "Shared neo4j is not running, unable to check version" ); +public class Neo4jWithFeatureCondition implements ExecutionCondition { + private static final ConditionEvaluationResult ENABLED_NOT_ANNOTATED = + enabled("Neither @EnabledOnNeo4jWith nor @DisabledOnNeo4jWith is present"); + private static final ConditionEvaluationResult ENABLED_UNKNOWN_DB_VERSION = + enabled("Shared neo4j is not running, unable to check version"); @Override - public ConditionEvaluationResult evaluateExecutionCondition( ExtensionContext context ) - { + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { Optional elementOptional = context.getElement(); - if ( elementOptional.isPresent() ) - { + if (elementOptional.isPresent()) { AnnotatedElement element = elementOptional.get(); - EnabledOnNeo4jWith enabledAnnotation = element.getAnnotation( EnabledOnNeo4jWith.class ); - if ( enabledAnnotation != null ) - { - ConditionEvaluationResult result = checkFeatureAvailability( enabledAnnotation.value(), false ); - if ( enabledAnnotation.edition() != Neo4jEdition.UNDEFINED ) - { - result = checkEditionAvailability( result, enabledAnnotation.edition() ); - } return result; + EnabledOnNeo4jWith enabledAnnotation = element.getAnnotation(EnabledOnNeo4jWith.class); + if (enabledAnnotation != null) { + ConditionEvaluationResult result = checkFeatureAvailability(enabledAnnotation.value(), false); + if (enabledAnnotation.edition() != Neo4jEdition.UNDEFINED) { + result = checkEditionAvailability(result, enabledAnnotation.edition()); + } + return result; } - DisabledOnNeo4jWith disabledAnnotation = element.getAnnotation( DisabledOnNeo4jWith.class ); - if ( disabledAnnotation != null ) - { - return checkFeatureAvailability( disabledAnnotation.value(), true ); + DisabledOnNeo4jWith disabledAnnotation = element.getAnnotation(DisabledOnNeo4jWith.class); + if (disabledAnnotation != null) { + return checkFeatureAvailability(disabledAnnotation.value(), true); } } return ENABLED_NOT_ANNOTATED; } - private static ConditionEvaluationResult checkFeatureAvailability( Neo4jFeature feature, boolean negated ) - { + private static ConditionEvaluationResult checkFeatureAvailability(Neo4jFeature feature, boolean negated) { Driver driver = getSharedNeo4jDriver(); - if ( driver != null ) - { - ServerVersion version = ServerVersion.version( driver ); - return createResult( version, feature, negated ); + if (driver != null) { + ServerVersion version = ServerVersion.version(driver); + return createResult(version, feature, negated); } return ENABLED_UNKNOWN_DB_VERSION; } - private static ConditionEvaluationResult checkEditionAvailability( ConditionEvaluationResult previousResult, Neo4jEdition edition ) - { - if(previousResult.isDisabled()) { + private static ConditionEvaluationResult checkEditionAvailability( + ConditionEvaluationResult previousResult, Neo4jEdition edition) { + if (previousResult.isDisabled()) { return previousResult; } Driver driver = getSharedNeo4jDriver(); - if ( driver != null ) - { - try ( Session session = driver.session() ) - { - String value = session.run( "CALL dbms.components() YIELD edition" ).single().get( "edition" ).asString(); - boolean editionMatches = edition.matches( value ); + if (driver != null) { + try (Session session = driver.session()) { + String value = session.run("CALL dbms.components() YIELD edition") + .single() + .get("edition") + .asString(); + boolean editionMatches = edition.matches(value); return editionMatches - ? enabled( previousResult.getReason().map( v -> v + " and enabled" ).orElse( "Enabled" ) + " on " + value + "-edition" ) - : disabled( previousResult.getReason().map( v -> v + " but disabled" ).orElse( "Disabled" ) + " on " + value + "-edition" ); + ? enabled(previousResult + .getReason() + .map(v -> v + " and enabled") + .orElse("Enabled") + " on " + value + "-edition") + : disabled(previousResult + .getReason() + .map(v -> v + " but disabled") + .orElse("Disabled") + " on " + value + "-edition"); } } return ENABLED_UNKNOWN_DB_VERSION; } - private static ConditionEvaluationResult createResult( ServerVersion version, Neo4jFeature feature, boolean negated ) - { - if ( feature.availableIn( version ) ) - { + private static ConditionEvaluationResult createResult( + ServerVersion version, Neo4jFeature feature, boolean negated) { + if (feature.availableIn(version)) { return negated - ? disabled( "Disabled on neo4j " + version + " because it supports " + feature ) - : enabled( "Enabled on neo4j " + version + " because it supports " + feature ); - } - else - { + ? disabled("Disabled on neo4j " + version + " because it supports " + feature) + : enabled("Enabled on neo4j " + version + " because it supports " + feature); + } else { return negated - ? enabled( "Enabled on neo4j " + version + " because it does not support " + feature ) - : disabled( "Disabled on neo4j " + version + " because it does not support " + feature ); + ? enabled("Enabled on neo4j " + version + " because it does not support " + feature) + : disabled("Disabled on neo4j " + version + " because it does not support " + feature); } } - private static Driver getSharedNeo4jDriver() - { - try - { + private static Driver getSharedNeo4jDriver() { + try { Neo4jRunner runner = Neo4jRunner.getOrCreateGlobalRunner(); // ensure database is running with default credentials - runner.ensureRunning( Neo4jSettings.TEST_SETTINGS ); + runner.ensureRunning(Neo4jSettings.TEST_SETTINGS); return runner.driver(); - } - catch ( Throwable t ) - { - System.err.println( "Failed to check database version in the test execution condition" ); + } catch (Throwable t) { + System.err.println("Failed to check database version in the test execution condition"); t.printStackTrace(); return null; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/PreconditionsTest.java b/driver/src/test/java/org/neo4j/driver/internal/util/PreconditionsTest.java index 3e4de5b05f..8dcfcb9437 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/PreconditionsTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/PreconditionsTest.java @@ -18,37 +18,35 @@ */ package org.neo4j.driver.internal.util; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.internal.util.Preconditions.checkArgument; import java.time.Duration; import java.time.Period; import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.internal.util.Preconditions.checkArgument; - -class PreconditionsTest -{ +class PreconditionsTest { @Test - void shouldCheckBooleanArgument() - { - assertDoesNotThrow( () -> checkArgument( true, "" ) ); - assertDoesNotThrow( () -> checkArgument( !Duration.ofSeconds( 1 ).isZero(), "" ) ); + void shouldCheckBooleanArgument() { + assertDoesNotThrow(() -> checkArgument(true, "")); + assertDoesNotThrow(() -> checkArgument(!Duration.ofSeconds(1).isZero(), "")); - assertThrows( IllegalArgumentException.class, () -> checkArgument( false, "" ) ); - assertThrows( IllegalArgumentException.class, () -> checkArgument( Period.ofDays( 2 ).isNegative(), "" ) ); + assertThrows(IllegalArgumentException.class, () -> checkArgument(false, "")); + assertThrows( + IllegalArgumentException.class, + () -> checkArgument(Period.ofDays(2).isNegative(), "")); } @Test - void shouldCheckArgumentType() - { - assertDoesNotThrow( () -> checkArgument( "Hello", String.class ) ); - assertDoesNotThrow( () -> checkArgument( new ArrayList<>(), List.class ) ); + void shouldCheckArgumentType() { + assertDoesNotThrow(() -> checkArgument("Hello", String.class)); + assertDoesNotThrow(() -> checkArgument(new ArrayList<>(), List.class)); - assertThrows( IllegalArgumentException.class, () -> checkArgument( 42, String.class ) ); - assertThrows( IllegalArgumentException.class, () -> checkArgument( new ArrayList<>(), Map.class ) ); + assertThrows(IllegalArgumentException.class, () -> checkArgument(42, String.class)); + assertThrows(IllegalArgumentException.class, () -> checkArgument(new ArrayList<>(), Map.class)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ServerVersionTest.java b/driver/src/test/java/org/neo4j/driver/internal/util/ServerVersionTest.java index d0e880d5d0..7001e6e312 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ServerVersionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ServerVersionTest.java @@ -18,8 +18,13 @@ */ package org.neo4j.driver.internal.util; -import org.junit.jupiter.api.Test; +import static java.lang.Integer.MAX_VALUE; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.messaging.BoltProtocolVersion; import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4; import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41; @@ -27,56 +32,46 @@ import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43; import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44; -import static java.lang.Integer.MAX_VALUE; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class ServerVersionTest -{ +class ServerVersionTest { @Test - void version() - { - assertThat( ServerVersion.version( "Neo4j/dev" ), is( ServerVersion.vInDev ) ); - assertThat( ServerVersion.version( "Neo4j/4.0.0" ), is( ServerVersion.v4_0_0 ) ); + void version() { + assertThat(ServerVersion.version("Neo4j/dev"), is(ServerVersion.vInDev)); + assertThat(ServerVersion.version("Neo4j/4.0.0"), is(ServerVersion.v4_0_0)); } @Test - void shouldHaveCorrectToString() - { - assertEquals( "Neo4j/dev", ServerVersion.vInDev.toString() ); - assertEquals( "Neo4j/4.0.0", ServerVersion.v4_0_0.toString() ); - assertEquals( "Neo4j/3.5.0", ServerVersion.v3_5_0.toString() ); - assertEquals( "Neo4j/3.5.7", ServerVersion.version( "Neo4j/3.5.7" ).toString() ); + void shouldHaveCorrectToString() { + assertEquals("Neo4j/dev", ServerVersion.vInDev.toString()); + assertEquals("Neo4j/4.0.0", ServerVersion.v4_0_0.toString()); + assertEquals("Neo4j/3.5.0", ServerVersion.v3_5_0.toString()); + assertEquals("Neo4j/3.5.7", ServerVersion.version("Neo4j/3.5.7").toString()); } @Test - void shouldFailToParseIllegalVersions() - { - assertThrows( IllegalArgumentException.class, () -> ServerVersion.version( "" ) ); - assertThrows( IllegalArgumentException.class, () -> ServerVersion.version( "/1.2.3" ) ); - assertThrows( IllegalArgumentException.class, () -> ServerVersion.version( "Neo4j1.2.3" ) ); - assertThrows( IllegalArgumentException.class, () -> ServerVersion.version( "Neo4j" ) ); + void shouldFailToParseIllegalVersions() { + assertThrows(IllegalArgumentException.class, () -> ServerVersion.version("")); + assertThrows(IllegalArgumentException.class, () -> ServerVersion.version("/1.2.3")); + assertThrows(IllegalArgumentException.class, () -> ServerVersion.version("Neo4j1.2.3")); + assertThrows(IllegalArgumentException.class, () -> ServerVersion.version("Neo4j")); } @Test - void shouldFailToCompareDifferentProducts() - { - ServerVersion version1 = ServerVersion.version( "MyNeo4j/1.2.3" ); - ServerVersion version2 = ServerVersion.version( "OtherNeo4j/1.2.4" ); + void shouldFailToCompareDifferentProducts() { + ServerVersion version1 = ServerVersion.version("MyNeo4j/1.2.3"); + ServerVersion version2 = ServerVersion.version("OtherNeo4j/1.2.4"); - assertThrows( IllegalArgumentException.class, () -> version1.greaterThanOrEqual( version2 ) ); + assertThrows(IllegalArgumentException.class, () -> version1.greaterThanOrEqual(version2)); } @Test - void shouldReturnCorrectServerVersionFromBoltProtocolVersion() - { - assertEquals( ServerVersion.v4_0_0, ServerVersion.fromBoltProtocolVersion( BoltProtocolV4.VERSION ) ); - assertEquals( ServerVersion.v4_1_0, ServerVersion.fromBoltProtocolVersion( BoltProtocolV41.VERSION ) ); - assertEquals( ServerVersion.v4_2_0, ServerVersion.fromBoltProtocolVersion( BoltProtocolV42.VERSION ) ); - assertEquals( ServerVersion.v4_3_0, ServerVersion.fromBoltProtocolVersion( BoltProtocolV43.VERSION ) ); - assertEquals( ServerVersion.v4_4_0, ServerVersion.fromBoltProtocolVersion( BoltProtocolV44.VERSION ) ); - assertEquals( ServerVersion.vInDev, ServerVersion.fromBoltProtocolVersion( new BoltProtocolVersion( MAX_VALUE, MAX_VALUE ) ) ); + void shouldReturnCorrectServerVersionFromBoltProtocolVersion() { + assertEquals(ServerVersion.v4_0_0, ServerVersion.fromBoltProtocolVersion(BoltProtocolV4.VERSION)); + assertEquals(ServerVersion.v4_1_0, ServerVersion.fromBoltProtocolVersion(BoltProtocolV41.VERSION)); + assertEquals(ServerVersion.v4_2_0, ServerVersion.fromBoltProtocolVersion(BoltProtocolV42.VERSION)); + assertEquals(ServerVersion.v4_3_0, ServerVersion.fromBoltProtocolVersion(BoltProtocolV43.VERSION)); + assertEquals(ServerVersion.v4_4_0, ServerVersion.fromBoltProtocolVersion(BoltProtocolV44.VERSION)); + assertEquals( + ServerVersion.vInDev, + ServerVersion.fromBoltProtocolVersion(new BoltProtocolVersion(MAX_VALUE, MAX_VALUE))); } } 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 index 8b7e29c042..2998e64959 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/SleeplessClock.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/SleeplessClock.java @@ -18,28 +18,22 @@ */ package org.neo4j.driver.internal.util; -public final class SleeplessClock implements Clock -{ +public final class SleeplessClock implements Clock { private final Clock delegate; - public SleeplessClock() - { - this( Clock.SYSTEM ); + public SleeplessClock() { + this(Clock.SYSTEM); } - public SleeplessClock( Clock delegate ) - { + public SleeplessClock(Clock delegate) { this.delegate = delegate; } @Override - public long millis() - { + public long millis() { return delegate.millis(); } @Override - public void sleep( long millis ) throws InterruptedException - { - } + public void sleep(long millis) throws InterruptedException {} } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ThrowingConsumer.java b/driver/src/test/java/org/neo4j/driver/internal/util/ThrowingConsumer.java index 95b3c05b1d..aaf4136758 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ThrowingConsumer.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ThrowingConsumer.java @@ -19,7 +19,6 @@ package org.neo4j.driver.internal.util; @FunctionalInterface -public interface ThrowingConsumer -{ - void accept( T t ) throws Exception; +public interface ThrowingConsumer { + void accept(T t) throws Exception; } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ThrowingMessageEncoder.java b/driver/src/test/java/org/neo4j/driver/internal/util/ThrowingMessageEncoder.java index f23cabf6ff..0c9fe50265 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ThrowingMessageEncoder.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ThrowingMessageEncoder.java @@ -20,23 +20,19 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageEncoder; - import java.util.List; -public class ThrowingMessageEncoder extends MessageToMessageEncoder -{ +public class ThrowingMessageEncoder extends MessageToMessageEncoder { private final RuntimeException error; - private ThrowingMessageEncoder( Class messageType, RuntimeException error ) - { - super( messageType ); + private ThrowingMessageEncoder(Class messageType, RuntimeException error) { + super(messageType); this.error = error; } @Override - protected void encode( ChannelHandlerContext ctx, T msg, List out ) - { - ctx.pipeline().remove( this ); + protected void encode(ChannelHandlerContext ctx, T msg, List out) { + ctx.pipeline().remove(this); throw error; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ValueFactory.java b/driver/src/test/java/org/neo4j/driver/internal/util/ValueFactory.java index 38d27bc076..ba9dc404cd 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ValueFactory.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ValueFactory.java @@ -18,49 +18,43 @@ */ package org.neo4j.driver.internal.util; -import java.util.HashMap; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static org.neo4j.driver.Values.value; +import java.util.HashMap; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalNode; import org.neo4j.driver.internal.InternalPath; import org.neo4j.driver.internal.InternalRelationship; import org.neo4j.driver.internal.value.NodeValue; import org.neo4j.driver.internal.value.PathValue; import org.neo4j.driver.internal.value.RelationshipValue; -import org.neo4j.driver.Value; - -import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; -import static org.neo4j.driver.Values.value; -public class ValueFactory -{ - public static NodeValue emptyNodeValue() - { - return new NodeValue( new InternalNode( 1234, singletonList( "User" ), new HashMap() ) ); +public class ValueFactory { + public static NodeValue emptyNodeValue() { + return new NodeValue(new InternalNode(1234, singletonList("User"), new HashMap())); } - public static NodeValue filledNodeValue() - { - return new NodeValue( new InternalNode( 1234, singletonList( "User" ), singletonMap( "name", value( "Dodo" ) ) ) ); + public static NodeValue filledNodeValue() { + return new NodeValue(new InternalNode(1234, singletonList("User"), singletonMap("name", value("Dodo")))); } - public static RelationshipValue emptyRelationshipValue() - { - return new RelationshipValue( new InternalRelationship( 1234, 1, 2, "KNOWS" ) ); + public static RelationshipValue emptyRelationshipValue() { + return new RelationshipValue(new InternalRelationship(1234, 1, 2, "KNOWS")); } - public static RelationshipValue filledRelationshipValue() - { - return new RelationshipValue( new InternalRelationship( 1234, 1, 2, "KNOWS", singletonMap( "name", value( "Dodo" ) ) ) ); + public static RelationshipValue filledRelationshipValue() { + return new RelationshipValue( + new InternalRelationship(1234, 1, 2, "KNOWS", singletonMap("name", value("Dodo")))); } - public static PathValue filledPathValue() - { - return new PathValue( new InternalPath( new InternalNode(42L), new InternalRelationship( 43L, 42L, 44L, "T" ), new InternalNode( 44L ) ) ); + public static PathValue filledPathValue() { + return new PathValue(new InternalPath( + new InternalNode(42L), new InternalRelationship(43L, 42L, 44L, "T"), new InternalNode(44L))); } - public static PathValue emptyPathValue() - { - return new PathValue( new InternalPath( new InternalNode( 1 ) ) ); + public static PathValue emptyPathValue() { + return new PathValue(new InternalPath(new InternalNode(1))); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/io/BufferedChannelInput.java b/driver/src/test/java/org/neo4j/driver/internal/util/io/BufferedChannelInput.java index d248875d00..f4df895f6f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/io/BufferedChannelInput.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/io/BufferedChannelInput.java @@ -22,127 +22,104 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.ReadableByteChannel; - import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.packstream.PackStream; /** * An {@link PackInput} implementation that reads from an input channel into an internal buffer. */ -public class BufferedChannelInput implements PackInput -{ +public class BufferedChannelInput implements PackInput { private final ByteBuffer buffer; private ReadableByteChannel channel; private static final int DEFAULT_BUFFER_CAPACITY = 8192; - public BufferedChannelInput(ReadableByteChannel ch ) - { - this( DEFAULT_BUFFER_CAPACITY, ch ); + public BufferedChannelInput(ReadableByteChannel ch) { + this(DEFAULT_BUFFER_CAPACITY, ch); } - public BufferedChannelInput( int bufferCapacity, ReadableByteChannel ch ) - { - this.buffer = ByteBuffer.allocate( bufferCapacity ).order( ByteOrder.BIG_ENDIAN ); - this.buffer.limit( 0 ); + public BufferedChannelInput(int bufferCapacity, ReadableByteChannel ch) { + this.buffer = ByteBuffer.allocate(bufferCapacity).order(ByteOrder.BIG_ENDIAN); + this.buffer.limit(0); this.channel = ch; } @Override - public byte readByte() throws IOException - { - ensure( 1 ); + public byte readByte() throws IOException { + ensure(1); return buffer.get(); } @Override - public short readShort() throws IOException - { - ensure( 2 ); + public short readShort() throws IOException { + ensure(2); return buffer.getShort(); } @Override - public int readInt() throws IOException - { - ensure( 4 ); + public int readInt() throws IOException { + ensure(4); return buffer.getInt(); } @Override - public long readLong() throws IOException - { - ensure( 8 ); + public long readLong() throws IOException { + ensure(8); return buffer.getLong(); } @Override - public double readDouble() throws IOException - { - ensure( 8 ); + public double readDouble() throws IOException { + ensure(8); return buffer.getDouble(); } @Override - public void readBytes( byte[] into, int index, int toRead ) throws IOException - { + public void readBytes(byte[] into, int index, int toRead) throws IOException { int endIndex = index + toRead; - while ( index < endIndex) - { - toRead = Math.min( buffer.remaining(), endIndex - index ); - buffer.get( into, index, toRead ); + while (index < endIndex) { + toRead = Math.min(buffer.remaining(), endIndex - index); + buffer.get(into, index, toRead); index += toRead; - if ( buffer.remaining() == 0 && index < endIndex ) - { - attempt( endIndex - index ); - if ( buffer.remaining() == 0 ) - { - throw new PackStream.EndOfStream( "Expected " + (endIndex - index) + " bytes available, " + - "but no more bytes accessible from underlying stream." ); + if (buffer.remaining() == 0 && index < endIndex) { + attempt(endIndex - index); + if (buffer.remaining() == 0) { + throw new PackStream.EndOfStream("Expected " + (endIndex - index) + " bytes available, " + + "but no more bytes accessible from underlying stream."); } } } } @Override - public byte peekByte() throws IOException - { - ensure( 1 ); - return buffer.get( buffer.position() ); + public byte peekByte() throws IOException { + ensure(1); + return buffer.get(buffer.position()); } - private boolean attempt( int numBytes ) throws IOException - { - if ( buffer.remaining() >= numBytes ) - { + private boolean attempt(int numBytes) throws IOException { + if (buffer.remaining() >= numBytes) { return true; } - if ( buffer.remaining() > 0 ) - { + if (buffer.remaining() > 0) { // If there is data remaining in the buffer, shift that remaining data to the beginning of the buffer. buffer.compact(); - } - else - { + } else { buffer.clear(); } int count; - do - { - count = channel.read( buffer ); - } - while ( count >= 0 && (buffer.position() < numBytes && buffer.remaining() != 0) ); + do { + count = channel.read(buffer); + } while (count >= 0 && (buffer.position() < numBytes && buffer.remaining() != 0)); buffer.flip(); return buffer.remaining() >= numBytes; } - private void ensure( int numBytes ) throws IOException - { - if ( !attempt( numBytes ) ) - { - throw new PackStream.EndOfStream( "Unexpected end of stream while trying to read " + numBytes + " bytes." ); + private void ensure(int numBytes) throws IOException { + if (!attempt(numBytes)) { + throw new PackStream.EndOfStream("Unexpected end of stream while trying to read " + numBytes + " bytes."); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/io/ByteBufOutput.java b/driver/src/test/java/org/neo4j/driver/internal/util/io/ByteBufOutput.java index 91de114c9a..514f43c8a5 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/io/ByteBufOutput.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/io/ByteBufOutput.java @@ -19,57 +19,48 @@ package org.neo4j.driver.internal.util.io; import io.netty.buffer.ByteBuf; - import org.neo4j.driver.internal.packstream.PackOutput; -public class ByteBufOutput implements PackOutput -{ +public class ByteBufOutput implements PackOutput { private final ByteBuf buf; - public ByteBufOutput( ByteBuf buf ) - { + public ByteBufOutput(ByteBuf buf) { this.buf = buf; } @Override - public PackOutput writeByte( byte value ) - { - buf.writeByte( value ); + public PackOutput writeByte(byte value) { + buf.writeByte(value); return this; } @Override - public PackOutput writeBytes( byte[] data ) - { - buf.writeBytes( data ); + public PackOutput writeBytes(byte[] data) { + buf.writeBytes(data); return this; } @Override - public PackOutput writeShort( short value ) - { - buf.writeShort( value ); + public PackOutput writeShort(short value) { + buf.writeShort(value); return this; } @Override - public PackOutput writeInt( int value ) - { - buf.writeInt( value ); + public PackOutput writeInt(int value) { + buf.writeInt(value); return this; } @Override - public PackOutput writeLong( long value ) - { - buf.writeLong( value ); + public PackOutput writeLong(long value) { + buf.writeLong(value); return this; } @Override - public PackOutput writeDouble( double value ) - { - buf.writeDouble( value ); + public PackOutput writeDouble(double value) { + buf.writeDouble(value); return this; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelOutput.java b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelOutput.java index c221883cc0..c6e4bdadf7 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelOutput.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelOutput.java @@ -21,69 +21,60 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.WritableByteChannel; - import org.neo4j.driver.internal.packstream.PackOutput; -public class ChannelOutput implements PackOutput -{ +public class ChannelOutput implements PackOutput { private final WritableByteChannel channel; - public ChannelOutput( WritableByteChannel channel ) - { + public ChannelOutput(WritableByteChannel channel) { this.channel = channel; } @Override - public PackOutput writeBytes( byte[] data ) throws IOException - { - channel.write( ByteBuffer.wrap( data ) ); + public PackOutput writeBytes(byte[] data) throws IOException { + channel.write(ByteBuffer.wrap(data)); return this; } @Override - public PackOutput writeByte( byte value ) throws IOException - { - channel.write( ByteBuffer.wrap( new byte[]{value} ) ); + public PackOutput writeByte(byte value) throws IOException { + channel.write(ByteBuffer.wrap(new byte[] {value})); return this; } @Override - public PackOutput writeShort( short value ) throws IOException - { - ByteBuffer buffer = ByteBuffer.allocate( Short.BYTES ); - buffer.putShort( value ); + public PackOutput writeShort(short value) throws IOException { + ByteBuffer buffer = ByteBuffer.allocate(Short.BYTES); + buffer.putShort(value); buffer.flip(); - channel.write( buffer ); + channel.write(buffer); return this; } @Override - public PackOutput writeInt( int value ) throws IOException - { - ByteBuffer buffer = ByteBuffer.allocate( Integer.BYTES ); - buffer.putInt( value ); + public PackOutput writeInt(int value) throws IOException { + ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); + buffer.putInt(value); buffer.flip(); - channel.write( buffer ); + channel.write(buffer); return this; } @Override - public PackOutput writeLong( long value ) throws IOException - { - ByteBuffer buffer = ByteBuffer.allocate( Long.BYTES ); - buffer.putLong( value ); + public PackOutput writeLong(long value) throws IOException { + ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); + buffer.putLong(value); buffer.flip(); - channel.write( buffer ); + channel.write(buffer); return this; } @Override - public PackOutput writeDouble( double value ) throws IOException - { - ByteBuffer buffer = ByteBuffer.allocate( Double.BYTES ); - buffer.putDouble( value ); + public PackOutput writeDouble(double value) throws IOException { + ByteBuffer buffer = ByteBuffer.allocate(Double.BYTES); + buffer.putDouble(value); buffer.flip(); - channel.write( buffer ); + channel.write(buffer); return this; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelPipelineBuilderWithFailingMessageFormat.java b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelPipelineBuilderWithFailingMessageFormat.java index 0f07c9c985..7217e86384 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelPipelineBuilderWithFailingMessageFormat.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelPipelineBuilderWithFailingMessageFormat.java @@ -19,29 +19,24 @@ package org.neo4j.driver.internal.util.io; import io.netty.channel.ChannelPipeline; - +import org.neo4j.driver.Logging; import org.neo4j.driver.internal.async.connection.ChannelPipelineBuilder; import org.neo4j.driver.internal.async.connection.ChannelPipelineBuilderImpl; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.util.FailingMessageFormat; -import org.neo4j.driver.Logging; -public class ChannelPipelineBuilderWithFailingMessageFormat implements ChannelPipelineBuilder -{ +public class ChannelPipelineBuilderWithFailingMessageFormat implements ChannelPipelineBuilder { private volatile FailingMessageFormat failingMessageFormat; @Override - public void build( MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging ) - { - if ( failingMessageFormat == null ) - { - failingMessageFormat = new FailingMessageFormat( messageFormat ); + public void build(MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging) { + if (failingMessageFormat == null) { + failingMessageFormat = new FailingMessageFormat(messageFormat); } - new ChannelPipelineBuilderImpl().build( failingMessageFormat, pipeline, logging ); + new ChannelPipelineBuilderImpl().build(failingMessageFormat, pipeline, logging); } - FailingMessageFormat getFailingMessageFormat() - { + FailingMessageFormat getFailingMessageFormat() { return failingMessageFormat; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingConnector.java b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingConnector.java index 03f0b1e6f0..e100c41318 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingConnector.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/io/ChannelTrackingConnector.java @@ -21,28 +21,23 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; - import java.util.List; - import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.connection.ChannelConnector; -public class ChannelTrackingConnector implements ChannelConnector -{ +public class ChannelTrackingConnector implements ChannelConnector { private final ChannelConnector realConnector; private final List channels; - public ChannelTrackingConnector( ChannelConnector realConnector, List channels ) - { + public ChannelTrackingConnector(ChannelConnector realConnector, List channels) { this.realConnector = realConnector; this.channels = channels; } @Override - public ChannelFuture connect( BoltServerAddress address, Bootstrap bootstrap ) - { - ChannelFuture channelFuture = realConnector.connect( address, bootstrap ); - channels.add( channelFuture.channel() ); + public ChannelFuture connect(BoltServerAddress address, Bootstrap bootstrap) { + ChannelFuture channelFuture = realConnector.connect(address, bootstrap); + channels.add(channelFuture.channel()); return channelFuture; } } 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 893ddc28fe..008fe9f94a 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,11 +20,9 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; - import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.Config; import org.neo4j.driver.internal.BoltServerAddress; @@ -38,74 +36,78 @@ import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.DriverFactoryWithClock; -public class ChannelTrackingDriverFactory extends DriverFactoryWithClock -{ +public class ChannelTrackingDriverFactory extends DriverFactoryWithClock { private final List channels = new CopyOnWriteArrayList<>(); private final int eventLoopThreads; private ConnectionPool pool; - public ChannelTrackingDriverFactory() - { - this( 0, Clock.SYSTEM ); + public ChannelTrackingDriverFactory() { + this(0, Clock.SYSTEM); } - public ChannelTrackingDriverFactory( Clock clock ) - { - this( 0, clock ); + public ChannelTrackingDriverFactory(Clock clock) { + this(0, clock); } - public ChannelTrackingDriverFactory( int eventLoopThreads, Clock clock ) - { - super( clock ); + public ChannelTrackingDriverFactory(int eventLoopThreads, Clock clock) { + super(clock); this.eventLoopThreads = eventLoopThreads; } @Override - protected Bootstrap createBootstrap( int size ) - { - return BootstrapFactory.newBootstrap( eventLoopThreads ); + protected Bootstrap createBootstrap(int size) { + return BootstrapFactory.newBootstrap(eventLoopThreads); } @Override - protected final ChannelConnector createConnector( ConnectionSettings settings, SecurityPlan securityPlan, - Config config, Clock clock, RoutingContext routingContext ) - { - return createChannelTrackingConnector( createRealConnector( settings, securityPlan, config, clock, routingContext ) ); + protected final ChannelConnector createConnector( + ConnectionSettings settings, + SecurityPlan securityPlan, + Config config, + Clock clock, + RoutingContext routingContext) { + return createChannelTrackingConnector( + createRealConnector(settings, securityPlan, config, clock, routingContext)); } @Override - protected final ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, - MetricsProvider metricsProvider, Config config, boolean ownsEventLoopGroup, RoutingContext routingContext ) - { - pool = super.createConnectionPool( authToken, securityPlan, bootstrap, metricsProvider, config, ownsEventLoopGroup, routingContext ); + protected final ConnectionPool createConnectionPool( + AuthToken authToken, + SecurityPlan securityPlan, + Bootstrap bootstrap, + MetricsProvider metricsProvider, + Config config, + boolean ownsEventLoopGroup, + RoutingContext routingContext) { + pool = super.createConnectionPool( + authToken, securityPlan, bootstrap, metricsProvider, config, ownsEventLoopGroup, routingContext); return pool; } - protected ChannelConnector createRealConnector( ConnectionSettings settings, SecurityPlan securityPlan, - Config config, Clock clock, RoutingContext routingContext ) - { - return super.createConnector( settings, securityPlan, config, clock, routingContext ); + protected ChannelConnector createRealConnector( + ConnectionSettings settings, + SecurityPlan securityPlan, + Config config, + Clock clock, + RoutingContext routingContext) { + return super.createConnector(settings, securityPlan, config, clock, routingContext); } - private ChannelTrackingConnector createChannelTrackingConnector( ChannelConnector connector ) - { - return new ChannelTrackingConnector( connector, channels ); + private ChannelTrackingConnector createChannelTrackingConnector(ChannelConnector connector) { + return new ChannelTrackingConnector(connector, channels); } - public List channels() - { - return new ArrayList<>( channels ); + public List channels() { + return new ArrayList<>(channels); } - public List pollChannels() - { - List result = new ArrayList<>( channels ); + public List pollChannels() { + List result = new ArrayList<>(channels); channels.clear(); return result; } - public int activeChannels( BoltServerAddress address ) - { - return pool == null ? 0 : pool.inUseConnections( address ); + public int activeChannels(BoltServerAddress address) { + return pool == null ? 0 : pool.inUseConnections(address); } } 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 7bc9faa59a..432da52906 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 @@ -28,26 +28,32 @@ import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.util.FailingMessageFormat; -public class ChannelTrackingDriverFactoryWithFailingMessageFormat extends ChannelTrackingDriverFactory -{ - private final ChannelPipelineBuilderWithFailingMessageFormat pipelineBuilder = new ChannelPipelineBuilderWithFailingMessageFormat(); +public class ChannelTrackingDriverFactoryWithFailingMessageFormat extends ChannelTrackingDriverFactory { + private final ChannelPipelineBuilderWithFailingMessageFormat pipelineBuilder = + new ChannelPipelineBuilderWithFailingMessageFormat(); - public ChannelTrackingDriverFactoryWithFailingMessageFormat( Clock clock ) - { - super( clock ); + public ChannelTrackingDriverFactoryWithFailingMessageFormat(Clock clock) { + super(clock); } @Override - protected ChannelConnector createRealConnector( ConnectionSettings settings, SecurityPlan securityPlan, - Config config, Clock clock, RoutingContext routingContext ) - { - return new ChannelConnectorImpl( settings, securityPlan, pipelineBuilder, config.logging(), clock, routingContext, - DefaultDomainNameResolver.getInstance() ); + protected ChannelConnector createRealConnector( + ConnectionSettings settings, + SecurityPlan securityPlan, + Config config, + Clock clock, + RoutingContext routingContext) { + return new ChannelConnectorImpl( + settings, + securityPlan, + pipelineBuilder, + config.logging(), + clock, + routingContext, + DefaultDomainNameResolver.getInstance()); } - public FailingMessageFormat getFailingMessageFormat() - { + public FailingMessageFormat getFailingMessageFormat() { return pipelineBuilder.getFailingMessageFormat(); } } - diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/io/MessageToByteBufWriter.java b/driver/src/test/java/org/neo4j/driver/internal/util/io/MessageToByteBufWriter.java index 816de8cb96..db7a518019 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/io/MessageToByteBufWriter.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/io/MessageToByteBufWriter.java @@ -20,33 +20,25 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; - import java.io.IOException; - import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageFormat; -public class MessageToByteBufWriter -{ +public class MessageToByteBufWriter { private final MessageFormat messageFormat; - public MessageToByteBufWriter( MessageFormat messageFormat ) - { + public MessageToByteBufWriter(MessageFormat messageFormat) { this.messageFormat = messageFormat; } - public ByteBuf asByteBuf( Message message ) - { - try - { + public ByteBuf asByteBuf(Message message) { + try { ByteBuf buf = Unpooled.buffer(); - ByteBufOutput output = new ByteBufOutput( buf ); - messageFormat.newWriter( output ).write( message ); + ByteBufOutput output = new ByteBufOutput(buf); + messageFormat.newWriter(output).write(message); return buf; - } - catch ( IOException e ) - { - throw new RuntimeException( e ); + } catch (IOException e) { + throw new RuntimeException(e); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/AbstractMessageReaderTestBase.java b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/AbstractMessageReaderTestBase.java index 259c30a72a..315b28de91 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/AbstractMessageReaderTestBase.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/AbstractMessageReaderTestBase.java @@ -18,14 +18,18 @@ */ package org.neo4j.driver.internal.util.messaging; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import org.junit.jupiter.api.DynamicNode; -import org.junit.jupiter.api.TestFactory; - import java.io.IOException; import java.util.stream.Stream; - +import org.junit.jupiter.api.DynamicNode; +import org.junit.jupiter.api.TestFactory; import org.neo4j.driver.internal.async.inbound.ByteBufInput; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageFormat; @@ -37,89 +41,67 @@ import org.neo4j.driver.internal.packstream.PackInput; import org.neo4j.driver.internal.util.io.ByteBufOutput; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; -import static org.junit.jupiter.api.DynamicTest.dynamicTest; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public abstract class AbstractMessageReaderTestBase -{ +public abstract class AbstractMessageReaderTestBase { @TestFactory - Stream shouldReadSupportedMessages() - { - return supportedMessages().map( message -> - dynamicTest( message.toString(), () -> testSupportedMessageReading( message ) ) ); + Stream shouldReadSupportedMessages() { + return supportedMessages() + .map(message -> dynamicTest(message.toString(), () -> testSupportedMessageReading(message))); } - private void testSupportedMessageReading( Message message ) throws IOException - { - ResponseMessageHandler handler = testMessageReading( message ); + private void testSupportedMessageReading(Message message) throws IOException { + ResponseMessageHandler handler = testMessageReading(message); - if ( message instanceof SuccessMessage ) - { + if (message instanceof SuccessMessage) { SuccessMessage successMessage = (SuccessMessage) message; - verify( handler ).handleSuccessMessage( successMessage.metadata() ); - } - else if ( message instanceof FailureMessage ) - { + verify(handler).handleSuccessMessage(successMessage.metadata()); + } else if (message instanceof FailureMessage) { FailureMessage failureMessage = (FailureMessage) message; - verify( handler ).handleFailureMessage( failureMessage.code(), failureMessage.message() ); - } - else if ( message instanceof IgnoredMessage ) - { - verify( handler ).handleIgnoredMessage(); - } - else if ( message instanceof RecordMessage ) - { + verify(handler).handleFailureMessage(failureMessage.code(), failureMessage.message()); + } else if (message instanceof IgnoredMessage) { + verify(handler).handleIgnoredMessage(); + } else if (message instanceof RecordMessage) { RecordMessage recordMessage = (RecordMessage) message; - verify( handler ).handleRecordMessage( recordMessage.fields() ); - } - else - { - fail( "Unsupported message type " + message.getClass().getSimpleName() ); + verify(handler).handleRecordMessage(recordMessage.fields()); + } else { + fail("Unsupported message type " + message.getClass().getSimpleName()); } } @TestFactory - Stream shouldFailToReadUnsupportedMessages() - { - return unsupportedMessages().map( message -> - dynamicTest( message.toString(), () -> testUnsupportedMessageReading( message ) ) ); + Stream shouldFailToReadUnsupportedMessages() { + return unsupportedMessages() + .map(message -> dynamicTest(message.toString(), () -> testUnsupportedMessageReading(message))); } - private void testUnsupportedMessageReading( Message message ) throws IOException - { - assertThrows( IOException.class, () -> testMessageReading( message ) ); + private void testUnsupportedMessageReading(Message message) throws IOException { + assertThrows(IOException.class, () -> testMessageReading(message)); } protected abstract Stream supportedMessages(); protected abstract Stream unsupportedMessages(); - protected abstract MessageFormat.Reader newReader( PackInput input ); + protected abstract MessageFormat.Reader newReader(PackInput input); - protected ResponseMessageHandler testMessageReading( Message message ) throws IOException - { - PackInput input = newInputWith( message ); - MessageFormat.Reader reader = newReader( input ); + protected ResponseMessageHandler testMessageReading(Message message) throws IOException { + PackInput input = newInputWith(message); + MessageFormat.Reader reader = newReader(input); - ResponseMessageHandler handler = mock( ResponseMessageHandler.class ); - reader.read( handler ); + ResponseMessageHandler handler = mock(ResponseMessageHandler.class); + reader.read(handler); return handler; } - private static PackInput newInputWith( Message message ) throws IOException - { + private static PackInput newInputWith(Message message) throws IOException { ByteBuf buffer = Unpooled.buffer(); MessageFormat messageFormat = new KnowledgeableMessageFormat(); - MessageFormat.Writer writer = messageFormat.newWriter( new ByteBufOutput( buffer ) ); - writer.write( message ); + MessageFormat.Writer writer = messageFormat.newWriter(new ByteBufOutput(buffer)); + writer.write(message); ByteBufInput input = new ByteBufInput(); - input.start( buffer ); + input.start(buffer); return input; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/AbstractMessageWriterTestBase.java b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/AbstractMessageWriterTestBase.java index 7db15ab7ef..7f3365573c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/AbstractMessageWriterTestBase.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/AbstractMessageWriterTestBase.java @@ -18,14 +18,19 @@ */ package org.neo4j.driver.internal.util.messaging; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; +import static org.mockito.Mockito.mock; + import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import org.junit.jupiter.api.DynamicNode; -import org.junit.jupiter.api.TestFactory; - import java.io.IOException; import java.util.stream.Stream; - +import org.junit.jupiter.api.DynamicNode; +import org.junit.jupiter.api.TestFactory; import org.neo4j.driver.internal.async.inbound.ByteBufInput; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageFormat; @@ -33,57 +38,45 @@ import org.neo4j.driver.internal.packstream.PackStream; import org.neo4j.driver.internal.util.io.ByteBufOutput; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.DynamicTest.dynamicTest; -import static org.mockito.Mockito.mock; - -public abstract class AbstractMessageWriterTestBase -{ +public abstract class AbstractMessageWriterTestBase { @TestFactory - Stream shouldWriteSupportedMessages() - { - return supportedMessages().map( message -> - dynamicTest( message.toString(), () -> testSupportedMessageWriting( message ) ) ); + Stream shouldWriteSupportedMessages() { + return supportedMessages() + .map(message -> dynamicTest(message.toString(), () -> testSupportedMessageWriting(message))); } @TestFactory - Stream shouldFailToWriteUnsupportedMessages() - { - return unsupportedMessages().map( message -> - dynamicTest( message.toString(), () -> testUnsupportedMessageWriting( message ) ) ); + Stream shouldFailToWriteUnsupportedMessages() { + return unsupportedMessages() + .map(message -> dynamicTest(message.toString(), () -> testUnsupportedMessageWriting(message))); } - protected abstract MessageFormat.Writer newWriter( PackOutput output ); + protected abstract MessageFormat.Writer newWriter(PackOutput output); protected abstract Stream supportedMessages(); protected abstract Stream unsupportedMessages(); - private void testSupportedMessageWriting( Message message ) throws IOException - { + private void testSupportedMessageWriting(Message message) throws IOException { ByteBuf buffer = Unpooled.buffer(); - PackOutput output = new ByteBufOutput( buffer ); + PackOutput output = new ByteBufOutput(buffer); - MessageFormat.Writer writer = newWriter( output ); - writer.write( message ); + MessageFormat.Writer writer = newWriter(output); + writer.write(message); ByteBufInput input = new ByteBufInput(); - input.start( buffer ); - PackStream.Unpacker unpacker = new PackStream.Unpacker( input ); + input.start(buffer); + PackStream.Unpacker unpacker = new PackStream.Unpacker(input); long structHeader = unpacker.unpackStructHeader(); - assertThat( structHeader, greaterThanOrEqualTo( 0L ) ); + assertThat(structHeader, greaterThanOrEqualTo(0L)); byte structSignature = unpacker.unpackStructSignature(); - assertEquals( message.signature(), structSignature ); + assertEquals(message.signature(), structSignature); } - private void testUnsupportedMessageWriting( Message message ) - { - MessageFormat.Writer writer = newWriter( mock( PackOutput.class ) ); - assertThrows( Exception.class, () -> writer.write( message ) ); + private void testUnsupportedMessageWriting(Message message) { + MessageFormat.Writer writer = newWriter(mock(PackOutput.class)); + assertThrows(Exception.class, () -> writer.write(message)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/FailureMessageEncoder.java b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/FailureMessageEncoder.java index a3aeacc1a7..ef137ac35f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/FailureMessageEncoder.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/FailureMessageEncoder.java @@ -21,24 +21,21 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; - +import org.neo4j.driver.Value; +import org.neo4j.driver.Values; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.response.FailureMessage; -import org.neo4j.driver.Value; -import org.neo4j.driver.Values; -public class FailureMessageEncoder implements MessageEncoder -{ +public class FailureMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { + public void encode(Message message, ValuePacker packer) throws IOException { FailureMessage failureMessage = (FailureMessage) message; - packer.packStructHeader( 1, failureMessage.signature() ); - Map body = new HashMap<>(); - body.put( "code", Values.value( failureMessage.code() ) ); - body.put( "message", Values.value( failureMessage.message() ) ); - packer.pack( body ); + packer.packStructHeader(1, failureMessage.signature()); + Map body = new HashMap<>(); + body.put("code", Values.value(failureMessage.code())); + body.put("message", Values.value(failureMessage.message())); + packer.pack(body); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/IgnoredMessageEncoder.java b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/IgnoredMessageEncoder.java index 3585a4f293..1b0e5053bd 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/IgnoredMessageEncoder.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/IgnoredMessageEncoder.java @@ -19,17 +19,14 @@ package org.neo4j.driver.internal.util.messaging; import java.io.IOException; - import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.response.IgnoredMessage; -public class IgnoredMessageEncoder implements MessageEncoder -{ +public class IgnoredMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { - packer.packStructHeader( 0, IgnoredMessage.SIGNATURE ); + public void encode(Message message, ValuePacker packer) throws IOException { + packer.packStructHeader(0, IgnoredMessage.SIGNATURE); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/KnowledgeableMessageFormat.java b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/KnowledgeableMessageFormat.java index e53df8bc99..5c701a2239 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/KnowledgeableMessageFormat.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/KnowledgeableMessageFormat.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.util.Map; - import org.neo4j.driver.internal.messaging.AbstractMessageWriter; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.common.CommonValuePacker; @@ -49,154 +48,132 @@ * This class provides the missing server side packing methods to serialize Node, Relationship and Path. It also allows writing of server side messages like * SUCCESS, FAILURE, IGNORED and RECORD. */ -public class KnowledgeableMessageFormat extends MessageFormatV3 -{ +public class KnowledgeableMessageFormat extends MessageFormatV3 { @Override - public Writer newWriter( PackOutput output ) - { - return new KnowledgeableMessageWriter( output ); + public Writer newWriter(PackOutput output) { + return new KnowledgeableMessageWriter(output); } - private static class KnowledgeableMessageWriter extends AbstractMessageWriter - { - KnowledgeableMessageWriter( PackOutput output ) - { - super( new KnowledgeableValuePacker( output ), buildEncoders() ); + private static class KnowledgeableMessageWriter extends AbstractMessageWriter { + KnowledgeableMessageWriter(PackOutput output) { + super(new KnowledgeableValuePacker(output), buildEncoders()); } - static Map buildEncoders() - { - Map result = Iterables.newHashMapWithSize( 10 ); + static Map buildEncoders() { + Map result = Iterables.newHashMapWithSize(10); // request message encoders - result.put( DiscardAllMessage.SIGNATURE, new DiscardAllMessageEncoder() ); - result.put( PullAllMessage.SIGNATURE, new PullAllMessageEncoder() ); - result.put( ResetMessage.SIGNATURE, new ResetMessageEncoder() ); + result.put(DiscardAllMessage.SIGNATURE, new DiscardAllMessageEncoder()); + result.put(PullAllMessage.SIGNATURE, new PullAllMessageEncoder()); + result.put(ResetMessage.SIGNATURE, new ResetMessageEncoder()); // response message encoders - result.put( FailureMessage.SIGNATURE, new FailureMessageEncoder() ); - result.put( IgnoredMessage.SIGNATURE, new IgnoredMessageEncoder() ); - result.put( RecordMessage.SIGNATURE, new RecordMessageEncoder() ); - result.put( SuccessMessage.SIGNATURE, new SuccessMessageEncoder() ); + result.put(FailureMessage.SIGNATURE, new FailureMessageEncoder()); + result.put(IgnoredMessage.SIGNATURE, new IgnoredMessageEncoder()); + result.put(RecordMessage.SIGNATURE, new RecordMessageEncoder()); + result.put(SuccessMessage.SIGNATURE, new SuccessMessageEncoder()); return result; } } - private static class KnowledgeableValuePacker extends CommonValuePacker - { - KnowledgeableValuePacker( PackOutput output ) - { - super( output ); + private static class KnowledgeableValuePacker extends CommonValuePacker { + KnowledgeableValuePacker(PackOutput output) { + super(output); } @Override - protected void packInternalValue( InternalValue value ) throws IOException - { + protected void packInternalValue(InternalValue value) throws IOException { TypeConstructor typeConstructor = value.typeConstructor(); - switch ( typeConstructor ) - { - case NODE: - Node node = value.asNode(); - packNode( node ); - break; - - case RELATIONSHIP: - Relationship rel = value.asRelationship(); - packRelationship( rel ); - break; - - case PATH: - Path path = value.asPath(); - packPath( path ); - break; - default: - super.packInternalValue( value ); + switch (typeConstructor) { + case NODE: + Node node = value.asNode(); + packNode(node); + break; + + case RELATIONSHIP: + Relationship rel = value.asRelationship(); + packRelationship(rel); + break; + + case PATH: + Path path = value.asPath(); + packPath(path); + break; + default: + super.packInternalValue(value); } } - private void packPath( Path path ) throws IOException - { - packer.packStructHeader( 3, CommonValueUnpacker.PATH ); + private void packPath(Path path) throws IOException { + packer.packStructHeader(3, CommonValueUnpacker.PATH); // Unique nodes - Map nodeIdx = Iterables.newLinkedHashMapWithSize( path.length() + 1 ); - for ( Node node : path.nodes() ) - { - if ( !nodeIdx.containsKey( node ) ) - { - nodeIdx.put( node, nodeIdx.size() ); + Map nodeIdx = Iterables.newLinkedHashMapWithSize(path.length() + 1); + for (Node node : path.nodes()) { + if (!nodeIdx.containsKey(node)) { + nodeIdx.put(node, nodeIdx.size()); } } - packer.packListHeader( nodeIdx.size() ); - for ( Node node : nodeIdx.keySet() ) - { - packNode( node ); + packer.packListHeader(nodeIdx.size()); + for (Node node : nodeIdx.keySet()) { + packNode(node); } // Unique rels - Map relIdx = Iterables.newLinkedHashMapWithSize( path.length() ); - for ( Relationship rel : path.relationships() ) - { - if ( !relIdx.containsKey( rel ) ) - { - relIdx.put( rel, relIdx.size() + 1 ); + Map relIdx = Iterables.newLinkedHashMapWithSize(path.length()); + for (Relationship rel : path.relationships()) { + if (!relIdx.containsKey(rel)) { + relIdx.put(rel, relIdx.size() + 1); } } - packer.packListHeader( relIdx.size() ); - for ( Relationship rel : relIdx.keySet() ) - { - packer.packStructHeader( 3, CommonValueUnpacker.UNBOUND_RELATIONSHIP ); - packer.pack( rel.id() ); - packer.pack( rel.type() ); - packProperties( rel ); + packer.packListHeader(relIdx.size()); + for (Relationship rel : relIdx.keySet()) { + packer.packStructHeader(3, CommonValueUnpacker.UNBOUND_RELATIONSHIP); + packer.pack(rel.id()); + packer.pack(rel.type()); + packProperties(rel); } // Sequence - packer.packListHeader( path.length() * 2 ); - for ( Path.Segment seg : path ) - { + packer.packListHeader(path.length() * 2); + for (Path.Segment seg : path) { Relationship rel = seg.relationship(); long relEndId = rel.endNodeId(); long segEndId = seg.end().id(); - int size = relEndId == segEndId ? relIdx.get( rel ) : -relIdx.get( rel ); - packer.pack( size ); - packer.pack( nodeIdx.get( seg.end() ) ); + int size = relEndId == segEndId ? relIdx.get(rel) : -relIdx.get(rel); + packer.pack(size); + packer.pack(nodeIdx.get(seg.end())); } } - private void packRelationship( Relationship rel ) throws IOException - { - packer.packStructHeader( 5, CommonValueUnpacker.RELATIONSHIP ); - packer.pack( rel.id() ); - packer.pack( rel.startNodeId() ); - packer.pack( rel.endNodeId() ); + private void packRelationship(Relationship rel) throws IOException { + packer.packStructHeader(5, CommonValueUnpacker.RELATIONSHIP); + packer.pack(rel.id()); + packer.pack(rel.startNodeId()); + packer.pack(rel.endNodeId()); - packer.pack( rel.type() ); + packer.pack(rel.type()); - packProperties( rel ); + packProperties(rel); } - private void packNode( Node node ) throws IOException - { - packer.packStructHeader( CommonValueUnpacker.NODE_FIELDS, CommonValueUnpacker.NODE ); - packer.pack( node.id() ); + private void packNode(Node node) throws IOException { + packer.packStructHeader(CommonValueUnpacker.NODE_FIELDS, CommonValueUnpacker.NODE); + packer.pack(node.id()); Iterable labels = node.labels(); - packer.packListHeader( Iterables.count( labels ) ); - for ( String label : labels ) - { - packer.pack( label ); + packer.packListHeader(Iterables.count(labels)); + for (String label : labels) { + packer.pack(label); } - packProperties( node ); + packProperties(node); } - private void packProperties( Entity entity ) throws IOException - { + private void packProperties(Entity entity) throws IOException { Iterable keys = entity.keys(); - packer.packMapHeader( entity.size() ); - for ( String propKey : keys ) - { - packer.pack( propKey ); - packInternalValue( (InternalValue) entity.get( propKey ) ); + packer.packMapHeader(entity.size()); + for (String propKey : keys) { + packer.pack(propKey); + packInternalValue((InternalValue) entity.get(propKey)); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/MemorizingInboundMessageDispatcher.java b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/MemorizingInboundMessageDispatcher.java index eebc0e2b98..4aeec382a4 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/MemorizingInboundMessageDispatcher.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/MemorizingInboundMessageDispatcher.java @@ -19,56 +19,47 @@ package org.neo4j.driver.internal.util.messaging; import io.netty.channel.Channel; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; - +import org.neo4j.driver.Logging; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.response.FailureMessage; import org.neo4j.driver.internal.messaging.response.IgnoredMessage; import org.neo4j.driver.internal.messaging.response.RecordMessage; import org.neo4j.driver.internal.messaging.response.SuccessMessage; -import org.neo4j.driver.Logging; -import org.neo4j.driver.Value; -public class MemorizingInboundMessageDispatcher extends InboundMessageDispatcher -{ +public class MemorizingInboundMessageDispatcher extends InboundMessageDispatcher { private final List messages = new CopyOnWriteArrayList<>(); - public MemorizingInboundMessageDispatcher( Channel channel, Logging logging ) - { - super( channel, logging ); + public MemorizingInboundMessageDispatcher(Channel channel, Logging logging) { + super(channel, logging); } - public List messages() - { - return new ArrayList<>( messages ); + public List messages() { + return new ArrayList<>(messages); } @Override - public void handleSuccessMessage( Map meta ) - { - messages.add( new SuccessMessage( meta ) ); + public void handleSuccessMessage(Map meta) { + messages.add(new SuccessMessage(meta)); } @Override - public void handleRecordMessage( Value[] fields ) - { - messages.add( new RecordMessage( fields ) ); + public void handleRecordMessage(Value[] fields) { + messages.add(new RecordMessage(fields)); } @Override - public void handleFailureMessage( String code, String message ) - { - messages.add( new FailureMessage( code, message ) ); + public void handleFailureMessage(String code, String message) { + messages.add(new FailureMessage(code, message)); } @Override - public void handleIgnoredMessage() - { - messages.add( IgnoredMessage.IGNORED ); + public void handleIgnoredMessage() { + messages.add(IgnoredMessage.IGNORED); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/RecordMessageEncoder.java b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/RecordMessageEncoder.java index 7fc8f19a3e..2e97849500 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/RecordMessageEncoder.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/RecordMessageEncoder.java @@ -18,24 +18,21 @@ */ package org.neo4j.driver.internal.util.messaging; -import java.io.IOException; +import static org.neo4j.driver.Values.value; +import java.io.IOException; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.response.RecordMessage; -import org.neo4j.driver.Value; - -import static org.neo4j.driver.Values.value; -public class RecordMessageEncoder implements MessageEncoder -{ +public class RecordMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { + public void encode(Message message, ValuePacker packer) throws IOException { RecordMessage recordMessage = (RecordMessage) message; Value[] fields = recordMessage.fields(); - packer.packStructHeader( 1, recordMessage.signature() ); - packer.pack( value( fields ) ); // pack list of fields + packer.packStructHeader(1, recordMessage.signature()); + packer.pack(value(fields)); // pack list of fields } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/SuccessMessageEncoder.java b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/SuccessMessageEncoder.java index 3eb475e8bf..82ebe6ed68 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/messaging/SuccessMessageEncoder.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/messaging/SuccessMessageEncoder.java @@ -19,19 +19,16 @@ package org.neo4j.driver.internal.util.messaging; import java.io.IOException; - import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageEncoder; import org.neo4j.driver.internal.messaging.ValuePacker; import org.neo4j.driver.internal.messaging.response.SuccessMessage; -public class SuccessMessageEncoder implements MessageEncoder -{ +public class SuccessMessageEncoder implements MessageEncoder { @Override - public void encode( Message message, ValuePacker packer ) throws IOException - { + public void encode(Message message, ValuePacker packer) throws IOException { SuccessMessage successMessage = (SuccessMessage) message; - packer.packStructHeader( 1, successMessage.signature() ); - packer.pack( successMessage.metadata() ); + packer.packStructHeader(1, successMessage.signature()); + packer.pack(successMessage.metadata()); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/BooleanValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/BooleanValueTest.java index 5f5c977547..bbaf68b40e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/BooleanValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/BooleanValueTest.java @@ -18,12 +18,6 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.types.TypeSystem; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.junit.MatcherAssert.assertThat; @@ -32,85 +26,81 @@ import static org.neo4j.driver.internal.value.BooleanValue.FALSE; import static org.neo4j.driver.internal.value.BooleanValue.TRUE; -class BooleanValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.neo4j.driver.internal.types.TypeConstructor; +import org.neo4j.driver.types.TypeSystem; + +class BooleanValueTest { private TypeSystem typeSystem = InternalTypeSystem.TYPE_SYSTEM; @Test - void testBooleanTrue() - { + void testBooleanTrue() { // Given BooleanValue value = TRUE; // Then - assertThat( value.asBoolean(), equalTo( true ) ); - assertThat( value.isTrue(), equalTo( true ) ); - assertThat( value.isFalse(), equalTo( false ) ); + assertThat(value.asBoolean(), equalTo(true)); + assertThat(value.isTrue(), equalTo(true)); + assertThat(value.isFalse(), equalTo(false)); } @Test - void testBooleanFalse() - { + void testBooleanFalse() { // Given BooleanValue value = FALSE; // Then - assertThat( value.asBoolean(), equalTo( false ) ); - assertThat( value.isTrue(), equalTo( false ) ); - assertThat( value.isFalse(), equalTo( true ) ); + assertThat(value.asBoolean(), equalTo(false)); + assertThat(value.isTrue(), equalTo(false)); + assertThat(value.isFalse(), equalTo(true)); } @Test - void testIsBoolean() - { + void testIsBoolean() { // Given BooleanValue value = TRUE; // Then - assertThat( typeSystem.BOOLEAN().isTypeOf( value ), equalTo( true ) ); + assertThat(typeSystem.BOOLEAN().isTypeOf(value), equalTo(true)); } @Test - void testEquals() - { + void testEquals() { // Given BooleanValue firstValue = TRUE; BooleanValue secondValue = TRUE; // Then - assertThat( firstValue, equalTo( secondValue ) ); + assertThat(firstValue, equalTo(secondValue)); } @Test - void testHashCode() - { + void testHashCode() { // Given BooleanValue value = TRUE; // Then - assertThat( value.hashCode(), notNullValue() ); + assertThat(value.hashCode(), notNullValue()); } @Test - void shouldNotBeNull() - { - assertFalse( TRUE.isNull() ); - assertFalse( BooleanValue.FALSE.isNull() ); + void shouldNotBeNull() { + assertFalse(TRUE.isNull()); + assertFalse(BooleanValue.FALSE.isNull()); } @Test - void shouldTypeAsBoolean() - { - assertThat( TRUE.typeConstructor(), equalTo( TypeConstructor.BOOLEAN ) ); - assertThat( BooleanValue.FALSE.typeConstructor(), equalTo( TypeConstructor.BOOLEAN ) ); + void shouldTypeAsBoolean() { + assertThat(TRUE.typeConstructor(), equalTo(TypeConstructor.BOOLEAN)); + assertThat(BooleanValue.FALSE.typeConstructor(), equalTo(TypeConstructor.BOOLEAN)); } @Test - void shouldConvertToBooleanAndObject() - { - assertTrue( TRUE.asBoolean()); - assertFalse( BooleanValue.FALSE.asBoolean()); - assertThat( TRUE.asObject(), equalTo( (Object) Boolean.TRUE )); - assertThat( FALSE.asObject(), equalTo( (Object) Boolean.FALSE )); + void shouldConvertToBooleanAndObject() { + assertTrue(TRUE.asBoolean()); + assertFalse(BooleanValue.FALSE.asBoolean()); + assertThat(TRUE.asObject(), equalTo((Object) Boolean.TRUE)); + assertThat(FALSE.asObject(), equalTo((Object) Boolean.FALSE)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/BytesValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/BytesValueTest.java index 4fead4e0ff..d2ae3cf83b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/BytesValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/BytesValueTest.java @@ -18,83 +18,74 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.Value; -import org.neo4j.driver.types.TypeSystem; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; -class BytesValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.neo4j.driver.internal.types.TypeConstructor; +import org.neo4j.driver.types.TypeSystem; + +class BytesValueTest { private static final byte[] TEST_BYTES = "0123".getBytes(); private TypeSystem typeSystem = InternalTypeSystem.TYPE_SYSTEM; @Test - void testBytesValue() - { + void testBytesValue() { // Given - BytesValue value = new BytesValue( TEST_BYTES ); + BytesValue value = new BytesValue(TEST_BYTES); // Then - assertThat( value.asObject(), equalTo( TEST_BYTES ) ); + assertThat(value.asObject(), equalTo(TEST_BYTES)); } @Test - void testIsBytes() - { + void testIsBytes() { // Given - BytesValue value = new BytesValue( TEST_BYTES ); + BytesValue value = new BytesValue(TEST_BYTES); // Then - assertThat( typeSystem.BYTES().isTypeOf( value ), equalTo( true ) ); + assertThat(typeSystem.BYTES().isTypeOf(value), equalTo(true)); } @Test - void testEquals() - { + void testEquals() { // Given - BytesValue firstValue = new BytesValue( TEST_BYTES ); - BytesValue secondValue = new BytesValue( TEST_BYTES ); + BytesValue firstValue = new BytesValue(TEST_BYTES); + BytesValue secondValue = new BytesValue(TEST_BYTES); // Then - assertThat( firstValue, equalTo( secondValue ) ); + assertThat(firstValue, equalTo(secondValue)); } @Test - void testHashCode() - { + void testHashCode() { // Given - BytesValue value = new BytesValue( TEST_BYTES ); + BytesValue value = new BytesValue(TEST_BYTES); // Then - assertThat( value.hashCode(), notNullValue() ); + assertThat(value.hashCode(), notNullValue()); } @Test - void shouldNotBeNull() - { - Value value = new BytesValue( TEST_BYTES ); - assertFalse( value.isNull() ); + void shouldNotBeNull() { + Value value = new BytesValue(TEST_BYTES); + assertFalse(value.isNull()); } @Test - void shouldTypeAsString() - { - InternalValue value = new BytesValue( TEST_BYTES ); - assertThat( value.typeConstructor(), equalTo( TypeConstructor.BYTES ) ); + void shouldTypeAsString() { + InternalValue value = new BytesValue(TEST_BYTES); + assertThat(value.typeConstructor(), equalTo(TypeConstructor.BYTES)); } @Test - void shouldHaveBytesType() - { - InternalValue value = new BytesValue( TEST_BYTES ); - assertThat( value.type(), equalTo( InternalTypeSystem.TYPE_SYSTEM.BYTES() ) ); + void shouldHaveBytesType() { + InternalValue value = new BytesValue(TEST_BYTES); + assertThat(value.type(), equalTo(InternalTypeSystem.TYPE_SYSTEM.BYTES())); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/DateTimeValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/DateTimeValueTest.java index 5f28accb15..361c097254 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/DateTimeValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/DateTimeValueTest.java @@ -18,62 +18,54 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; - -import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.junit.jupiter.api.Test; import org.neo4j.driver.exceptions.value.Uncoercible; +import org.neo4j.driver.internal.types.InternalTypeSystem; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class DateTimeValueTest -{ +class DateTimeValueTest { @Test - void shouldHaveCorrectType() - { - ZonedDateTime dateTime = ZonedDateTime.of( 1991, 2, 24, 12, 0, 0, 999_000, ZoneOffset.ofHours( -5 ) ); - DateTimeValue dateTimeValue = new DateTimeValue( dateTime ); - assertEquals( InternalTypeSystem.TYPE_SYSTEM.DATE_TIME(), dateTimeValue.type() ); + void shouldHaveCorrectType() { + ZonedDateTime dateTime = ZonedDateTime.of(1991, 2, 24, 12, 0, 0, 999_000, ZoneOffset.ofHours(-5)); + DateTimeValue dateTimeValue = new DateTimeValue(dateTime); + assertEquals(InternalTypeSystem.TYPE_SYSTEM.DATE_TIME(), dateTimeValue.type()); } @Test - void shouldSupportAsObject() - { - ZonedDateTime dateTime = ZonedDateTime.of( 2015, 8, 2, 23, 59, 59, 999_999, ZoneId.of( "Europe/Stockholm" ) ); - DateTimeValue dateTimeValue = new DateTimeValue( dateTime ); - assertEquals( dateTime, dateTimeValue.asObject() ); + void shouldSupportAsObject() { + ZonedDateTime dateTime = ZonedDateTime.of(2015, 8, 2, 23, 59, 59, 999_999, ZoneId.of("Europe/Stockholm")); + DateTimeValue dateTimeValue = new DateTimeValue(dateTime); + assertEquals(dateTime, dateTimeValue.asObject()); } @Test - void shouldSupportAsZonedDateTime() - { - ZonedDateTime dateTime = ZonedDateTime.of( 1822, 9, 24, 9, 23, 57, 123, ZoneOffset.ofHoursMinutes( 12, 15 ) ); - DateTimeValue dateTimeValue = new DateTimeValue( dateTime ); - assertEquals( dateTime, dateTimeValue.asZonedDateTime() ); + void shouldSupportAsZonedDateTime() { + ZonedDateTime dateTime = ZonedDateTime.of(1822, 9, 24, 9, 23, 57, 123, ZoneOffset.ofHoursMinutes(12, 15)); + DateTimeValue dateTimeValue = new DateTimeValue(dateTime); + assertEquals(dateTime, dateTimeValue.asZonedDateTime()); } @Test - void shouldSupportAsOffsetDateTime() - { - ZonedDateTime dateTimeWithOffset = ZonedDateTime.of( 2019, 1, 2, 3, 14, 22, 100, ZoneOffset.ofHours( -5 ) ); - DateTimeValue dateTimeValue1 = new DateTimeValue( dateTimeWithOffset ); - assertEquals( dateTimeWithOffset.toOffsetDateTime(), dateTimeValue1.asOffsetDateTime() ); + void shouldSupportAsOffsetDateTime() { + ZonedDateTime dateTimeWithOffset = ZonedDateTime.of(2019, 1, 2, 3, 14, 22, 100, ZoneOffset.ofHours(-5)); + DateTimeValue dateTimeValue1 = new DateTimeValue(dateTimeWithOffset); + assertEquals(dateTimeWithOffset.toOffsetDateTime(), dateTimeValue1.asOffsetDateTime()); - ZonedDateTime dateTimeWithZoneId = ZonedDateTime.of( 2000, 11, 8, 5, 57, 59, 1, ZoneId.of( "Europe/Stockholm" ) ); - DateTimeValue dateTimeValue2 = new DateTimeValue( dateTimeWithZoneId ); - assertEquals( dateTimeWithZoneId.toOffsetDateTime(), dateTimeValue2.asOffsetDateTime() ); + ZonedDateTime dateTimeWithZoneId = ZonedDateTime.of(2000, 11, 8, 5, 57, 59, 1, ZoneId.of("Europe/Stockholm")); + DateTimeValue dateTimeValue2 = new DateTimeValue(dateTimeWithZoneId); + assertEquals(dateTimeWithZoneId.toOffsetDateTime(), dateTimeValue2.asOffsetDateTime()); } @Test - void shouldNotSupportAsLong() - { + void shouldNotSupportAsLong() { ZonedDateTime dateTime = ZonedDateTime.now(); - DateTimeValue dateTimeValue = new DateTimeValue( dateTime ); + DateTimeValue dateTimeValue = new DateTimeValue(dateTime); - assertThrows( Uncoercible.class, dateTimeValue::asLong ); + assertThrows(Uncoercible.class, dateTimeValue::asLong); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/DateValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/DateValueTest.java index f411bfaaa9..fb0d793c74 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/DateValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/DateValueTest.java @@ -18,48 +18,41 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.time.LocalDate; - -import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.junit.jupiter.api.Test; import org.neo4j.driver.exceptions.value.Uncoercible; +import org.neo4j.driver.internal.types.InternalTypeSystem; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class DateValueTest -{ +class DateValueTest { @Test - void shouldHaveCorrectType() - { + void shouldHaveCorrectType() { LocalDate localDate = LocalDate.now(); - DateValue dateValue = new DateValue( localDate ); - assertEquals( InternalTypeSystem.TYPE_SYSTEM.DATE(), dateValue.type() ); + DateValue dateValue = new DateValue(localDate); + assertEquals(InternalTypeSystem.TYPE_SYSTEM.DATE(), dateValue.type()); } @Test - void shouldSupportAsObject() - { + void shouldSupportAsObject() { LocalDate localDate = LocalDate.now(); - DateValue dateValue = new DateValue( localDate ); - assertEquals( localDate, dateValue.asObject() ); + DateValue dateValue = new DateValue(localDate); + assertEquals(localDate, dateValue.asObject()); } @Test - void shouldSupportAsLocalDate() - { + void shouldSupportAsLocalDate() { LocalDate localDate = LocalDate.now(); - DateValue dateValue = new DateValue( localDate ); - assertEquals( localDate, dateValue.asLocalDate() ); + DateValue dateValue = new DateValue(localDate); + assertEquals(localDate, dateValue.asLocalDate()); } @Test - void shouldNotSupportAsLong() - { + void shouldNotSupportAsLong() { LocalDate localDate = LocalDate.now(); - DateValue dateValue = new DateValue( localDate ); + DateValue dateValue = new DateValue(localDate); - assertThrows( Uncoercible.class, dateValue::asLong ); + assertThrows(Uncoercible.class, dateValue::asLong); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/DurationValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/DurationValueTest.java index 0e25ac8b04..89f47d43a1 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/DurationValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/DurationValueTest.java @@ -18,53 +18,46 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.value.Uncoercible; import org.neo4j.driver.internal.InternalIsoDuration; import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.exceptions.value.Uncoercible; import org.neo4j.driver.types.IsoDuration; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class DurationValueTest -{ +class DurationValueTest { @Test - void shouldHaveCorrectType() - { - IsoDuration duration = newDuration( 1, 2, 3, 4 ); - DurationValue durationValue = new DurationValue( duration ); - assertEquals( InternalTypeSystem.TYPE_SYSTEM.DURATION(), durationValue.type() ); + void shouldHaveCorrectType() { + IsoDuration duration = newDuration(1, 2, 3, 4); + DurationValue durationValue = new DurationValue(duration); + assertEquals(InternalTypeSystem.TYPE_SYSTEM.DURATION(), durationValue.type()); } @Test - void shouldSupportAsObject() - { - IsoDuration duration = newDuration( 11, 22, 33, 44 ); - DurationValue durationValue = new DurationValue( duration ); - assertEquals( duration, durationValue.asObject() ); + void shouldSupportAsObject() { + IsoDuration duration = newDuration(11, 22, 33, 44); + DurationValue durationValue = new DurationValue(duration); + assertEquals(duration, durationValue.asObject()); } @Test - void shouldSupportAsOffsetTime() - { - IsoDuration duration = newDuration( 111, 222, 333, 444 ); - DurationValue durationValue = new DurationValue( duration ); - assertEquals( duration, durationValue.asIsoDuration() ); + void shouldSupportAsOffsetTime() { + IsoDuration duration = newDuration(111, 222, 333, 444); + DurationValue durationValue = new DurationValue(duration); + assertEquals(duration, durationValue.asIsoDuration()); } @Test - void shouldNotSupportAsLong() - { - IsoDuration duration = newDuration( 1111, 2222, 3333, 4444 ); - DurationValue durationValue = new DurationValue( duration ); + void shouldNotSupportAsLong() { + IsoDuration duration = newDuration(1111, 2222, 3333, 4444); + DurationValue durationValue = new DurationValue(duration); - assertThrows( Uncoercible.class, durationValue::asLong ); + assertThrows(Uncoercible.class, durationValue::asLong); } - private static IsoDuration newDuration( long months, long days, long seconds, int nanoseconds ) - { - return new InternalIsoDuration( months, days, seconds, nanoseconds ); + private static IsoDuration newDuration(long months, long days, long seconds, int nanoseconds) { + return new InternalIsoDuration(months, days, seconds, nanoseconds); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/FloatValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/FloatValueTest.java index 54214e7000..174393de3e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/FloatValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/FloatValueTest.java @@ -18,117 +18,105 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.Value; -import org.neo4j.driver.exceptions.value.LossyCoercion; -import org.neo4j.driver.types.TypeSystem; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; -class FloatValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.exceptions.value.LossyCoercion; +import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.neo4j.driver.internal.types.TypeConstructor; +import org.neo4j.driver.types.TypeSystem; + +class FloatValueTest { private TypeSystem typeSystem = InternalTypeSystem.TYPE_SYSTEM; @Test - void testZeroFloatValue() - { + void testZeroFloatValue() { // Given - FloatValue value = new FloatValue( 0 ); + FloatValue value = new FloatValue(0); // Then - assertThat( value.asInt(), equalTo( 0 ) ); - assertThat( value.asLong(), equalTo( 0L ) ); - assertThat( value.asFloat(), equalTo( (float) 0.0 ) ); - assertThat( value.asDouble(), equalTo( 0.0 ) ); + assertThat(value.asInt(), equalTo(0)); + assertThat(value.asLong(), equalTo(0L)); + assertThat(value.asFloat(), equalTo((float) 0.0)); + assertThat(value.asDouble(), equalTo(0.0)); } @Test - void testNonZeroFloatValue() - { + void testNonZeroFloatValue() { // Given - FloatValue value = new FloatValue( 6.28 ); + FloatValue value = new FloatValue(6.28); // Then - assertThat( value.asDouble(), equalTo( 6.28 ) ); + assertThat(value.asDouble(), equalTo(6.28)); } @Test - void testIsFloat() - { + void testIsFloat() { // Given - FloatValue value = new FloatValue( 6.28 ); + FloatValue value = new FloatValue(6.28); // Then - assertThat( typeSystem.FLOAT().isTypeOf( value ), equalTo( true ) ); + assertThat(typeSystem.FLOAT().isTypeOf(value), equalTo(true)); } @Test - void testEquals() - { + void testEquals() { // Given - FloatValue firstValue = new FloatValue( 6.28 ); - FloatValue secondValue = new FloatValue( 6.28 ); + FloatValue firstValue = new FloatValue(6.28); + FloatValue secondValue = new FloatValue(6.28); // Then - assertThat( firstValue, equalTo( secondValue ) ); + assertThat(firstValue, equalTo(secondValue)); } @Test - void testHashCode() - { + void testHashCode() { // Given - FloatValue value = new FloatValue( 6.28 ); + FloatValue value = new FloatValue(6.28); // Then - assertThat( value.hashCode(), notNullValue() ); + assertThat(value.hashCode(), notNullValue()); } @Test - void shouldNotBeNull() - { - Value value = new FloatValue( 6.28 ); - assertFalse( value.isNull() ); + void shouldNotBeNull() { + Value value = new FloatValue(6.28); + assertFalse(value.isNull()); } @Test - void shouldTypeAsFloat() - { - InternalValue value = new FloatValue( 6.28 ); - assertThat( value.typeConstructor(), equalTo( TypeConstructor.FLOAT ) ); + void shouldTypeAsFloat() { + InternalValue value = new FloatValue(6.28); + assertThat(value.typeConstructor(), equalTo(TypeConstructor.FLOAT)); } @Test - void shouldThrowIfFloatContainsDecimalWhenConverting() - { - FloatValue value = new FloatValue( 1.1 ); + void shouldThrowIfFloatContainsDecimalWhenConverting() { + FloatValue value = new FloatValue(1.1); - assertThrows( LossyCoercion.class, value::asInt ); + assertThrows(LossyCoercion.class, value::asInt); } @Test - void shouldThrowIfLargerThanIntegerMax() - { - FloatValue value1 = new FloatValue( Integer.MAX_VALUE ); - FloatValue value2 = new FloatValue( Integer.MAX_VALUE + 1L); + void shouldThrowIfLargerThanIntegerMax() { + FloatValue value1 = new FloatValue(Integer.MAX_VALUE); + FloatValue value2 = new FloatValue(Integer.MAX_VALUE + 1L); assertThat(value1.asInt(), equalTo(Integer.MAX_VALUE)); - assertThrows( LossyCoercion.class, value2::asInt ); + assertThrows(LossyCoercion.class, value2::asInt); } @Test - void shouldThrowIfSmallerThanIntegerMin() - { - FloatValue value1 = new FloatValue( Integer.MIN_VALUE ); - FloatValue value2 = new FloatValue( Integer.MIN_VALUE - 1L ); + void shouldThrowIfSmallerThanIntegerMin() { + FloatValue value1 = new FloatValue(Integer.MIN_VALUE); + FloatValue value2 = new FloatValue(Integer.MIN_VALUE - 1L); assertThat(value1.asInt(), equalTo(Integer.MIN_VALUE)); - assertThrows( LossyCoercion.class, value2::asInt ); + assertThrows(LossyCoercion.class, value2::asInt); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/IntegerValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/IntegerValueTest.java index 9a2dd565b0..813bde4ebd 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/IntegerValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/IntegerValueTest.java @@ -18,124 +18,112 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.Value; -import org.neo4j.driver.exceptions.value.LossyCoercion; -import org.neo4j.driver.types.TypeSystem; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; -class IntegerValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.exceptions.value.LossyCoercion; +import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.neo4j.driver.internal.types.TypeConstructor; +import org.neo4j.driver.types.TypeSystem; + +class IntegerValueTest { private TypeSystem typeSystem = InternalTypeSystem.TYPE_SYSTEM; @Test - void testZeroIntegerValue() - { + void testZeroIntegerValue() { // Given - IntegerValue value = new IntegerValue( 0 ); + IntegerValue value = new IntegerValue(0); // Then - assertThat( value.asLong(), equalTo( 0L ) ); - assertThat( value.asInt(), equalTo( 0 ) ); - assertThat( value.asDouble(), equalTo( 0.0 ) ); - assertThat( value.asFloat(), equalTo( (float) 0.0 ) ); - assertThat( value.asNumber(), equalTo( (Number) 0L ) ); + assertThat(value.asLong(), equalTo(0L)); + assertThat(value.asInt(), equalTo(0)); + assertThat(value.asDouble(), equalTo(0.0)); + assertThat(value.asFloat(), equalTo((float) 0.0)); + assertThat(value.asNumber(), equalTo((Number) 0L)); } @Test - void testNonZeroIntegerValue() - { + void testNonZeroIntegerValue() { // Given - IntegerValue value = new IntegerValue( 1 ); + IntegerValue value = new IntegerValue(1); // Then - assertThat( value.asLong(), equalTo( 1L ) ); - assertThat( value.asInt(), equalTo( 1 ) ); - assertThat( value.asDouble(), equalTo( 1.0 ) ); - assertThat( value.asFloat(), equalTo( (float) 1.0 ) ); - assertThat( value.asNumber(), equalTo( (Number) 1L ) ); + assertThat(value.asLong(), equalTo(1L)); + assertThat(value.asInt(), equalTo(1)); + assertThat(value.asDouble(), equalTo(1.0)); + assertThat(value.asFloat(), equalTo((float) 1.0)); + assertThat(value.asNumber(), equalTo((Number) 1L)); } @Test - void testIsInteger() - { + void testIsInteger() { // Given - IntegerValue value = new IntegerValue( 1L ); + IntegerValue value = new IntegerValue(1L); // Then - assertThat( typeSystem.INTEGER().isTypeOf( value ), equalTo( true ) ); + assertThat(typeSystem.INTEGER().isTypeOf(value), equalTo(true)); } @Test - void testEquals() - { + void testEquals() { // Given - IntegerValue firstValue = new IntegerValue( 1 ); - IntegerValue secondValue = new IntegerValue( 1 ); + IntegerValue firstValue = new IntegerValue(1); + IntegerValue secondValue = new IntegerValue(1); // Then - assertThat( firstValue, equalTo( secondValue ) ); + assertThat(firstValue, equalTo(secondValue)); } @Test - void testHashCode() - { + void testHashCode() { // Given - IntegerValue value = new IntegerValue( 1L ); + IntegerValue value = new IntegerValue(1L); // Then - assertThat( value.hashCode(), notNullValue() ); + assertThat(value.hashCode(), notNullValue()); } @Test - void shouldNotBeNull() - { - Value value = new IntegerValue( 1L ); - assertFalse( value.isNull() ); + void shouldNotBeNull() { + Value value = new IntegerValue(1L); + assertFalse(value.isNull()); } @Test - void shouldTypeAsInteger() - { - InternalValue value = new IntegerValue( 1L ); - assertThat( value.typeConstructor(), equalTo( TypeConstructor.INTEGER ) ); + void shouldTypeAsInteger() { + InternalValue value = new IntegerValue(1L); + assertThat(value.typeConstructor(), equalTo(TypeConstructor.INTEGER)); } @Test - void shouldThrowIfLargerThanIntegerMax() - { - IntegerValue value1 = new IntegerValue( Integer.MAX_VALUE ); - IntegerValue value2 = new IntegerValue( Integer.MAX_VALUE + 1L); + void shouldThrowIfLargerThanIntegerMax() { + IntegerValue value1 = new IntegerValue(Integer.MAX_VALUE); + IntegerValue value2 = new IntegerValue(Integer.MAX_VALUE + 1L); assertThat(value1.asInt(), equalTo(Integer.MAX_VALUE)); - assertThrows( LossyCoercion.class, value2::asInt ); + assertThrows(LossyCoercion.class, value2::asInt); } @Test - void shouldThrowIfSmallerThanIntegerMin() - { - IntegerValue value1 = new IntegerValue( Integer.MIN_VALUE ); - IntegerValue value2 = new IntegerValue( Integer.MIN_VALUE - 1L ); + void shouldThrowIfSmallerThanIntegerMin() { + IntegerValue value1 = new IntegerValue(Integer.MIN_VALUE); + IntegerValue value2 = new IntegerValue(Integer.MIN_VALUE - 1L); assertThat(value1.asInt(), equalTo(Integer.MIN_VALUE)); - assertThrows( LossyCoercion.class, value2::asInt ); + assertThrows(LossyCoercion.class, value2::asInt); } @Test - void shouldThrowIfLargerThan() - { - IntegerValue value1 = new IntegerValue( 9007199254740992L); - IntegerValue value2 = new IntegerValue(9007199254740993L ); + void shouldThrowIfLargerThan() { + IntegerValue value1 = new IntegerValue(9007199254740992L); + IntegerValue value2 = new IntegerValue(9007199254740993L); assertThat(value1.asDouble(), equalTo(9007199254740992D)); - assertThrows( LossyCoercion.class, value2::asDouble ); + assertThrows(LossyCoercion.class, value2::asDouble); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/ListValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/ListValueTest.java index 3bcf2e29fe..93105b58f6 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/ListValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/ListValueTest.java @@ -18,35 +18,30 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.Value; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.neo4j.driver.Values.value; -class ListValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.types.InternalTypeSystem; + +class ListValueTest { @Test - void shouldHaveSensibleToString() - { - ListValue listValue = listValue( value( 1 ), value( 2 ), value( 3 ) ); - assertThat( listValue.toString(), equalTo( "[1, 2, 3]" ) ); + void shouldHaveSensibleToString() { + ListValue listValue = listValue(value(1), value(2), value(3)); + assertThat(listValue.toString(), equalTo("[1, 2, 3]")); } @Test - void shouldHaveCorrectType() - { + void shouldHaveCorrectType() { ListValue listValue = listValue(); - assertThat(listValue.type(), equalTo( InternalTypeSystem.TYPE_SYSTEM.LIST() )); + assertThat(listValue.type(), equalTo(InternalTypeSystem.TYPE_SYSTEM.LIST())); } - private ListValue listValue( Value... values ) - { - return new ListValue( values ); + private ListValue listValue(Value... values) { + return new ListValue(values); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/LocalDateTimeValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/LocalDateTimeValueTest.java index 8a224e14ea..55d0f20822 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/LocalDateTimeValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/LocalDateTimeValueTest.java @@ -18,51 +18,44 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import java.time.LocalDateTime; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.exceptions.value.Uncoercible; - import static java.time.Month.AUGUST; import static java.time.Month.FEBRUARY; import static java.time.Month.JANUARY; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -class LocalDateTimeValueTest -{ +import java.time.LocalDateTime; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.exceptions.value.Uncoercible; +import org.neo4j.driver.internal.types.InternalTypeSystem; + +class LocalDateTimeValueTest { @Test - void shouldHaveCorrectType() - { - LocalDateTime dateTime = LocalDateTime.of( 1991, AUGUST, 24, 12, 0, 0 ); - LocalDateTimeValue dateTimeValue = new LocalDateTimeValue( dateTime ); - assertEquals( InternalTypeSystem.TYPE_SYSTEM.LOCAL_DATE_TIME(), dateTimeValue.type() ); + void shouldHaveCorrectType() { + LocalDateTime dateTime = LocalDateTime.of(1991, AUGUST, 24, 12, 0, 0); + LocalDateTimeValue dateTimeValue = new LocalDateTimeValue(dateTime); + assertEquals(InternalTypeSystem.TYPE_SYSTEM.LOCAL_DATE_TIME(), dateTimeValue.type()); } @Test - void shouldSupportAsObject() - { - LocalDateTime dateTime = LocalDateTime.of( 2015, FEBRUARY, 2, 23, 59, 59, 999_999 ); - LocalDateTimeValue dateTimeValue = new LocalDateTimeValue( dateTime ); - assertEquals( dateTime, dateTimeValue.asObject() ); + void shouldSupportAsObject() { + LocalDateTime dateTime = LocalDateTime.of(2015, FEBRUARY, 2, 23, 59, 59, 999_999); + LocalDateTimeValue dateTimeValue = new LocalDateTimeValue(dateTime); + assertEquals(dateTime, dateTimeValue.asObject()); } @Test - void shouldSupportAsLocalDateTime() - { - LocalDateTime dateTime = LocalDateTime.of( 1822, JANUARY, 24, 9, 23, 57, 123 ); - LocalDateTimeValue dateTimeValue = new LocalDateTimeValue( dateTime ); - assertEquals( dateTime, dateTimeValue.asLocalDateTime() ); + void shouldSupportAsLocalDateTime() { + LocalDateTime dateTime = LocalDateTime.of(1822, JANUARY, 24, 9, 23, 57, 123); + LocalDateTimeValue dateTimeValue = new LocalDateTimeValue(dateTime); + assertEquals(dateTime, dateTimeValue.asLocalDateTime()); } @Test - void shouldNotSupportAsLong() - { + void shouldNotSupportAsLong() { LocalDateTime dateTime = LocalDateTime.now(); - LocalDateTimeValue dateTimeValue = new LocalDateTimeValue( dateTime ); + LocalDateTimeValue dateTimeValue = new LocalDateTimeValue(dateTime); - assertThrows( Uncoercible.class, dateTimeValue::asLong ); + assertThrows(Uncoercible.class, dateTimeValue::asLong); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/LocalTimeValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/LocalTimeValueTest.java index 148df7ef40..b927f2a5f7 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/LocalTimeValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/LocalTimeValueTest.java @@ -18,48 +18,41 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.time.LocalTime; - -import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.junit.jupiter.api.Test; import org.neo4j.driver.exceptions.value.Uncoercible; +import org.neo4j.driver.internal.types.InternalTypeSystem; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class LocalTimeValueTest -{ +class LocalTimeValueTest { @Test - void shouldHaveCorrectType() - { - LocalTime time = LocalTime.of( 23, 59, 59 ); - LocalTimeValue timeValue = new LocalTimeValue( time ); - assertEquals( InternalTypeSystem.TYPE_SYSTEM.LOCAL_TIME(), timeValue.type() ); + void shouldHaveCorrectType() { + LocalTime time = LocalTime.of(23, 59, 59); + LocalTimeValue timeValue = new LocalTimeValue(time); + assertEquals(InternalTypeSystem.TYPE_SYSTEM.LOCAL_TIME(), timeValue.type()); } @Test - void shouldSupportAsObject() - { - LocalTime time = LocalTime.of( 1, 17, 59, 999 ); - LocalTimeValue timeValue = new LocalTimeValue( time ); - assertEquals( time, timeValue.asObject() ); + void shouldSupportAsObject() { + LocalTime time = LocalTime.of(1, 17, 59, 999); + LocalTimeValue timeValue = new LocalTimeValue(time); + assertEquals(time, timeValue.asObject()); } @Test - void shouldSupportAsLocalTime() - { - LocalTime time = LocalTime.of( 12, 59, 12, 999_999_999 ); - LocalTimeValue timeValue = new LocalTimeValue( time ); - assertEquals( time, timeValue.asLocalTime() ); + void shouldSupportAsLocalTime() { + LocalTime time = LocalTime.of(12, 59, 12, 999_999_999); + LocalTimeValue timeValue = new LocalTimeValue(time); + assertEquals(time, timeValue.asLocalTime()); } @Test - void shouldNotSupportAsLong() - { + void shouldNotSupportAsLong() { LocalTime time = LocalTime.now(); - LocalTimeValue timeValue = new LocalTimeValue( time ); + LocalTimeValue timeValue = new LocalTimeValue(time); - assertThrows( Uncoercible.class, timeValue::asLong ); + assertThrows(Uncoercible.class, timeValue::asLong); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/MapValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/MapValueTest.java index bc51b236c9..527d8cde8a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/MapValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/MapValueTest.java @@ -18,56 +18,48 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.Value; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.neo4j.driver.Values.value; -class MapValueTest -{ +import java.util.HashMap; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.types.InternalTypeSystem; + +class MapValueTest { @Test - void shouldHaveSensibleToString() - { + void shouldHaveSensibleToString() { MapValue mapValue = mapValue(); - assertThat( mapValue.toString(), equalTo( "{k1: \"v1\", k2: 42}" ) ); + assertThat(mapValue.toString(), equalTo("{k1: \"v1\", k2: 42}")); } @Test - void shouldHaveCorrectPropertyCount() - { + void shouldHaveCorrectPropertyCount() { MapValue mapValue = mapValue(); - assertThat( mapValue.size(), equalTo( 2 ) ); + assertThat(mapValue.size(), equalTo(2)); } @Test - void shouldHaveCorrectType() - { + void shouldHaveCorrectType() { MapValue map = mapValue(); - assertThat(map.type(), equalTo( InternalTypeSystem.TYPE_SYSTEM.MAP() )); + assertThat(map.type(), equalTo(InternalTypeSystem.TYPE_SYSTEM.MAP())); } @Test - void shouldNotBeNull() - { + void shouldNotBeNull() { MapValue map = mapValue(); - assertFalse(map.isNull()); + assertFalse(map.isNull()); } - private MapValue mapValue() - { - HashMap map = new HashMap<>(); - map.put( "k1", value( "v1" ) ); - map.put( "k2", value( 42 ) ); - return new MapValue( map ); + private MapValue mapValue() { + HashMap map = new HashMap<>(); + map.put("k1", value("v1")); + map.put("k2", value(42)); + return new MapValue(map); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/NodeValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/NodeValueTest.java index a6ae89089d..7858e6ca74 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/NodeValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/NodeValueTest.java @@ -18,11 +18,6 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.internal.types.TypeConstructor; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -30,38 +25,36 @@ import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; import static org.neo4j.driver.internal.util.ValueFactory.filledNodeValue; -class NodeValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.neo4j.driver.internal.types.TypeConstructor; + +class NodeValueTest { @Test - void shouldHaveSensibleToString() - { - assertEquals( "node<1234>", emptyNodeValue().toString() ); - assertEquals( "node<1234>", filledNodeValue().toString() ); + void shouldHaveSensibleToString() { + assertEquals("node<1234>", emptyNodeValue().toString()); + assertEquals("node<1234>", filledNodeValue().toString()); } @Test - void shouldHaveCorrectPropertyCount() - { - assertEquals( 0, emptyNodeValue().size()) ; - assertEquals( 1, filledNodeValue().size()) ; + void shouldHaveCorrectPropertyCount() { + assertEquals(0, emptyNodeValue().size()); + assertEquals(1, filledNodeValue().size()); } @Test - void shouldNotBeNull() - { - assertFalse( emptyNodeValue().isNull() ); + void shouldNotBeNull() { + assertFalse(emptyNodeValue().isNull()); } @Test - void shouldHaveCorrectType() - { - assertThat( emptyNodeValue().type(), equalTo( InternalTypeSystem.TYPE_SYSTEM.NODE() )); + void shouldHaveCorrectType() { + assertThat(emptyNodeValue().type(), equalTo(InternalTypeSystem.TYPE_SYSTEM.NODE())); } @Test - void shouldTypeAsNode() - { + void shouldTypeAsNode() { InternalValue value = emptyNodeValue(); - assertThat( value.typeConstructor(), equalTo( TypeConstructor.NODE ) ); + assertThat(value.typeConstructor(), equalTo(TypeConstructor.NODE)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/NullValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/NullValueTest.java index e0dd49f531..bcc3431cc0 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/NullValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/NullValueTest.java @@ -18,19 +18,6 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetDateTime; -import java.time.OffsetTime; -import java.time.ZonedDateTime; - -import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.Value; -import java.util.function.Function; - import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static org.hamcrest.MatcherAssert.assertThat; @@ -40,110 +27,111 @@ import static org.neo4j.driver.Values.ofValue; import static org.neo4j.driver.Values.point; -class NullValueTest -{ +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZonedDateTime; +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.types.TypeConstructor; + +class NullValueTest { @Test - void shouldEqualItself() - { - assertThat( NullValue.NULL, equalTo( NullValue.NULL ) ); + void shouldEqualItself() { + assertThat(NullValue.NULL, equalTo(NullValue.NULL)); } @Test - void shouldBeNull() - { - assertTrue( NullValue.NULL.isNull() ); + void shouldBeNull() { + assertTrue(NullValue.NULL.isNull()); } @Test - void shouldTypeAsNull() - { - assertThat( ((InternalValue) NullValue.NULL).typeConstructor(), equalTo( TypeConstructor.NULL ) ); + void shouldTypeAsNull() { + assertThat(((InternalValue) NullValue.NULL).typeConstructor(), equalTo(TypeConstructor.NULL)); } @Test - void shouldReturnNativeTypesAsDefaultValue() - { + void shouldReturnNativeTypesAsDefaultValue() { Value value = NullValue.NULL; // string - assertThat( value.asString( "string value" ), equalTo( "string value" ) ); + assertThat(value.asString("string value"), equalTo("string value")); // primitives - assertThat( value.asBoolean( false ), equalTo( false ) ); - assertThat( value.asBoolean( true ), equalTo( true ) ); - assertThat( value.asInt( 10 ), equalTo( 10 ) ); - assertThat( value.asLong( 100L ), equalTo( 100L ) ); - assertThat( value.asFloat( 10.4f ), equalTo( 10.4f ) ); - assertThat( value.asDouble( 10.10 ), equalTo( 10.10 ) ); - - //array, list, map - assertThat( value.asByteArray( new byte[]{1, 2} ), equalTo( new byte[]{1, 2} ) ); - assertThat( value.asList( emptyList() ), equalTo( emptyList() ) ); - assertThat( value.asList( ofValue(), emptyList() ), equalTo( emptyList() ) ); - assertThat( value.asMap( emptyMap() ), equalTo( emptyMap() ) ); - assertThat( value.asMap( ofValue(), emptyMap() ), equalTo( emptyMap() ) ); + assertThat(value.asBoolean(false), equalTo(false)); + assertThat(value.asBoolean(true), equalTo(true)); + assertThat(value.asInt(10), equalTo(10)); + assertThat(value.asLong(100L), equalTo(100L)); + assertThat(value.asFloat(10.4f), equalTo(10.4f)); + assertThat(value.asDouble(10.10), equalTo(10.10)); + + // array, list, map + assertThat(value.asByteArray(new byte[] {1, 2}), equalTo(new byte[] {1, 2})); + assertThat(value.asList(emptyList()), equalTo(emptyList())); + assertThat(value.asList(ofValue(), emptyList()), equalTo(emptyList())); + assertThat(value.asMap(emptyMap()), equalTo(emptyMap())); + assertThat(value.asMap(ofValue(), emptyMap()), equalTo(emptyMap())); // spatial, temporal - assertAsWithDefaultValueReturnDefault( value::asPoint, point( 1234, 1, 2 ).asPoint() ); - - assertAsWithDefaultValueReturnDefault( value::asLocalDate, LocalDate.now() ); - assertAsWithDefaultValueReturnDefault( value::asOffsetTime, OffsetTime.now() ); - assertAsWithDefaultValueReturnDefault( value::asLocalTime, LocalTime.now() ); - assertAsWithDefaultValueReturnDefault( value::asLocalDateTime, LocalDateTime.now() ); - assertAsWithDefaultValueReturnDefault( value::asOffsetDateTime, OffsetDateTime.now() ); - assertAsWithDefaultValueReturnDefault( value::asZonedDateTime, ZonedDateTime.now() ); - assertAsWithDefaultValueReturnDefault( value::asIsoDuration, - isoDuration( 1, 2, 3, 4 ).asIsoDuration() ); + assertAsWithDefaultValueReturnDefault(value::asPoint, point(1234, 1, 2).asPoint()); + + assertAsWithDefaultValueReturnDefault(value::asLocalDate, LocalDate.now()); + assertAsWithDefaultValueReturnDefault(value::asOffsetTime, OffsetTime.now()); + assertAsWithDefaultValueReturnDefault(value::asLocalTime, LocalTime.now()); + assertAsWithDefaultValueReturnDefault(value::asLocalDateTime, LocalDateTime.now()); + assertAsWithDefaultValueReturnDefault(value::asOffsetDateTime, OffsetDateTime.now()); + assertAsWithDefaultValueReturnDefault(value::asZonedDateTime, ZonedDateTime.now()); + assertAsWithDefaultValueReturnDefault( + value::asIsoDuration, isoDuration(1, 2, 3, 4).asIsoDuration()); } @Test - void shouldReturnAsNull() - { - assertComputeOrDefaultReturnNull( Value::asObject ); - assertComputeOrDefaultReturnNull( Value::asNumber ); - - assertComputeOrDefaultReturnNull( Value::asEntity ); - assertComputeOrDefaultReturnNull( Value::asNode ); - assertComputeOrDefaultReturnNull( Value::asRelationship ); - assertComputeOrDefaultReturnNull( Value::asPath ); - - assertComputeOrDefaultReturnNull( Value::asString ); - assertComputeOrDefaultReturnNull( Value::asByteArray ); - assertComputeOrDefaultReturnNull( Value::asList ); - assertComputeOrDefaultReturnNull( v -> v.asList( ofValue() ) ); - assertComputeOrDefaultReturnNull( Value::asMap ); - assertComputeOrDefaultReturnNull( v -> v.asMap( ofValue() ) ); - - assertComputeOrDefaultReturnNull( Value::asPoint ); - - assertComputeOrDefaultReturnNull( Value::asLocalDate ); - assertComputeOrDefaultReturnNull( Value::asOffsetTime ); - assertComputeOrDefaultReturnNull( Value::asLocalTime ); - assertComputeOrDefaultReturnNull( Value::asLocalDateTime ); - assertComputeOrDefaultReturnNull( Value::asOffsetTime ); - assertComputeOrDefaultReturnNull( Value::asZonedDateTime ); - assertComputeOrDefaultReturnNull( Value::asIsoDuration ); + void shouldReturnAsNull() { + assertComputeOrDefaultReturnNull(Value::asObject); + assertComputeOrDefaultReturnNull(Value::asNumber); + + assertComputeOrDefaultReturnNull(Value::asEntity); + assertComputeOrDefaultReturnNull(Value::asNode); + assertComputeOrDefaultReturnNull(Value::asRelationship); + assertComputeOrDefaultReturnNull(Value::asPath); + + assertComputeOrDefaultReturnNull(Value::asString); + assertComputeOrDefaultReturnNull(Value::asByteArray); + assertComputeOrDefaultReturnNull(Value::asList); + assertComputeOrDefaultReturnNull(v -> v.asList(ofValue())); + assertComputeOrDefaultReturnNull(Value::asMap); + assertComputeOrDefaultReturnNull(v -> v.asMap(ofValue())); + + assertComputeOrDefaultReturnNull(Value::asPoint); + + assertComputeOrDefaultReturnNull(Value::asLocalDate); + assertComputeOrDefaultReturnNull(Value::asOffsetTime); + assertComputeOrDefaultReturnNull(Value::asLocalTime); + assertComputeOrDefaultReturnNull(Value::asLocalDateTime); + assertComputeOrDefaultReturnNull(Value::asOffsetTime); + assertComputeOrDefaultReturnNull(Value::asZonedDateTime); + assertComputeOrDefaultReturnNull(Value::asIsoDuration); } @Test - void shouldReturnAsDefaultValue() - { - assertComputeOrDefaultReturnDefault( Value::asObject, "null string" ); - assertComputeOrDefaultReturnDefault( Value::asNumber, 10 ); + void shouldReturnAsDefaultValue() { + assertComputeOrDefaultReturnDefault(Value::asObject, "null string"); + assertComputeOrDefaultReturnDefault(Value::asNumber, 10); } - private static void assertComputeOrDefaultReturnDefault( Function f, T defaultAndExpectedValue ) - { + private static void assertComputeOrDefaultReturnDefault(Function f, T defaultAndExpectedValue) { Value value = NullValue.NULL; - assertThat( value.computeOrDefault( f, defaultAndExpectedValue ), equalTo( defaultAndExpectedValue ) ); + assertThat(value.computeOrDefault(f, defaultAndExpectedValue), equalTo(defaultAndExpectedValue)); } - private static void assertComputeOrDefaultReturnNull( Function f ) - { - assertComputeOrDefaultReturnDefault( f, null ); + private static void assertComputeOrDefaultReturnNull(Function f) { + assertComputeOrDefaultReturnDefault(f, null); } - private static void assertAsWithDefaultValueReturnDefault( Function map, T defaultValue ) - { - assertThat( map.apply( defaultValue ), equalTo( defaultValue ) ); + private static void assertAsWithDefaultValueReturnDefault(Function map, T defaultValue) { + assertThat(map.apply(defaultValue), equalTo(defaultValue)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/PathValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/PathValueTest.java index dfe7aef0f3..80365915ba 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/PathValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/PathValueTest.java @@ -18,35 +18,30 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.Value; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.neo4j.driver.internal.util.ValueFactory.filledPathValue; -class PathValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.types.InternalTypeSystem; + +class PathValueTest { @Test - void shouldHaveSensibleToString() - { + void shouldHaveSensibleToString() { assertEquals("path[(42)-[43:T]->(44)]", filledPathValue().toString()); } @Test - void shouldNotBeNull() - { + void shouldNotBeNull() { Value value = filledPathValue(); - assertFalse( value.isNull() ); + assertFalse(value.isNull()); } @Test - void shouldHaveCorrectType() - { - assertThat( filledPathValue().type(), equalTo( InternalTypeSystem.TYPE_SYSTEM.PATH() )); + void shouldHaveCorrectType() { + assertThat(filledPathValue().type(), equalTo(InternalTypeSystem.TYPE_SYSTEM.PATH())); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/RelationshipValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/RelationshipValueTest.java index b299f501d7..84bbdc17a2 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/RelationshipValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/RelationshipValueTest.java @@ -18,11 +18,6 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.Value; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -30,33 +25,32 @@ import static org.neo4j.driver.internal.util.ValueFactory.emptyRelationshipValue; import static org.neo4j.driver.internal.util.ValueFactory.filledRelationshipValue; -class RelationshipValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.types.TypeConstructor; + +class RelationshipValueTest { @Test - void shouldHaveSensibleToString() - { - assertEquals( "relationship<1234>", emptyRelationshipValue().toString() ); - assertEquals( "relationship<1234>", filledRelationshipValue().toString() ); + void shouldHaveSensibleToString() { + assertEquals("relationship<1234>", emptyRelationshipValue().toString()); + assertEquals("relationship<1234>", filledRelationshipValue().toString()); } @Test - void shouldHaveCorrectPropertyCount() - { - assertEquals( 0, emptyRelationshipValue().size()) ; - assertEquals( 1, filledRelationshipValue().size()) ; + void shouldHaveCorrectPropertyCount() { + assertEquals(0, emptyRelationshipValue().size()); + assertEquals(1, filledRelationshipValue().size()); } @Test - void shouldNotBeNull() - { + void shouldNotBeNull() { Value value = emptyRelationshipValue(); - assertFalse( value.isNull() ); + assertFalse(value.isNull()); } @Test - void shouldTypeAsRelationship() - { + void shouldTypeAsRelationship() { InternalValue value = emptyRelationshipValue(); - assertThat( value.typeConstructor(), equalTo( TypeConstructor.RELATIONSHIP ) ); + assertThat(value.typeConstructor(), equalTo(TypeConstructor.RELATIONSHIP)); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/StringValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/StringValueTest.java index 349ea9d741..1cc503635f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/StringValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/StringValueTest.java @@ -18,81 +18,72 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; - -import org.neo4j.driver.internal.types.InternalTypeSystem; -import org.neo4j.driver.internal.types.TypeConstructor; -import org.neo4j.driver.Value; -import org.neo4j.driver.types.TypeSystem; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; -class StringValueTest -{ +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; +import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.neo4j.driver.internal.types.TypeConstructor; +import org.neo4j.driver.types.TypeSystem; + +class StringValueTest { private TypeSystem typeSystem = InternalTypeSystem.TYPE_SYSTEM; @Test - void testStringValue() - { + void testStringValue() { // Given - StringValue value = new StringValue( "Spongebob" ); + StringValue value = new StringValue("Spongebob"); // Then - assertThat( value.asString(), equalTo( "Spongebob" ) ); + assertThat(value.asString(), equalTo("Spongebob")); } @Test - void testIsString() - { + void testIsString() { // Given - StringValue value = new StringValue( "Spongebob" ); + StringValue value = new StringValue("Spongebob"); // Then - assertThat( typeSystem.STRING().isTypeOf( value ), equalTo( true ) ); + assertThat(typeSystem.STRING().isTypeOf(value), equalTo(true)); } @Test - void testEquals() - { + void testEquals() { // Given - StringValue firstValue = new StringValue( "Spongebob" ); - StringValue secondValue = new StringValue( "Spongebob" ); + StringValue firstValue = new StringValue("Spongebob"); + StringValue secondValue = new StringValue("Spongebob"); // Then - assertThat( firstValue, equalTo( secondValue ) ); + assertThat(firstValue, equalTo(secondValue)); } @Test - void testHashCode() - { + void testHashCode() { // Given - StringValue value = new StringValue( "Spongebob" ); + StringValue value = new StringValue("Spongebob"); // Then - assertThat( value.hashCode(), notNullValue() ); + assertThat(value.hashCode(), notNullValue()); } @Test - void shouldNotBeNull() - { - Value value = new StringValue( "Spongebob" ); - assertFalse( value.isNull() ); + void shouldNotBeNull() { + Value value = new StringValue("Spongebob"); + assertFalse(value.isNull()); } @Test - void shouldTypeAsString() - { - InternalValue value = new StringValue( "Spongebob" ); - assertThat( value.typeConstructor(), equalTo( TypeConstructor.STRING ) ); + void shouldTypeAsString() { + InternalValue value = new StringValue("Spongebob"); + assertThat(value.typeConstructor(), equalTo(TypeConstructor.STRING)); } @Test - void shouldHaveStringType() - { - InternalValue value = new StringValue( "Spongebob" ); - assertThat( value.type(), equalTo( InternalTypeSystem.TYPE_SYSTEM.STRING() ) ); + void shouldHaveStringType() { + InternalValue value = new StringValue("Spongebob"); + assertThat(value.type(), equalTo(InternalTypeSystem.TYPE_SYSTEM.STRING())); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/value/TimeValueTest.java b/driver/src/test/java/org/neo4j/driver/internal/value/TimeValueTest.java index 78e292bd65..7a07bf674b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/value/TimeValueTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/value/TimeValueTest.java @@ -18,49 +18,42 @@ */ package org.neo4j.driver.internal.value; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.time.OffsetTime; import java.time.ZoneOffset; - -import org.neo4j.driver.internal.types.InternalTypeSystem; +import org.junit.jupiter.api.Test; import org.neo4j.driver.exceptions.value.Uncoercible; +import org.neo4j.driver.internal.types.InternalTypeSystem; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -class TimeValueTest -{ +class TimeValueTest { @Test - void shouldHaveCorrectType() - { - OffsetTime time = OffsetTime.now().withOffsetSameInstant( ZoneOffset.ofHoursMinutes( 5, 30 ) ); - TimeValue timeValue = new TimeValue( time ); - assertEquals( InternalTypeSystem.TYPE_SYSTEM.TIME(), timeValue.type() ); + void shouldHaveCorrectType() { + OffsetTime time = OffsetTime.now().withOffsetSameInstant(ZoneOffset.ofHoursMinutes(5, 30)); + TimeValue timeValue = new TimeValue(time); + assertEquals(InternalTypeSystem.TYPE_SYSTEM.TIME(), timeValue.type()); } @Test - void shouldSupportAsObject() - { - OffsetTime time = OffsetTime.of( 19, 0, 10, 1, ZoneOffset.ofHours( -3 ) ); - TimeValue timeValue = new TimeValue( time ); - assertEquals( time, timeValue.asObject() ); + void shouldSupportAsObject() { + OffsetTime time = OffsetTime.of(19, 0, 10, 1, ZoneOffset.ofHours(-3)); + TimeValue timeValue = new TimeValue(time); + assertEquals(time, timeValue.asObject()); } @Test - void shouldSupportAsOffsetTime() - { - OffsetTime time = OffsetTime.of( 23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes( 2, 15 ) ); - TimeValue timeValue = new TimeValue( time ); - assertEquals( time, timeValue.asOffsetTime() ); + void shouldSupportAsOffsetTime() { + OffsetTime time = OffsetTime.of(23, 59, 59, 999_999_999, ZoneOffset.ofHoursMinutes(2, 15)); + TimeValue timeValue = new TimeValue(time); + assertEquals(time, timeValue.asOffsetTime()); } @Test - void shouldNotSupportAsLong() - { - OffsetTime time = OffsetTime.now().withOffsetSameInstant( ZoneOffset.ofHours( -5 ) ); - TimeValue timeValue = new TimeValue( time ); + void shouldNotSupportAsLong() { + OffsetTime time = OffsetTime.now().withOffsetSameInstant(ZoneOffset.ofHours(-5)); + TimeValue timeValue = new TimeValue(time); - assertThrows( Uncoercible.class, timeValue::asLong ); + assertThrows(Uncoercible.class, timeValue::asLong); } } diff --git a/driver/src/test/java/org/neo4j/driver/net/ServerAddressTest.java b/driver/src/test/java/org/neo4j/driver/net/ServerAddressTest.java index fa11ce625e..2ea9515735 100644 --- a/driver/src/test/java/org/neo4j/driver/net/ServerAddressTest.java +++ b/driver/src/test/java/org/neo4j/driver/net/ServerAddressTest.java @@ -18,31 +18,27 @@ */ package org.neo4j.driver.net; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -class ServerAddressTest -{ +import org.junit.jupiter.api.Test; + +class ServerAddressTest { @Test - void shouldCreateAddress() - { - ServerAddress address = ServerAddress.of( "my.database.com", 8897 ); - assertEquals( "my.database.com", address.host() ); - assertEquals( 8897, address.port() ); + void shouldCreateAddress() { + ServerAddress address = ServerAddress.of("my.database.com", 8897); + assertEquals("my.database.com", address.host()); + assertEquals(8897, address.port()); } @Test - void shouldFailToCreateAddressWithInvalidHost() - { - assertThrows( NullPointerException.class, () -> ServerAddress.of( null, 9999 ) ); + void shouldFailToCreateAddressWithInvalidHost() { + assertThrows(NullPointerException.class, () -> ServerAddress.of(null, 9999)); } @Test - void shouldFailToCreateAddressWithInvalidPort() - { - assertThrows( IllegalArgumentException.class, () -> ServerAddress.of( "hello.graphs.com", -42 ) ); - assertThrows( IllegalArgumentException.class, () -> ServerAddress.of( "hello.graphs.com", 66_000 ) ); + void shouldFailToCreateAddressWithInvalidPort() { + assertThrows(IllegalArgumentException.class, () -> ServerAddress.of("hello.graphs.com", -42)); + assertThrows(IllegalArgumentException.class, () -> ServerAddress.of("hello.graphs.com", 66_000)); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AbstractAsyncQuery.java b/driver/src/test/java/org/neo4j/driver/stress/AbstractAsyncQuery.java index de135d01ae..db75078e1c 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AbstractAsyncQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AbstractAsyncQuery.java @@ -18,29 +18,28 @@ */ package org.neo4j.driver.stress; +import static org.neo4j.driver.SessionConfig.builder; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.async.AsyncSession; -import static org.neo4j.driver.SessionConfig.builder; - -public abstract class AbstractAsyncQuery implements AsyncCommand -{ +public abstract class AbstractAsyncQuery implements AsyncCommand { protected final Driver driver; protected final boolean useBookmark; - public AbstractAsyncQuery( Driver driver, boolean useBookmark ) - { + public AbstractAsyncQuery(Driver driver, boolean useBookmark) { this.driver = driver; this.useBookmark = useBookmark; } - public AsyncSession newSession( AccessMode mode, C context ) - { - if ( useBookmark ) - { - return driver.asyncSession( builder().withDefaultAccessMode( mode ).withBookmarks( context.getBookmark() ).build() ); + public AsyncSession newSession(AccessMode mode, C context) { + if (useBookmark) { + return driver.asyncSession(builder() + .withDefaultAccessMode(mode) + .withBookmarks(context.getBookmark()) + .build()); } - return driver.asyncSession( builder().withDefaultAccessMode( mode ).build() ); + return driver.asyncSession(builder().withDefaultAccessMode(mode).build()); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AbstractBlockingQuery.java b/driver/src/test/java/org/neo4j/driver/stress/AbstractBlockingQuery.java index ec0d7dd34e..29dcef2c3f 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AbstractBlockingQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AbstractBlockingQuery.java @@ -18,46 +18,39 @@ */ package org.neo4j.driver.stress; +import static org.neo4j.driver.SessionConfig.builder; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; import org.neo4j.driver.exceptions.TransientException; -import static org.neo4j.driver.SessionConfig.builder; - -public abstract class AbstractBlockingQuery implements BlockingCommand -{ +public abstract class AbstractBlockingQuery implements BlockingCommand { protected final Driver driver; protected final boolean useBookmark; - public AbstractBlockingQuery( Driver driver, boolean useBookmark ) - { + public AbstractBlockingQuery(Driver driver, boolean useBookmark) { this.driver = driver; this.useBookmark = useBookmark; } - public Session newSession( AccessMode mode, C context ) - { - if ( useBookmark ) - { - return driver.session( builder().withDefaultAccessMode( mode ).withBookmarks( context.getBookmark() ).build() ); + public Session newSession(AccessMode mode, C context) { + if (useBookmark) { + return driver.session(builder() + .withDefaultAccessMode(mode) + .withBookmarks(context.getBookmark()) + .build()); } - return driver.session( builder().withDefaultAccessMode( mode ).build() ); + return driver.session(builder().withDefaultAccessMode(mode).build()); } - public Transaction beginTransaction( Session session, C context ) - { - if ( useBookmark ) - { - while ( true ) - { - try - { + public Transaction beginTransaction(Session session, C context) { + if (useBookmark) { + while (true) { + try { return session.beginTransaction(); - } - catch ( TransientException e ) - { + } catch (TransientException e) { context.bookmarkFailed(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AbstractContext.java b/driver/src/test/java/org/neo4j/driver/stress/AbstractContext.java index 84037dd84a..f6dc488942 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AbstractContext.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AbstractContext.java @@ -20,65 +20,53 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.summary.ResultSummary; -public abstract class AbstractContext -{ +public abstract class AbstractContext { private volatile boolean stopped; private volatile Bookmark bookmark; private final AtomicLong readNodesCount = new AtomicLong(); private final AtomicLong createdNodesCount = new AtomicLong(); private final AtomicInteger bookmarkFailures = new AtomicInteger(); - public final boolean isStopped() - { + public final boolean isStopped() { return stopped; } - public final void stop() - { + public final void stop() { this.stopped = true; } - public final Bookmark getBookmark() - { + public final Bookmark getBookmark() { return bookmark; } - public final void setBookmark( Bookmark bookmark ) - { + public final void setBookmark(Bookmark bookmark) { this.bookmark = bookmark; } - public final void nodeCreated() - { + public final void nodeCreated() { createdNodesCount.incrementAndGet(); } - public final long getCreatedNodesCount() - { + public final long getCreatedNodesCount() { return createdNodesCount.get(); } - public final void readCompleted( ResultSummary summary ) - { + public final void readCompleted(ResultSummary summary) { readNodesCount.incrementAndGet(); } - public long getReadNodesCount() - { + public long getReadNodesCount() { return readNodesCount.get(); } - public final void bookmarkFailed() - { + public final void bookmarkFailed() { bookmarkFailures.incrementAndGet(); } - public final int getBookmarkFailures() - { + public final int getBookmarkFailures() { return bookmarkFailures.get(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AbstractRxQuery.java b/driver/src/test/java/org/neo4j/driver/stress/AbstractRxQuery.java index e53b290252..4f7ced88d6 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AbstractRxQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AbstractRxQuery.java @@ -18,29 +18,28 @@ */ package org.neo4j.driver.stress; +import static org.neo4j.driver.SessionConfig.builder; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.reactive.RxSession; -import static org.neo4j.driver.SessionConfig.builder; - -public abstract class AbstractRxQuery implements RxCommand -{ +public abstract class AbstractRxQuery implements RxCommand { protected final Driver driver; protected final boolean useBookmark; - public AbstractRxQuery( Driver driver, boolean useBookmark ) - { + public AbstractRxQuery(Driver driver, boolean useBookmark) { this.driver = driver; this.useBookmark = useBookmark; } - public RxSession newSession( AccessMode mode, C context ) - { - if ( useBookmark ) - { - return driver.rxSession( builder().withDefaultAccessMode( mode ).withBookmarks( context.getBookmark() ).build() ); + public RxSession newSession(AccessMode mode, C context) { + if (useBookmark) { + return driver.rxSession(builder() + .withDefaultAccessMode(mode) + .withBookmarks(context.getBookmark()) + .build()); } - return driver.rxSession( builder().withDefaultAccessMode( mode ).build() ); + return driver.rxSession(builder().withDefaultAccessMode(mode).build()); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AbstractStressTestBase.java b/driver/src/test/java/org/neo4j/driver/stress/AbstractStressTestBase.java index f807aa372a..fd138aea39 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AbstractStressTestBase.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AbstractStressTestBase.java @@ -18,12 +18,20 @@ */ package org.neo4j.driver.stress; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; +import static java.util.Collections.nCopies; +import static java.util.Collections.singletonMap; +import static java.util.concurrent.CompletableFuture.completedFuture; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.neo4j.driver.SessionConfig.builder; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; @@ -48,7 +56,10 @@ import java.util.function.Function; import java.util.logging.Level; import java.util.stream.IntStream; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.neo4j.driver.AuthToken; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Config; @@ -72,32 +83,18 @@ import org.neo4j.driver.reactive.RxTransaction; import org.neo4j.driver.types.Node; import org.neo4j.driver.util.DaemonThreadFactory; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; -import static java.util.Collections.nCopies; -import static java.util.Collections.singletonMap; -import static java.util.concurrent.CompletableFuture.completedFuture; -import static java.util.concurrent.TimeUnit.MINUTES; -import static java.util.concurrent.TimeUnit.NANOSECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.lessThanOrEqualTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeTrue; -import static org.neo4j.driver.SessionConfig.builder; - -@ExtendWith( DumpLogsOnFailureWatcher.class ) -abstract class AbstractStressTestBase -{ - private static final int THREAD_COUNT = Integer.getInteger( "threadCount", 8 ); - private static final int ASYNC_BATCH_SIZE = Integer.getInteger( "asyncBatchSize", 10 ); - private static final int EXECUTION_TIME_SECONDS = Integer.getInteger( "executionTimeSeconds", 20 ); - private static final boolean DEBUG_LOGGING_ENABLED = Boolean.getBoolean( "loggingEnabled" ); +@ExtendWith(DumpLogsOnFailureWatcher.class) +abstract class AbstractStressTestBase { + private static final int THREAD_COUNT = Integer.getInteger("threadCount", 8); + private static final int ASYNC_BATCH_SIZE = Integer.getInteger("asyncBatchSize", 10); + private static final int EXECUTION_TIME_SECONDS = Integer.getInteger("executionTimeSeconds", 20); + private static final boolean DEBUG_LOGGING_ENABLED = Boolean.getBoolean("loggingEnabled"); - private static final int BIG_DATA_TEST_NODE_COUNT = Integer.getInteger( "bigDataTestNodeCount", 30_000 ); - private static final int BIG_DATA_TEST_BATCH_SIZE = Integer.getInteger( "bigDataTestBatchSize", 10_000 ); + private static final int BIG_DATA_TEST_NODE_COUNT = Integer.getInteger("bigDataTestNodeCount", 30_000); + private static final int BIG_DATA_TEST_BATCH_SIZE = Integer.getInteger("bigDataTestBatchSize", 10_000); private LoggerNameTrackingLogging logging; private ExecutorService executor; @@ -105,101 +102,85 @@ abstract class AbstractStressTestBase InternalDriver driver; @BeforeEach - void setUp() - { + void setUp() { logging = new LoggerNameTrackingLogging(); - driver = (InternalDriver) GraphDatabase.driver( databaseUri(), authToken(), config() ); + driver = (InternalDriver) GraphDatabase.driver(databaseUri(), authToken(), config()); - ThreadFactory threadFactory = new DaemonThreadFactory( getClass().getSimpleName() + "-worker-" ); - executor = Executors.newCachedThreadPool( threadFactory ); + ThreadFactory threadFactory = new DaemonThreadFactory(getClass().getSimpleName() + "-worker-"); + executor = Executors.newCachedThreadPool(threadFactory); } @AfterEach - void tearDown() - { + void tearDown() { executor.shutdownNow(); - if ( driver != null ) - { + if (driver != null) { driver.close(); } } @Test - void blockingApiStressTest() throws Throwable - { - runStressTest( this::launchBlockingWorkerThreads ); + void blockingApiStressTest() throws Throwable { + runStressTest(this::launchBlockingWorkerThreads); } @Test - void asyncApiStressTest() throws Throwable - { - runStressTest( this::launchAsyncWorkerThreads ); + void asyncApiStressTest() throws Throwable { + runStressTest(this::launchAsyncWorkerThreads); } @Test - void rxApiStressTest() throws Throwable - { + void rxApiStressTest() throws Throwable { assertRxIsAvailable(); - runStressTest( this::launchRxWorkerThreads ); + runStressTest(this::launchRxWorkerThreads); } @Test - void blockingApiBigDataTest() - { - Bookmark bookmark = createNodesBlocking( bigDataTestBatchCount(), BIG_DATA_TEST_BATCH_SIZE, driver ); - readNodesBlocking( driver, bookmark, BIG_DATA_TEST_NODE_COUNT ); + void blockingApiBigDataTest() { + Bookmark bookmark = createNodesBlocking(bigDataTestBatchCount(), BIG_DATA_TEST_BATCH_SIZE, driver); + readNodesBlocking(driver, bookmark, BIG_DATA_TEST_NODE_COUNT); } @Test - void asyncApiBigDataTest() throws Throwable - { - Bookmark bookmark = createNodesAsync( bigDataTestBatchCount(), BIG_DATA_TEST_BATCH_SIZE, driver ); - readNodesAsync( driver, bookmark, BIG_DATA_TEST_NODE_COUNT ); + void asyncApiBigDataTest() throws Throwable { + Bookmark bookmark = createNodesAsync(bigDataTestBatchCount(), BIG_DATA_TEST_BATCH_SIZE, driver); + readNodesAsync(driver, bookmark, BIG_DATA_TEST_NODE_COUNT); } @Test - void rxApiBigDataTest() - { + void rxApiBigDataTest() { assertRxIsAvailable(); - Bookmark bookmark = createNodesRx( bigDataTestBatchCount(), BIG_DATA_TEST_BATCH_SIZE, driver ); - readNodesRx( driver, bookmark, BIG_DATA_TEST_NODE_COUNT ); + Bookmark bookmark = createNodesRx(bigDataTestBatchCount(), BIG_DATA_TEST_BATCH_SIZE, driver); + readNodesRx(driver, bookmark, BIG_DATA_TEST_NODE_COUNT); } - private void assertRxIsAvailable() - { - assumeTrue( driver.supportsMultiDb() ); + private void assertRxIsAvailable() { + assumeTrue(driver.supportsMultiDb()); } - private void runStressTest( Function>> threadLauncher ) throws Throwable - { + private void runStressTest(Function>> threadLauncher) throws Throwable { C context = createContext(); - List> resultFutures = threadLauncher.apply( context ); + List> resultFutures = threadLauncher.apply(context); ResourcesInfo resourcesInfo = sleepAndGetResourcesInfo(); context.stop(); Throwable firstError = null; - for ( Future future : resultFutures ) - { - try - { - assertNull( future.get( 10, SECONDS ) ); - } - catch ( Throwable error ) - { - firstError = withSuppressed( firstError, error ); + for (Future future : resultFutures) { + try { + assertNull(future.get(10, SECONDS)); + } catch (Throwable error) { + firstError = withSuppressed(firstError, error); } } - printStats( context ); + printStats(context); - if ( firstError != null ) - { + if (firstError != null) { throw firstError; } - verifyResults( context, resourcesInfo ); + verifyResults(context, resourcesInfo); } abstract void dumpLogs(); @@ -208,15 +189,14 @@ private void runStressTest( Function>> threadLauncher ) throws abstract AuthToken authToken(); - abstract Config.ConfigBuilder config( Config.ConfigBuilder builder ); + abstract Config.ConfigBuilder config(Config.ConfigBuilder builder); - Config config() - { + Config config() { Config.ConfigBuilder builder = Config.builder() - .withLogging( logging ) - .withMaxConnectionPoolSize( 100 ) - .withConnectionAcquisitionTimeout( 1, MINUTES ); - return config( builder ).build(); + .withLogging(logging) + .withMaxConnectionPoolSize(100) + .withConnectionAcquisitionTimeout(1, MINUTES); + return config(builder).build(); } abstract C createContext(); @@ -233,538 +213,478 @@ List> createTestSpecificRxCommands() { return Collections.emptyList(); } - abstract boolean handleWriteFailure( Throwable error, C context ); + abstract boolean handleWriteFailure(Throwable error, C context); - abstract void printStats( A context ); + abstract void printStats(A context); - private List> launchBlockingWorkerThreads( C context ) - { + private List> launchBlockingWorkerThreads(C context) { List> commands = createBlockingCommands(); List> futures = new ArrayList<>(); - for ( int i = 0; i < THREAD_COUNT; i++ ) - { - Future future = launchBlockingWorkerThread( executor, commands, context ); - futures.add( future ); + for (int i = 0; i < THREAD_COUNT; i++) { + Future future = launchBlockingWorkerThread(executor, commands, context); + futures.add(future); } return futures; } - private List> createBlockingCommands() - { + private List> createBlockingCommands() { List> commands = new ArrayList<>(); - commands.add( new BlockingReadQueryWithRetries<>( driver, false ) ); - commands.add( new BlockingReadQueryWithRetries<>( driver, true ) ); + commands.add(new BlockingReadQueryWithRetries<>(driver, false)); + commands.add(new BlockingReadQueryWithRetries<>(driver, true)); - commands.add( new BlockingWriteQueryWithRetries<>( this, driver, false ) ); - commands.add( new BlockingWriteQueryWithRetries<>( this, driver, true ) ); + commands.add(new BlockingWriteQueryWithRetries<>(this, driver, false)); + commands.add(new BlockingWriteQueryWithRetries<>(this, driver, true)); - commands.add( new BlockingWrongQueryWithRetries<>( driver ) ); + commands.add(new BlockingWrongQueryWithRetries<>(driver)); - commands.add( new BlockingFailingQueryWithRetries<>( driver ) ); + commands.add(new BlockingFailingQueryWithRetries<>(driver)); - commands.add( new FailedAuth<>( databaseUri(), config() ) ); + commands.add(new FailedAuth<>(databaseUri(), config())); - commands.addAll( createTestSpecificBlockingCommands() ); + commands.addAll(createTestSpecificBlockingCommands()); return commands; } - private Future launchBlockingWorkerThread( ExecutorService executor, List> commands, - C context ) - { - return executor.submit( () -> - { - while ( !context.isStopped() ) - { - BlockingCommand command = randomOf( commands ); - command.execute( context ); + private Future launchBlockingWorkerThread( + ExecutorService executor, List> commands, C context) { + return executor.submit(() -> { + while (!context.isStopped()) { + BlockingCommand command = randomOf(commands); + command.execute(context); } return null; - } ); + }); } - private List> launchRxWorkerThreads( C context ) - { + private List> launchRxWorkerThreads(C context) { List> commands = createRxCommands(); List> futures = new ArrayList<>(); - for ( int i = 0; i < THREAD_COUNT; i++ ) - { - Future future = launchRxWorkerThread( executor, commands, context ); - futures.add( future ); + for (int i = 0; i < THREAD_COUNT; i++) { + Future future = launchRxWorkerThread(executor, commands, context); + futures.add(future); } return futures; } - private List> createRxCommands() - { + private List> createRxCommands() { List> commands = new ArrayList<>(); - commands.add( new RxReadQueryWithRetries<>( driver, false ) ); - commands.add( new RxReadQueryWithRetries<>( driver, true ) ); + commands.add(new RxReadQueryWithRetries<>(driver, false)); + commands.add(new RxReadQueryWithRetries<>(driver, true)); - commands.add( new RxWriteQueryWithRetries<>( this, driver, false ) ); - commands.add( new RxWriteQueryWithRetries<>( this, driver, true ) ); + commands.add(new RxWriteQueryWithRetries<>(this, driver, false)); + commands.add(new RxWriteQueryWithRetries<>(this, driver, true)); - commands.add( new RxFailingQueryWithRetries<>( driver ) ); + commands.add(new RxFailingQueryWithRetries<>(driver)); - commands.addAll( createTestSpecificRxCommands() ); + commands.addAll(createTestSpecificRxCommands()); return commands; } - private Future launchRxWorkerThread( ExecutorService executor, List> commands, C context ) - { - return executor.submit( () -> - { - while ( !context.isStopped() ) - { - CompletableFuture allCommands = executeRxCommands( context, commands, ASYNC_BATCH_SIZE ); - assertNull( allCommands.get() ); + private Future launchRxWorkerThread(ExecutorService executor, List> commands, C context) { + return executor.submit(() -> { + while (!context.isStopped()) { + CompletableFuture allCommands = executeRxCommands(context, commands, ASYNC_BATCH_SIZE); + assertNull(allCommands.get()); } return null; - } ); + }); } - private CompletableFuture executeRxCommands( C context, List> commands, int count ) - { + private CompletableFuture executeRxCommands(C context, List> commands, int count) { CompletableFuture[] executions = new CompletableFuture[count]; - for ( int i = 0; i < count; i++ ) - { - RxCommand command = randomOf( commands ); - CompletionStage execution = command.execute( context ); + for (int i = 0; i < count; i++) { + RxCommand command = randomOf(commands); + CompletionStage execution = command.execute(context); executions[i] = execution.toCompletableFuture(); } - return CompletableFuture.allOf( executions ); + return CompletableFuture.allOf(executions); } - private List> launchAsyncWorkerThreads( C context ) - { + private List> launchAsyncWorkerThreads(C context) { List> commands = createAsyncCommands(); List> futures = new ArrayList<>(); - for ( int i = 0; i < THREAD_COUNT; i++ ) - { - Future future = launchAsyncWorkerThread( executor, commands, context ); - futures.add( future ); + for (int i = 0; i < THREAD_COUNT; i++) { + Future future = launchAsyncWorkerThread(executor, commands, context); + futures.add(future); } return futures; } - private List> createAsyncCommands() - { + private List> createAsyncCommands() { List> commands = new ArrayList<>(); - commands.add( new AsyncReadQueryWithRetries<>( driver, false ) ); - commands.add( new AsyncReadQueryWithRetries<>( driver, true ) ); + commands.add(new AsyncReadQueryWithRetries<>(driver, false)); + commands.add(new AsyncReadQueryWithRetries<>(driver, true)); - commands.add( new AsyncWriteQueryWithRetries<>( this, driver, false ) ); - commands.add( new AsyncWriteQueryWithRetries<>( this, driver, true ) ); + commands.add(new AsyncWriteQueryWithRetries<>(this, driver, false)); + commands.add(new AsyncWriteQueryWithRetries<>(this, driver, true)); - commands.add( new AsyncWrongQueryWithRetries<>( driver ) ); + commands.add(new AsyncWrongQueryWithRetries<>(driver)); - commands.add( new AsyncFailingQueryWithRetries<>( driver ) ); + commands.add(new AsyncFailingQueryWithRetries<>(driver)); return commands; } - private Future launchAsyncWorkerThread( ExecutorService executor, List> commands, C context ) - { - return executor.submit( () -> - { - while ( !context.isStopped() ) - { - CompletableFuture allCommands = executeAsyncCommands( context, commands, ASYNC_BATCH_SIZE ); - assertNull( allCommands.get() ); + private Future launchAsyncWorkerThread(ExecutorService executor, List> commands, C context) { + return executor.submit(() -> { + while (!context.isStopped()) { + CompletableFuture allCommands = executeAsyncCommands(context, commands, ASYNC_BATCH_SIZE); + assertNull(allCommands.get()); } return null; - } ); + }); } - @SuppressWarnings( "unchecked" ) - private CompletableFuture executeAsyncCommands( C context, List> commands, int count ) - { + @SuppressWarnings("unchecked") + private CompletableFuture executeAsyncCommands(C context, List> commands, int count) { CompletableFuture[] executions = new CompletableFuture[count]; - for ( int i = 0; i < count; i++ ) - { - AsyncCommand command = randomOf( commands ); - CompletionStage execution = command.execute( context ); + for (int i = 0; i < count; i++) { + AsyncCommand command = randomOf(commands); + CompletionStage execution = command.execute(context); executions[i] = execution.toCompletableFuture(); } - return CompletableFuture.allOf( executions ); + return CompletableFuture.allOf(executions); } - private ResourcesInfo sleepAndGetResourcesInfo() throws InterruptedException - { - int halfSleepSeconds = Math.max( 1, EXECUTION_TIME_SECONDS / 2 ); - SECONDS.sleep( halfSleepSeconds ); + private ResourcesInfo sleepAndGetResourcesInfo() throws InterruptedException { + int halfSleepSeconds = Math.max(1, EXECUTION_TIME_SECONDS / 2); + SECONDS.sleep(halfSleepSeconds); ResourcesInfo resourcesInfo = getResourcesInfo(); - SECONDS.sleep( halfSleepSeconds ); + SECONDS.sleep(halfSleepSeconds); return resourcesInfo; } - private ResourcesInfo getResourcesInfo() - { + private ResourcesInfo getResourcesInfo() { long openFileDescriptorCount = getOpenFileDescriptorCount(); Set acquiredLoggerNames = logging.getAcquiredLoggerNames(); - return new ResourcesInfo( openFileDescriptorCount, acquiredLoggerNames ); + return new ResourcesInfo(openFileDescriptorCount, acquiredLoggerNames); } - private void verifyResults( C context, ResourcesInfo resourcesInfo ) - { - assertNoFileDescriptorLeak( resourcesInfo.openFileDescriptorCount ); - assertNoLoggersLeak( resourcesInfo.acquiredLoggerNames ); - assertExpectedNumberOfNodesCreated( context.getCreatedNodesCount() ); + private void verifyResults(C context, ResourcesInfo resourcesInfo) { + assertNoFileDescriptorLeak(resourcesInfo.openFileDescriptorCount); + assertNoLoggersLeak(resourcesInfo.acquiredLoggerNames); + assertExpectedNumberOfNodesCreated(context.getCreatedNodesCount()); } - private void assertNoFileDescriptorLeak( long previousOpenFileDescriptors ) - { - System.out.println( "Initially open file descriptors: " + previousOpenFileDescriptors ); + private void assertNoFileDescriptorLeak(long previousOpenFileDescriptors) { + System.out.println("Initially open file descriptors: " + previousOpenFileDescriptors); // number of open file descriptors should not go up for more than 50% long maxOpenFileDescriptors = (long) (previousOpenFileDescriptors * 1.5); long currentOpenFileDescriptorCount = getOpenFileDescriptorCount(); - System.out.println( "Currently open file descriptors: " + currentOpenFileDescriptorCount ); + System.out.println("Currently open file descriptors: " + currentOpenFileDescriptorCount); - assertThat( "Unexpectedly high number of open file descriptors", - currentOpenFileDescriptorCount, lessThanOrEqualTo( maxOpenFileDescriptors ) ); + assertThat( + "Unexpectedly high number of open file descriptors", + currentOpenFileDescriptorCount, + lessThanOrEqualTo(maxOpenFileDescriptors)); } - private void assertNoLoggersLeak( Set previousAcquiredLoggerNames ) - { + private void assertNoLoggersLeak(Set previousAcquiredLoggerNames) { Set currentAcquiredLoggerNames = logging.getAcquiredLoggerNames(); - assertThat( "Unexpected amount of logger instances", - currentAcquiredLoggerNames, equalTo( previousAcquiredLoggerNames ) ); - } - - private void assertExpectedNumberOfNodesCreated( long expectedCount ) - { - try ( Session session = driver.session() ) - { - List records = session.run( "MATCH (n) RETURN count(n) AS nodesCount" ).list(); - assertEquals( 1, records.size() ); - Record record = records.get( 0 ); - long actualCount = record.get( "nodesCount" ).asLong(); - assertEquals( expectedCount, actualCount, "Unexpected number of nodes in the database" ); + assertThat( + "Unexpected amount of logger instances", + currentAcquiredLoggerNames, + equalTo(previousAcquiredLoggerNames)); + } + + private void assertExpectedNumberOfNodesCreated(long expectedCount) { + try (Session session = driver.session()) { + List records = + session.run("MATCH (n) RETURN count(n) AS nodesCount").list(); + assertEquals(1, records.size()); + Record record = records.get(0); + long actualCount = record.get("nodesCount").asLong(); + assertEquals(expectedCount, actualCount, "Unexpected number of nodes in the database"); } } - private static long getOpenFileDescriptorCount() - { - try - { + private static long getOpenFileDescriptorCount() { + try { OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean(); - Method method = osBean.getClass().getDeclaredMethod( "getOpenFileDescriptorCount" ); - method.setAccessible( true ); - return (long) method.invoke( osBean ); - } - catch ( Throwable t ) - { + Method method = osBean.getClass().getDeclaredMethod("getOpenFileDescriptorCount"); + method.setAccessible(true); + return (long) method.invoke(osBean); + } catch (Throwable t) { return 0; } } - private static Throwable withSuppressed( Throwable firstError, Throwable newError ) - { - if ( firstError == null ) - { + private static Throwable withSuppressed(Throwable firstError, Throwable newError) { + if (firstError == null) { return newError; } - firstError.addSuppressed( newError ); + firstError.addSuppressed(newError); return firstError; } - private static T randomOf( List elements ) - { - int index = ThreadLocalRandom.current().nextInt( elements.size() ); - return elements.get( index ); + private static T randomOf(List elements) { + int index = ThreadLocalRandom.current().nextInt(elements.size()); + return elements.get(index); } - private static int bigDataTestBatchCount() - { - if ( BIG_DATA_TEST_NODE_COUNT < BIG_DATA_TEST_BATCH_SIZE ) - { + private static int bigDataTestBatchCount() { + if (BIG_DATA_TEST_NODE_COUNT < BIG_DATA_TEST_BATCH_SIZE) { return 1; } return BIG_DATA_TEST_NODE_COUNT / BIG_DATA_TEST_BATCH_SIZE; } - private static Bookmark createNodesBlocking( int batchCount, int batchSize, Driver driver ) - { + private static Bookmark createNodesBlocking(int batchCount, int batchSize, Driver driver) { Bookmark bookmark; long start = System.nanoTime(); - try ( Session session = driver.session() ) - { - for ( int i = 0; i < batchCount; i++ ) - { + try (Session session = driver.session()) { + for (int i = 0; i < batchCount; i++) { int batchIndex = i; - session.writeTransaction( tx -> createNodesInTx( tx, batchIndex, batchSize ) ); + session.writeTransaction(tx -> createNodesInTx(tx, batchIndex, batchSize)); } bookmark = session.lastBookmark(); } long end = System.nanoTime(); - System.out.println( "Node creation with blocking API took: " + NANOSECONDS.toMillis( end - start ) + "ms" ); + System.out.println("Node creation with blocking API took: " + NANOSECONDS.toMillis(end - start) + "ms"); return bookmark; } - private static void readNodesBlocking( Driver driver, Bookmark bookmark, int expectedNodeCount ) - { + private static void readNodesBlocking(Driver driver, Bookmark bookmark, int expectedNodeCount) { long start = System.nanoTime(); - try ( Session session = driver.session( builder().withBookmarks( bookmark ).build() ) ) - { - int nodesProcessed = session.readTransaction( tx -> - { - Result result = tx.run( "MATCH (n:Node) RETURN n" ); + try (Session session = driver.session(builder().withBookmarks(bookmark).build())) { + int nodesProcessed = session.readTransaction(tx -> { + Result result = tx.run("MATCH (n:Node) RETURN n"); int nodesSeen = 0; - while ( result.hasNext() ) - { - Node node = result.next().get( 0 ).asNode(); + while (result.hasNext()) { + Node node = result.next().get(0).asNode(); nodesSeen++; - List labels = Iterables.asList( node.labels() ); - assertEquals( 2, labels.size() ); - assertTrue( labels.contains( "Test" ) ); - assertTrue( labels.contains( "Node" ) ); + List labels = Iterables.asList(node.labels()); + assertEquals(2, labels.size()); + assertTrue(labels.contains("Test")); + assertTrue(labels.contains("Node")); - verifyNodeProperties( node ); + verifyNodeProperties(node); } return nodesSeen; - } ); + }); - assertEquals( expectedNodeCount, nodesProcessed ); + assertEquals(expectedNodeCount, nodesProcessed); } long end = System.nanoTime(); - System.out.println( "Reading nodes with blocking API took: " + NANOSECONDS.toMillis( end - start ) + "ms" ); + System.out.println("Reading nodes with blocking API took: " + NANOSECONDS.toMillis(end - start) + "ms"); } - private static Bookmark createNodesAsync( int batchCount, int batchSize, Driver driver ) throws Throwable - { + private static Bookmark createNodesAsync(int batchCount, int batchSize, Driver driver) throws Throwable { long start = System.nanoTime(); AsyncSession session = driver.asyncSession(); - CompletableFuture writeTransactions = completedFuture( null ); + CompletableFuture writeTransactions = completedFuture(null); - for ( int i = 0; i < batchCount; i++ ) - { + for (int i = 0; i < batchCount; i++) { int batchIndex = i; - writeTransactions = writeTransactions.thenCompose( ignore -> - session.writeTransactionAsync( tx -> createNodesInTxAsync( tx, batchIndex, batchSize ) ) ); + writeTransactions = writeTransactions.thenCompose( + ignore -> session.writeTransactionAsync(tx -> createNodesInTxAsync(tx, batchIndex, batchSize))); } - writeTransactions = writeTransactions.exceptionally( error -> error ) - .thenCompose( error -> safeCloseSession( session, error ) ); + writeTransactions = + writeTransactions.exceptionally(error -> error).thenCompose(error -> safeCloseSession(session, error)); - Throwable error = Futures.blockingGet( writeTransactions ); - if ( error != null ) - { + Throwable error = Futures.blockingGet(writeTransactions); + if (error != null) { throw error; } long end = System.nanoTime(); - System.out.println( "Node creation with async API took: " + NANOSECONDS.toMillis( end - start ) + "ms" ); + System.out.println("Node creation with async API took: " + NANOSECONDS.toMillis(end - start) + "ms"); return session.lastBookmark(); } - private static void readNodesAsync( Driver driver, Bookmark bookmark, int expectedNodeCount ) throws Throwable - { + private static void readNodesAsync(Driver driver, Bookmark bookmark, int expectedNodeCount) throws Throwable { long start = System.nanoTime(); - AsyncSession session = driver.asyncSession( builder().withBookmarks( bookmark ).build() ); + AsyncSession session = + driver.asyncSession(builder().withBookmarks(bookmark).build()); AtomicInteger nodesSeen = new AtomicInteger(); - CompletionStage readQuery = session.readTransactionAsync( tx -> - tx.runAsync( "MATCH (n:Node) RETURN n" ) - .thenCompose( cursor -> cursor.forEachAsync( record -> - { - Node node = record.get( 0 ).asNode(); + CompletionStage readQuery = session.readTransactionAsync(tx -> tx.runAsync("MATCH (n:Node) RETURN n") + .thenCompose(cursor -> cursor.forEachAsync(record -> { + Node node = record.get(0).asNode(); nodesSeen.incrementAndGet(); - List labels = Iterables.asList( node.labels() ); - assertEquals( 2, labels.size() ); - assertTrue( labels.contains( "Test" ) ); - assertTrue( labels.contains( "Node" ) ); + List labels = Iterables.asList(node.labels()); + assertEquals(2, labels.size()); + assertTrue(labels.contains("Test")); + assertTrue(labels.contains("Node")); - verifyNodeProperties( node ); - } ) ) ) - .thenApply( summary -> (Throwable) null ) - .exceptionally( error -> error ) - .thenCompose( error -> safeCloseSession( session, error ) ); + verifyNodeProperties(node); + }))) + .thenApply(summary -> (Throwable) null) + .exceptionally(error -> error) + .thenCompose(error -> safeCloseSession(session, error)); - Throwable error = Futures.blockingGet( readQuery ); - if ( error != null ) - { + Throwable error = Futures.blockingGet(readQuery); + if (error != null) { throw error; } - assertEquals( expectedNodeCount, nodesSeen.get() ); + assertEquals(expectedNodeCount, nodesSeen.get()); long end = System.nanoTime(); - System.out.println( "Reading nodes with async API took: " + NANOSECONDS.toMillis( end - start ) + "ms" ); + System.out.println("Reading nodes with async API took: " + NANOSECONDS.toMillis(end - start) + "ms"); } - private Bookmark createNodesRx( int batchCount, int batchSize, InternalDriver driver ) - { + private Bookmark createNodesRx(int batchCount, int batchSize, InternalDriver driver) { long start = System.nanoTime(); RxSession session = driver.rxSession(); - Flux.concat( Flux.range( 0, batchCount ).map( batchIndex -> - session.writeTransaction( tx -> createNodesInTxRx( tx, batchIndex, batchSize ) ) - ) ).blockLast(); // throw any error if happened + Flux.concat(Flux.range(0, batchCount) + .map(batchIndex -> + session.writeTransaction(tx -> createNodesInTxRx(tx, batchIndex, batchSize)))) + .blockLast(); // throw any error if happened long end = System.nanoTime(); - System.out.println( "Node creation with reactive API took: " + NANOSECONDS.toMillis( end - start ) + "ms" ); + System.out.println("Node creation with reactive API took: " + NANOSECONDS.toMillis(end - start) + "ms"); return session.lastBookmark(); } - private Publisher createNodesInTxRx( RxTransaction tx, int batchIndex, int batchSize ) - { - return Flux.concat( Flux.range( 0, batchSize ).map( index -> batchIndex * batchSize + index ).map( nodeIndex -> { - Query query = createNodeInTxQuery( nodeIndex ); - return Flux.from( tx.run(query).consume() ).then(); // As long as there is no error - } ) ); + private Publisher createNodesInTxRx(RxTransaction tx, int batchIndex, int batchSize) { + return Flux.concat(Flux.range(0, batchSize) + .map(index -> batchIndex * batchSize + index) + .map(nodeIndex -> { + Query query = createNodeInTxQuery(nodeIndex); + return Flux.from(tx.run(query).consume()).then(); // As long as there is no error + })); } - private void readNodesRx( InternalDriver driver, Bookmark bookmark, int expectedNodeCount ) - { + private void readNodesRx(InternalDriver driver, Bookmark bookmark, int expectedNodeCount) { long start = System.nanoTime(); - RxSession session = driver.rxSession( builder().withBookmarks( bookmark ).build() ); + RxSession session = driver.rxSession(builder().withBookmarks(bookmark).build()); AtomicInteger nodesSeen = new AtomicInteger(); - Publisher readQuery = session.readTransaction( tx -> Flux.from( tx.run( "MATCH (n:Node) RETURN n" ).records() ).doOnNext( record -> { - Node node = record.get( 0 ).asNode(); - nodesSeen.incrementAndGet(); + Publisher readQuery = session.readTransaction( + tx -> Flux.from(tx.run("MATCH (n:Node) RETURN n").records()) + .doOnNext(record -> { + Node node = record.get(0).asNode(); + nodesSeen.incrementAndGet(); - List labels = Iterables.asList( node.labels() ); - assertEquals( 2, labels.size() ); - assertTrue( labels.contains( "Test" ) ); - assertTrue( labels.contains( "Node" ) ); + List labels = Iterables.asList(node.labels()); + assertEquals(2, labels.size()); + assertTrue(labels.contains("Test")); + assertTrue(labels.contains("Node")); - verifyNodeProperties( node ); - } ).then() ); + verifyNodeProperties(node); + }) + .then()); - Flux.from( readQuery ).blockLast(); + Flux.from(readQuery).blockLast(); - assertEquals( expectedNodeCount, nodesSeen.get() ); + assertEquals(expectedNodeCount, nodesSeen.get()); long end = System.nanoTime(); - System.out.println( "Reading nodes with async API took: " + NANOSECONDS.toMillis( end - start ) + "ms" ); + System.out.println("Reading nodes with async API took: " + NANOSECONDS.toMillis(end - start) + "ms"); } - private static Void createNodesInTx( Transaction tx, int batchIndex, int batchSize ) - { - for ( int index = 0; index < batchSize; index++ ) - { + private static Void createNodesInTx(Transaction tx, int batchIndex, int batchSize) { + for (int index = 0; index < batchSize; index++) { int nodeIndex = batchIndex * batchSize + index; - createNodeInTx( tx, nodeIndex ); + createNodeInTx(tx, nodeIndex); } return null; } - private static void createNodeInTx( Transaction tx, int nodeIndex ) - { - Query query = createNodeInTxQuery( nodeIndex ); + private static void createNodeInTx(Transaction tx, int nodeIndex) { + Query query = createNodeInTxQuery(nodeIndex); tx.run(query).consume(); } - private static CompletionStage createNodesInTxAsync( AsyncTransaction tx, int batchIndex, int batchSize ) - { - @SuppressWarnings( "unchecked" ) - CompletableFuture[] queryFutures = IntStream.range( 0, batchSize ) - .map( index -> batchIndex * batchSize + index ) - .mapToObj( nodeIndex -> createNodeInTxAsync( tx, nodeIndex ) ) - .toArray( CompletableFuture[]::new ); + private static CompletionStage createNodesInTxAsync(AsyncTransaction tx, int batchIndex, int batchSize) { + @SuppressWarnings("unchecked") + CompletableFuture[] queryFutures = IntStream.range(0, batchSize) + .map(index -> batchIndex * batchSize + index) + .mapToObj(nodeIndex -> createNodeInTxAsync(tx, nodeIndex)) + .toArray(CompletableFuture[]::new); - return CompletableFuture.allOf( queryFutures ) - .thenApply( ignored -> (Throwable) null ) - .exceptionally( error -> error ); + return CompletableFuture.allOf(queryFutures) + .thenApply(ignored -> (Throwable) null) + .exceptionally(error -> error); } - private static CompletableFuture createNodeInTxAsync( AsyncTransaction tx, int nodeIndex ) - { - Query query = createNodeInTxQuery( nodeIndex ); + private static CompletableFuture createNodeInTxAsync(AsyncTransaction tx, int nodeIndex) { + Query query = createNodeInTxQuery(nodeIndex); return tx.runAsync(query) - .thenCompose( ResultCursor::consumeAsync ) - .thenApply( ignore -> (Void) null ) + .thenCompose(ResultCursor::consumeAsync) + .thenApply(ignore -> (Void) null) .toCompletableFuture(); } - private static Query createNodeInTxQuery(int nodeIndex ) - { + private static Query createNodeInTxQuery(int nodeIndex) { String query = "CREATE (n:Test:Node) SET n = $props"; - Map params = singletonMap( "props", createNodeProperties( nodeIndex ) ); - return new Query( query, params ); - } - - private static Map createNodeProperties( int nodeIndex ) - { - Map result = new HashMap<>(); - result.put( "index", nodeIndex ); - result.put( "name", "name-" + nodeIndex ); - result.put( "surname", "surname-" + nodeIndex ); - result.put( "long-indices", nCopies( 10, (long) nodeIndex ) ); - result.put( "double-indices", nCopies( 10, (double) nodeIndex ) ); - result.put( "booleans", nCopies( 10, nodeIndex % 2 == 0 ) ); + Map params = singletonMap("props", createNodeProperties(nodeIndex)); + return new Query(query, params); + } + + private static Map createNodeProperties(int nodeIndex) { + Map result = new HashMap<>(); + result.put("index", nodeIndex); + result.put("name", "name-" + nodeIndex); + result.put("surname", "surname-" + nodeIndex); + result.put("long-indices", nCopies(10, (long) nodeIndex)); + result.put("double-indices", nCopies(10, (double) nodeIndex)); + result.put("booleans", nCopies(10, nodeIndex % 2 == 0)); return result; } - private static void verifyNodeProperties( Node node ) - { - int nodeIndex = node.get( "index" ).asInt(); - assertEquals( "name-" + nodeIndex, node.get( "name" ).asString() ); - assertEquals( "surname-" + nodeIndex, node.get( "surname" ).asString() ); - assertEquals( nCopies( 10, (long) nodeIndex ), node.get( "long-indices" ).asList() ); - assertEquals( nCopies( 10, (double) nodeIndex ), node.get( "double-indices" ).asList() ); - assertEquals( nCopies( 10, nodeIndex % 2 == 0 ), node.get( "booleans" ).asList() ); + private static void verifyNodeProperties(Node node) { + int nodeIndex = node.get("index").asInt(); + assertEquals("name-" + nodeIndex, node.get("name").asString()); + assertEquals("surname-" + nodeIndex, node.get("surname").asString()); + assertEquals(nCopies(10, (long) nodeIndex), node.get("long-indices").asList()); + assertEquals(nCopies(10, (double) nodeIndex), node.get("double-indices").asList()); + assertEquals(nCopies(10, nodeIndex % 2 == 0), node.get("booleans").asList()); } - private static CompletionStage safeCloseSession( AsyncSession session, T result ) - { - return session.closeAsync() - .exceptionally( ignore -> null ) - .thenApply( ignore -> result ); + private static CompletionStage safeCloseSession(AsyncSession session, T result) { + return session.closeAsync().exceptionally(ignore -> null).thenApply(ignore -> result); } - private static class ResourcesInfo - { + private static class ResourcesInfo { final long openFileDescriptorCount; final Set acquiredLoggerNames; - ResourcesInfo( long openFileDescriptorCount, Set acquiredLoggerNames ) - { + ResourcesInfo(long openFileDescriptorCount, Set acquiredLoggerNames) { this.openFileDescriptorCount = openFileDescriptorCount; this.acquiredLoggerNames = acquiredLoggerNames; } } - private static class LoggerNameTrackingLogging implements Logging - { - private final Logging consoleLogging = Logging.console( Level.FINE ); + private static class LoggerNameTrackingLogging implements Logging { + private final Logging consoleLogging = Logging.console(Level.FINE); private final Set acquiredLoggerNames = ConcurrentHashMap.newKeySet(); @Override - public Logger getLog( String name ) - { - acquiredLoggerNames.add( name ); - if ( DEBUG_LOGGING_ENABLED ) - { - return consoleLogging.getLog( name ); + public Logger getLog(String name) { + acquiredLoggerNames.add(name); + if (DEBUG_LOGGING_ENABLED) { + return consoleLogging.getLog(name); } return DevNullLogger.DEV_NULL_LOGGER; } - Set getAcquiredLoggerNames() - { - return new HashSet<>( acquiredLoggerNames ); + Set getAcquiredLoggerNames() { + return new HashSet<>(acquiredLoggerNames); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncCommand.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncCommand.java index 6b6a36df34..91f1c955c8 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncCommand.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncCommand.java @@ -20,7 +20,6 @@ import java.util.concurrent.CompletionStage; -public interface AsyncCommand -{ - CompletionStage execute( C context ); +public interface AsyncCommand { + CompletionStage execute(C context); } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQuery.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQuery.java index eab28574cc..17095a8de0 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQuery.java @@ -18,42 +18,37 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.neo4j.driver.internal.util.Matchers.arithmeticError; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.internal.util.Futures; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.neo4j.driver.internal.util.Matchers.arithmeticError; - -public class AsyncFailingQuery extends AbstractAsyncQuery -{ - public AsyncFailingQuery( Driver driver ) - { - super( driver, false ); +public class AsyncFailingQuery extends AbstractAsyncQuery { + public AsyncFailingQuery(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.READ, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.READ, context); - return session.runAsync( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ) - .thenCompose( ResultCursor::listAsync ) - .handle( ( records, error ) -> - { + return session.runAsync("UNWIND [10, 5, 0] AS x RETURN 10 / x") + .thenCompose(ResultCursor::listAsync) + .handle((records, error) -> { session.closeAsync(); - assertNull( records ); - Throwable cause = Futures.completionExceptionCause( error ); - assertThat( cause, is( arithmeticError() ) ); + assertNull(records); + Throwable cause = Futures.completionExceptionCause(error); + assertThat(cause, is(arithmeticError())); return null; - } ); + }); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQueryInTx.java index 7dca2d564f..5ed4118bef 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQueryInTx.java @@ -18,8 +18,12 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.neo4j.driver.internal.util.Matchers.arithmeticError; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.async.AsyncSession; @@ -27,35 +31,26 @@ import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.internal.util.Futures; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.neo4j.driver.internal.util.Matchers.arithmeticError; - -public class AsyncFailingQueryInTx extends AbstractAsyncQuery -{ - public AsyncFailingQueryInTx( Driver driver ) - { - super( driver, false ); +public class AsyncFailingQueryInTx extends AbstractAsyncQuery { + public AsyncFailingQueryInTx(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.READ, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.READ, context); return session.beginTransactionAsync() - .thenCompose( tx -> tx.runAsync( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ) - .thenCompose( ResultCursor::listAsync ) - .handle( ( records, error ) -> - { - assertNull( records ); - Throwable cause = Futures.completionExceptionCause( error ); - assertThat( cause, is( arithmeticError() ) ); + .thenCompose(tx -> tx.runAsync("UNWIND [10, 5, 0] AS x RETURN 10 / x") + .thenCompose(ResultCursor::listAsync) + .handle((records, error) -> { + assertNull(records); + Throwable cause = Futures.completionExceptionCause(error); + assertThat(cause, is(arithmeticError())); return tx; - } ) ) - .thenCompose( AsyncTransaction::rollbackAsync ) - .whenComplete( ( ignore, error ) -> session.closeAsync() ); + })) + .thenCompose(AsyncTransaction::rollbackAsync) + .whenComplete((ignore, error) -> session.closeAsync()); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQueryWithRetries.java index 5b8287ae16..1ade362b0c 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncFailingQueryWithRetries.java @@ -18,9 +18,13 @@ */ package org.neo4j.driver.stress; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.neo4j.driver.internal.util.Matchers.arithmeticError; + import java.util.List; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; @@ -28,36 +32,26 @@ import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.internal.util.Futures; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.neo4j.driver.internal.util.Matchers.arithmeticError; - -public class AsyncFailingQueryWithRetries extends AbstractAsyncQuery -{ - public AsyncFailingQueryWithRetries( Driver driver ) - { - super( driver, false ); +public class AsyncFailingQueryWithRetries extends AbstractAsyncQuery { + public AsyncFailingQueryWithRetries(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.READ, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.READ, context); - CompletionStage> txStage = session.readTransactionAsync( tx -> tx.runAsync( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ) - .thenCompose( ResultCursor::listAsync ) ); + CompletionStage> txStage = session.readTransactionAsync( + tx -> tx.runAsync("UNWIND [10, 5, 0] AS x RETURN 10 / x").thenCompose(ResultCursor::listAsync)); - CompletionStage resultsProcessingStage = txStage - .handle( ( records, error ) -> - { - assertNull( records ); - Throwable cause = Futures.completionExceptionCause( error ); - assertThat( cause, is( arithmeticError() ) ); + CompletionStage resultsProcessingStage = txStage.handle((records, error) -> { + assertNull(records); + Throwable cause = Futures.completionExceptionCause(error); + assertThat(cause, is(arithmeticError())); - return null; - } ); + return null; + }); - return resultsProcessingStage.whenComplete( ( nothing, throwable ) -> session.closeAsync() ); + return resultsProcessingStage.whenComplete((nothing, throwable) -> session.closeAsync()); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQuery.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQuery.java index 1fc0d3ce27..b0771e62f5 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQuery.java @@ -18,8 +18,9 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; @@ -28,42 +29,32 @@ import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.types.Node; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class AsyncReadQuery extends AbstractAsyncQuery -{ - public AsyncReadQuery( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class AsyncReadQuery extends AbstractAsyncQuery { + public AsyncReadQuery(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.READ, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.READ, context); - CompletionStage queryFinished = session.runAsync( "MATCH (n) RETURN n LIMIT 1" ) - .thenCompose( cursor -> cursor.nextAsync() - .thenCompose( record -> processAndGetSummary( record, cursor ) ) ); + CompletionStage queryFinished = session.runAsync("MATCH (n) RETURN n LIMIT 1") + .thenCompose(cursor -> cursor.nextAsync().thenCompose(record -> processAndGetSummary(record, cursor))); - queryFinished.whenComplete( ( summary, error ) -> - { - if ( summary != null ) - { - context.readCompleted( summary ); + queryFinished.whenComplete((summary, error) -> { + if (summary != null) { + context.readCompleted(summary); } session.closeAsync(); - } ); + }); - return queryFinished.thenApply( summary -> null ); + return queryFinished.thenApply(summary -> null); } - private CompletionStage processAndGetSummary( Record record, ResultCursor cursor ) - { - if ( record != null ) - { - Node node = record.get( 0 ).asNode(); - assertNotNull( node ); + private CompletionStage processAndGetSummary(Record record, ResultCursor cursor) { + if (record != null) { + Node node = record.get(0).asNode(); + assertNotNull(node); } return cursor.consumeAsync(); } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQueryInTx.java index 857af09362..8d03569791 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQueryInTx.java @@ -18,8 +18,9 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; @@ -29,44 +30,35 @@ import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.types.Node; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class AsyncReadQueryInTx extends AbstractAsyncQuery -{ - public AsyncReadQueryInTx( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class AsyncReadQueryInTx extends AbstractAsyncQuery { + public AsyncReadQueryInTx(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public CompletionStage execute( C ctx ) - { - AsyncSession session = newSession( AccessMode.READ, ctx ); + public CompletionStage execute(C ctx) { + AsyncSession session = newSession(AccessMode.READ, ctx); CompletionStage txCommitted = session.beginTransactionAsync() - .thenCompose( tx -> tx.runAsync( "MATCH (n) RETURN n LIMIT 1" ) - .thenCompose( cursor -> cursor.nextAsync() - .thenCompose( record -> processRecordAndGetSummary( record, cursor ) - .thenCompose( summary -> processSummaryAndCommit( summary, tx, ctx ) ) ) ) ); + .thenCompose(tx -> tx.runAsync("MATCH (n) RETURN n LIMIT 1").thenCompose(cursor -> cursor.nextAsync() + .thenCompose(record -> processRecordAndGetSummary(record, cursor) + .thenCompose(summary -> processSummaryAndCommit(summary, tx, ctx))))); - txCommitted.whenComplete( ( ignore, error ) -> session.closeAsync() ); + txCommitted.whenComplete((ignore, error) -> session.closeAsync()); return txCommitted; } - private CompletionStage processRecordAndGetSummary( Record record, ResultCursor cursor ) - { - if ( record != null ) - { - Node node = record.get( 0 ).asNode(); - assertNotNull( node ); + private CompletionStage processRecordAndGetSummary(Record record, ResultCursor cursor) { + if (record != null) { + Node node = record.get(0).asNode(); + assertNotNull(node); } return cursor.consumeAsync(); } - private CompletionStage processSummaryAndCommit( ResultSummary summary, AsyncTransaction tx, C context ) - { - context.readCompleted( summary ); + private CompletionStage processSummaryAndCommit(ResultSummary summary, AsyncTransaction tx, C context) { + context.readCompleted(summary); return tx.commitAsync(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQueryWithRetries.java index fa6589918d..da43b584b5 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncReadQueryWithRetries.java @@ -18,8 +18,9 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; @@ -28,47 +29,36 @@ import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.types.Node; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class AsyncReadQueryWithRetries extends AbstractAsyncQuery -{ - public AsyncReadQueryWithRetries( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class AsyncReadQueryWithRetries extends AbstractAsyncQuery { + public AsyncReadQueryWithRetries(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.READ, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.READ, context); CompletionStage txStage = session.readTransactionAsync( - tx -> tx.runAsync( "MATCH (n) RETURN n LIMIT 1" ) - .thenCompose( - cursor -> cursor.nextAsync() - .thenCompose( - record -> processRecordAndGetSummary( record, cursor ) ) ) ); + tx -> tx.runAsync("MATCH (n) RETURN n LIMIT 1").thenCompose(cursor -> cursor.nextAsync() + .thenCompose(record -> processRecordAndGetSummary(record, cursor)))); - CompletionStage resultsProcessingStage = txStage.thenApply( resultSummary -> processResultSummary( resultSummary, context ) ); + CompletionStage resultsProcessingStage = + txStage.thenApply(resultSummary -> processResultSummary(resultSummary, context)); - return resultsProcessingStage.whenComplete( ( nothing, throwable ) -> session.closeAsync() ); + return resultsProcessingStage.whenComplete((nothing, throwable) -> session.closeAsync()); } - private CompletionStage processRecordAndGetSummary( Record record, ResultCursor cursor ) - { - if ( record != null ) - { - Node node = record.get( 0 ).asNode(); - assertNotNull( node ); + private CompletionStage processRecordAndGetSummary(Record record, ResultCursor cursor) { + if (record != null) { + Node node = record.get(0).asNode(); + assertNotNull(node); } return cursor.consumeAsync(); } - private Void processResultSummary( ResultSummary resultSummary, C context ) - { - if ( resultSummary != null ) - { - context.readCompleted( resultSummary ); + private Void processResultSummary(ResultSummary resultSummary, C context) { + if (resultSummary != null) { + context.readCompleted(resultSummary); } return null; } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQuery.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQuery.java index e683ed68a6..52fc97041d 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQuery.java @@ -18,57 +18,47 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.internal.util.Futures; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class AsyncWriteQuery extends AbstractAsyncQuery -{ +public class AsyncWriteQuery extends AbstractAsyncQuery { private AbstractStressTestBase stressTest; - public AsyncWriteQuery( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public AsyncWriteQuery(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.WRITE, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.WRITE, context); - return session.runAsync( "CREATE ()" ) - .thenCompose( ResultCursor::consumeAsync ) - .handle( ( summary, error ) -> - { + return session.runAsync("CREATE ()") + .thenCompose(ResultCursor::consumeAsync) + .handle((summary, error) -> { session.closeAsync(); - if ( error != null ) - { - handleError( Futures.completionExceptionCause( error ), context ); - } - else - { - context.setBookmark( session.lastBookmark() ); - assertEquals( 1, summary.counters().nodesCreated() ); + if (error != null) { + handleError(Futures.completionExceptionCause(error), context); + } else { + context.setBookmark(session.lastBookmark()); + assertEquals(1, summary.counters().nodesCreated()); context.nodeCreated(); } return null; - } ); + }); } - private void handleError( Throwable error, C context ) - { - if ( !stressTest.handleWriteFailure( error, context ) ) - { - throw new RuntimeException( error ); + private void handleError(Throwable error, C context) { + if (!stressTest.handleWriteFailure(error, context)) { + throw new RuntimeException(error); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQueryInTx.java index 7f566d3ac7..bb45615f8c 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQueryInTx.java @@ -18,61 +18,51 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.summary.ResultSummary; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class AsyncWriteQueryInTx extends AbstractAsyncQuery -{ +public class AsyncWriteQueryInTx extends AbstractAsyncQuery { private AbstractStressTestBase stressTest; - public AsyncWriteQueryInTx( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public AsyncWriteQueryInTx(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.WRITE, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.WRITE, context); - CompletionStage txCommitted = session.beginTransactionAsync().thenCompose( tx -> - tx.runAsync( "CREATE ()" ).thenCompose( cursor -> - cursor.consumeAsync().thenCompose( summary -> tx.commitAsync().thenApply( ignore -> { - context.setBookmark( session.lastBookmark() ); + CompletionStage txCommitted = session.beginTransactionAsync() + .thenCompose(tx -> tx.runAsync("CREATE ()").thenCompose(cursor -> cursor.consumeAsync() + .thenCompose(summary -> tx.commitAsync().thenApply(ignore -> { + context.setBookmark(session.lastBookmark()); return summary; - } ) ) ) ); + })))); - return txCommitted.handle( ( summary, error ) -> - { + return txCommitted.handle((summary, error) -> { session.closeAsync(); - if ( error != null ) - { - handleError( Futures.completionExceptionCause( error ), context ); - } - else - { - assertEquals( 1, summary.counters().nodesCreated() ); + if (error != null) { + handleError(Futures.completionExceptionCause(error), context); + } else { + assertEquals(1, summary.counters().nodesCreated()); context.nodeCreated(); } return null; - } ); + }); } - private void handleError( Throwable error, C context ) - { - if ( !stressTest.handleWriteFailure( error, context ) ) - { - throw new RuntimeException( error ); + private void handleError(Throwable error, C context) { + if (!stressTest.handleWriteFailure(error, context)) { + throw new RuntimeException(error); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQueryWithRetries.java index 68b70baaa9..424ff62ddf 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncWriteQueryWithRetries.java @@ -18,59 +18,51 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.summary.ResultSummary; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class AsyncWriteQueryWithRetries extends AbstractAsyncQuery -{ +public class AsyncWriteQueryWithRetries extends AbstractAsyncQuery { private final AbstractStressTestBase stressTest; - public AsyncWriteQueryWithRetries( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public AsyncWriteQueryWithRetries(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.WRITE, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.WRITE, context); - CompletionStage txStage = session.writeTransactionAsync( - tx -> tx.runAsync( "CREATE ()" ).thenCompose( ResultCursor::consumeAsync ) ); + CompletionStage txStage = + session.writeTransactionAsync(tx -> tx.runAsync("CREATE ()").thenCompose(ResultCursor::consumeAsync)); - return txStage.thenApply( resultSummary -> processResultSummary( resultSummary, context ) ) - .handle( ( nothing, throwable ) -> recordAndRethrowThrowable( throwable, context ) ) - .whenComplete( ( nothing, throwable ) -> finalizeSession( session, context ) ); + return txStage.thenApply(resultSummary -> processResultSummary(resultSummary, context)) + .handle((nothing, throwable) -> recordAndRethrowThrowable(throwable, context)) + .whenComplete((nothing, throwable) -> finalizeSession(session, context)); } - private Void processResultSummary( ResultSummary resultSummary, C context ) - { - assertEquals( 1, resultSummary.counters().nodesCreated() ); + private Void processResultSummary(ResultSummary resultSummary, C context) { + assertEquals(1, resultSummary.counters().nodesCreated()); context.nodeCreated(); return null; } - private Void recordAndRethrowThrowable( Throwable throwable, C context ) - { - if ( throwable != null ) - { - stressTest.handleWriteFailure( throwable, context ); - throw new RuntimeException( throwable ); + private Void recordAndRethrowThrowable(Throwable throwable, C context) { + if (throwable != null) { + stressTest.handleWriteFailure(throwable, context); + throw new RuntimeException(throwable); } return null; } - private void finalizeSession( AsyncSession session, C context ) - { - context.setBookmark( session.lastBookmark() ); + private void finalizeSession(AsyncSession session, C context) { + context.setBookmark(session.lastBookmark()); session.closeAsync(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQuery.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQuery.java index 3afc6cb6fb..3e3a968699 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQuery.java @@ -18,8 +18,13 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.async.AsyncSession; @@ -28,37 +33,27 @@ import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.internal.util.Futures; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -public class AsyncWrongQuery extends AbstractAsyncQuery -{ - public AsyncWrongQuery( Driver driver ) - { - super( driver, false ); +public class AsyncWrongQuery extends AbstractAsyncQuery { + public AsyncWrongQuery(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.READ, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.READ, context); - return session.runAsync( "RETURN Wrong" ) - .thenCompose( ResultCursor::nextAsync ) - .handle( ( record, error ) -> - { + return session.runAsync("RETURN Wrong") + .thenCompose(ResultCursor::nextAsync) + .handle((record, error) -> { session.closeAsync(); - assertNull( record ); + assertNull(record); - Throwable cause = Futures.completionExceptionCause( error ); - assertNotNull( cause ); - assertThat( cause, instanceOf( ClientException.class ) ); - assertThat( ((Neo4jException) cause).code(), containsString( "SyntaxError" ) ); + Throwable cause = Futures.completionExceptionCause(error); + assertNotNull(cause); + assertThat(cause, instanceOf(ClientException.class)); + assertThat(((Neo4jException) cause).code(), containsString("SyntaxError")); return null; - } ); + }); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQueryInTx.java index 55e9868152..c36a386b5a 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQueryInTx.java @@ -18,8 +18,13 @@ */ package org.neo4j.driver.stress; -import java.util.concurrent.CompletionStage; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import java.util.concurrent.CompletionStage; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.async.AsyncSession; @@ -29,39 +34,29 @@ import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.internal.util.Futures; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -public class AsyncWrongQueryInTx extends AbstractAsyncQuery -{ - public AsyncWrongQueryInTx( Driver driver ) - { - super( driver, false ); +public class AsyncWrongQueryInTx extends AbstractAsyncQuery { + public AsyncWrongQueryInTx(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.READ, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.READ, context); return session.beginTransactionAsync() - .thenCompose( tx -> tx.runAsync( "RETURN Wrong" ) - .thenCompose( ResultCursor::nextAsync ) - .handle( ( record, error ) -> - { - assertNull( record ); + .thenCompose(tx -> tx.runAsync("RETURN Wrong") + .thenCompose(ResultCursor::nextAsync) + .handle((record, error) -> { + assertNull(record); - Throwable cause = Futures.completionExceptionCause( error ); - assertNotNull( cause ); - assertThat( cause, instanceOf( ClientException.class ) ); - assertThat( ((Neo4jException) cause).code(), containsString( "SyntaxError" ) ); + Throwable cause = Futures.completionExceptionCause(error); + assertNotNull(cause); + assertThat(cause, instanceOf(ClientException.class)); + assertThat(((Neo4jException) cause).code(), containsString("SyntaxError")); return tx; - } ) ) - .thenCompose( AsyncTransaction::rollbackAsync ) - .whenComplete( ( ignore, error ) -> session.closeAsync() ); + })) + .thenCompose(AsyncTransaction::rollbackAsync) + .whenComplete((ignore, error) -> session.closeAsync()); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQueryWithRetries.java index b9156696b5..59fb40b376 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/AsyncWrongQueryWithRetries.java @@ -18,9 +18,14 @@ */ package org.neo4j.driver.stress; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicReference; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; @@ -30,55 +35,38 @@ import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.summary.ResultSummary; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -public class AsyncWrongQueryWithRetries extends AbstractAsyncQuery -{ - public AsyncWrongQueryWithRetries( Driver driver ) - { - super( driver, false ); +public class AsyncWrongQueryWithRetries extends AbstractAsyncQuery { + public AsyncWrongQueryWithRetries(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { - AsyncSession session = newSession( AccessMode.READ, context ); + public CompletionStage execute(C context) { + AsyncSession session = newSession(AccessMode.READ, context); AtomicReference recordRef = new AtomicReference<>(); AtomicReference throwableRef = new AtomicReference<>(); - CompletionStage txStage = session.readTransactionAsync( - tx -> tx.runAsync( "RETURN Wrong" ) - .thenCompose( - cursor -> cursor.nextAsync() - .thenCompose( - record -> - { - recordRef.set( record ); - return cursor.consumeAsync(); - } ) ) ); + CompletionStage txStage = session.readTransactionAsync(tx -> tx.runAsync("RETURN Wrong") + .thenCompose(cursor -> cursor.nextAsync().thenCompose(record -> { + recordRef.set(record); + return cursor.consumeAsync(); + }))); - CompletionStage resultsProcessingStage = txStage - .handle( ( resultSummary, throwable ) -> - { - throwableRef.set( throwable ); - return null; - } ) - .thenApply( nothing -> - { - assertNull( recordRef.get() ); + CompletionStage resultsProcessingStage = txStage.handle((resultSummary, throwable) -> { + throwableRef.set(throwable); + return null; + }) + .thenApply(nothing -> { + assertNull(recordRef.get()); - Throwable cause = Futures.completionExceptionCause( throwableRef.get() ); - assertNotNull( cause ); - assertThat( cause, instanceOf( ClientException.class ) ); - assertThat( ((Neo4jException) cause).code(), containsString( "SyntaxError" ) ); - return null; - } ); + Throwable cause = Futures.completionExceptionCause(throwableRef.get()); + assertNotNull(cause); + assertThat(cause, instanceOf(ClientException.class)); + assertThat(((Neo4jException) cause).code(), containsString("SyntaxError")); + return null; + }); - return resultsProcessingStage.whenComplete( ( nothing, throwable ) -> session.closeAsync() ); + return resultsProcessingStage.whenComplete((nothing, throwable) -> session.closeAsync()); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingCommand.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingCommand.java index e41e56c643..bf2a37b3f6 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingCommand.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingCommand.java @@ -18,7 +18,6 @@ */ package org.neo4j.driver.stress; -public interface BlockingCommand -{ - void execute( C context ); +public interface BlockingCommand { + void execute(C context); } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQuery.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQuery.java index 8202340eed..318818f24c 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQuery.java @@ -18,31 +18,27 @@ */ package org.neo4j.driver.stress; -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; -import org.neo4j.driver.Result; - import static org.hamcrest.Matchers.is; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.neo4j.driver.internal.util.Matchers.arithmeticError; -public class BlockingFailingQuery extends AbstractBlockingQuery -{ - public BlockingFailingQuery( Driver driver ) - { - super( driver, false ); +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Result; +import org.neo4j.driver.Session; + +public class BlockingFailingQuery extends AbstractBlockingQuery { + public BlockingFailingQuery(Driver driver) { + super(driver, false); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { - Result result = session.run( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ); - Exception e = assertThrows( Exception.class, result::consume ); - assertThat( e, is( arithmeticError() ) ); + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { + Result result = session.run("UNWIND [10, 5, 0] AS x RETURN 10 / x"); + Exception e = assertThrows(Exception.class, result::consume); + assertThat(e, is(arithmeticError())); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQueryInTx.java index 6634226877..82b2f08875 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQueryInTx.java @@ -18,35 +18,30 @@ */ package org.neo4j.driver.stress; -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; -import org.neo4j.driver.Result; -import org.neo4j.driver.Transaction; - import static org.hamcrest.Matchers.is; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.neo4j.driver.internal.util.Matchers.arithmeticError; -public class BlockingFailingQueryInTx extends AbstractBlockingQuery -{ - public BlockingFailingQueryInTx( Driver driver ) - { - super( driver, false ); +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Result; +import org.neo4j.driver.Session; +import org.neo4j.driver.Transaction; + +public class BlockingFailingQueryInTx extends AbstractBlockingQuery { + public BlockingFailingQueryInTx(Driver driver) { + super(driver, false); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { - try ( Transaction tx = beginTransaction( session, context ) ) - { - Result result = tx.run( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ); + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { + try (Transaction tx = beginTransaction(session, context)) { + Result result = tx.run("UNWIND [10, 5, 0] AS x RETURN 10 / x"); - Exception e = assertThrows( Exception.class, result::consume ); - assertThat( e, is( arithmeticError() ) ); + Exception e = assertThrows(Exception.class, result::consume); + assertThat(e, is(arithmeticError())); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQueryWithRetries.java index cd49625572..b3b98addbe 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingFailingQueryWithRetries.java @@ -18,31 +18,28 @@ */ package org.neo4j.driver.stress; -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; - import static org.hamcrest.Matchers.is; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.neo4j.driver.internal.util.Matchers.arithmeticError; -public class BlockingFailingQueryWithRetries extends AbstractBlockingQuery -{ - public BlockingFailingQueryWithRetries( Driver driver ) - { - super( driver, false ); +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Session; + +public class BlockingFailingQueryWithRetries extends AbstractBlockingQuery { + public BlockingFailingQueryWithRetries(Driver driver) { + super(driver, false); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { Exception e = assertThrows( Exception.class, - () -> session.readTransaction( tx -> tx.run( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ).consume() ) ); - assertThat( e, is( arithmeticError() ) ); + () -> session.readTransaction( + tx -> tx.run("UNWIND [10, 5, 0] AS x RETURN 10 / x").consume())); + assertThat(e, is(arithmeticError())); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQuery.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQuery.java index d9c56f2dd9..8473458ee3 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQuery.java @@ -18,40 +18,34 @@ */ package org.neo4j.driver.stress; -import java.util.List; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.neo4j.driver.internal.util.Iterables.single; +import java.util.List; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.types.Node; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.neo4j.driver.internal.util.Iterables.single; - -public class BlockingReadQuery extends AbstractBlockingQuery -{ - public BlockingReadQuery( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class BlockingReadQuery extends AbstractBlockingQuery { + public BlockingReadQuery(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { - Result result = session.run( "MATCH (n) RETURN n LIMIT 1" ); + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { + Result result = session.run("MATCH (n) RETURN n LIMIT 1"); List records = result.list(); - if ( !records.isEmpty() ) - { - Record record = single( records ); - Node node = record.get( 0 ).asNode(); - assertNotNull( node ); + if (!records.isEmpty()) { + Record record = single(records); + Node node = record.get(0).asNode(); + assertNotNull(node); } - context.readCompleted( result.consume() ); + context.readCompleted(result.consume()); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQueryInTx.java index 713064dc01..4bfbe40158 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQueryInTx.java @@ -18,42 +18,36 @@ */ package org.neo4j.driver.stress; -import java.util.List; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.neo4j.driver.internal.util.Iterables.single; +import java.util.List; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; import org.neo4j.driver.types.Node; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.neo4j.driver.internal.util.Iterables.single; - -public class BlockingReadQueryInTx extends AbstractBlockingQuery -{ - public BlockingReadQueryInTx( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class BlockingReadQueryInTx extends AbstractBlockingQuery { + public BlockingReadQueryInTx(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ); - Transaction tx = beginTransaction( session, context ) ) - { - Result result = tx.run( "MATCH (n) RETURN n LIMIT 1" ); + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context); + Transaction tx = beginTransaction(session, context)) { + Result result = tx.run("MATCH (n) RETURN n LIMIT 1"); List records = result.list(); - if ( !records.isEmpty() ) - { - Record record = single( records ); - Node node = record.get( 0 ).asNode(); - assertNotNull( node ); + if (!records.isEmpty()) { + Record record = single(records); + Node node = record.get(0).asNode(); + assertNotNull(node); } - context.readCompleted( result.consume() ); + context.readCompleted(result.consume()); tx.commit(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQueryWithRetries.java index 2819593136..c951cf7e36 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingReadQueryWithRetries.java @@ -18,8 +18,10 @@ */ package org.neo4j.driver.stress; -import java.util.List; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.neo4j.driver.internal.util.Iterables.single; +import java.util.List; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; @@ -28,36 +30,26 @@ import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.types.Node; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.neo4j.driver.internal.util.Iterables.single; - -public class BlockingReadQueryWithRetries extends AbstractBlockingQuery -{ - public BlockingReadQueryWithRetries( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class BlockingReadQueryWithRetries extends AbstractBlockingQuery { + public BlockingReadQueryWithRetries(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { - ResultSummary resultSummary = session.readTransaction( - tx -> - { - Result result = tx.run( "MATCH (n) RETURN n LIMIT 1" ); - List records = result.list(); - if ( !records.isEmpty() ) - { - Record record = single( records ); - Node node = record.get( 0 ).asNode(); - assertNotNull( node ); - } + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { + ResultSummary resultSummary = session.readTransaction(tx -> { + Result result = tx.run("MATCH (n) RETURN n LIMIT 1"); + List records = result.list(); + if (!records.isEmpty()) { + Record record = single(records); + Node node = record.get(0).asNode(); + assertNotNull(node); + } - return result.consume(); - } ); - context.readCompleted( resultSummary ); + return result.consume(); + }); + context.readCompleted(resultSummary); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQuery.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQuery.java index ad3d17e908..890d728ed3 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQuery.java @@ -18,46 +18,38 @@ */ package org.neo4j.driver.stress; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Session; import org.neo4j.driver.summary.ResultSummary; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class BlockingWriteQuery extends AbstractBlockingQuery -{ +public class BlockingWriteQuery extends AbstractBlockingQuery { private AbstractStressTestBase stressTest; - public BlockingWriteQuery( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public BlockingWriteQuery(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public void execute( C context ) - { + public void execute(C context) { ResultSummary summary = null; Throwable queryError = null; - try ( Session session = newSession( AccessMode.WRITE, context ) ) - { - summary = session.run( "CREATE ()" ).consume(); - context.setBookmark( session.lastBookmark() ); - } - catch ( Throwable error ) - { + try (Session session = newSession(AccessMode.WRITE, context)) { + summary = session.run("CREATE ()").consume(); + context.setBookmark(session.lastBookmark()); + } catch (Throwable error) { queryError = error; - if ( !stressTest.handleWriteFailure( error, context ) ) - { + if (!stressTest.handleWriteFailure(error, context)) { throw error; } } - if ( queryError == null && summary != null ) - { - assertEquals( 1, summary.counters().nodesCreated() ); + if (queryError == null && summary != null) { + assertEquals(1, summary.counters().nodesCreated()); context.nodeCreated(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryInTx.java index 538d463cd8..8c8e6bf607 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryInTx.java @@ -18,52 +18,43 @@ */ package org.neo4j.driver.stress; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class BlockingWriteQueryInTx extends AbstractBlockingQuery -{ +public class BlockingWriteQueryInTx extends AbstractBlockingQuery { private AbstractStressTestBase stressTest; - public BlockingWriteQueryInTx( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public BlockingWriteQueryInTx(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public void execute( C context ) - { + public void execute(C context) { Result result = null; Throwable txError = null; - try ( Session session = newSession( AccessMode.WRITE, context ) ) - { - try ( Transaction tx = beginTransaction( session, context ) ) - { - result = tx.run( "CREATE ()" ); + try (Session session = newSession(AccessMode.WRITE, context)) { + try (Transaction tx = beginTransaction(session, context)) { + result = tx.run("CREATE ()"); tx.commit(); } - context.setBookmark( session.lastBookmark() ); - } - catch ( Throwable error ) - { + context.setBookmark(session.lastBookmark()); + } catch (Throwable error) { txError = error; - if ( !stressTest.handleWriteFailure( error, context ) ) - { + if (!stressTest.handleWriteFailure(error, context)) { throw error; } } - if ( txError == null && result != null ) - { - assertEquals( 1, result.consume().counters().nodesCreated() ); + if (txError == null && result != null) { + assertEquals(1, result.consume().counters().nodesCreated()); context.nodeCreated(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryUsingReadSessionWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryUsingReadSessionWithRetries.java index 0b80667735..9514fe56b5 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryUsingReadSessionWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryUsingReadSessionWithRetries.java @@ -18,26 +18,22 @@ */ package org.neo4j.driver.stress; +import static org.junit.jupiter.api.Assertions.assertThrows; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Session; import org.neo4j.driver.exceptions.ClientException; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class BlockingWriteQueryUsingReadSessionWithRetries extends AbstractBlockingQuery -{ - public BlockingWriteQueryUsingReadSessionWithRetries( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class BlockingWriteQueryUsingReadSessionWithRetries extends AbstractBlockingQuery { + public BlockingWriteQueryUsingReadSessionWithRetries(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { - assertThrows( ClientException.class, () -> session.readTransaction( tx -> tx.run( "CREATE ()" ) ) ); + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { + assertThrows(ClientException.class, () -> session.readTransaction(tx -> tx.run("CREATE ()"))); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryWithRetries.java index 181a46244a..beab3835b9 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingWriteQueryWithRetries.java @@ -18,36 +18,31 @@ */ package org.neo4j.driver.stress; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Session; import org.neo4j.driver.summary.ResultSummary; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class BlockingWriteQueryWithRetries extends AbstractBlockingQuery -{ +public class BlockingWriteQueryWithRetries extends AbstractBlockingQuery { private final AbstractStressTestBase stressTest; - public BlockingWriteQueryWithRetries( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public BlockingWriteQueryWithRetries(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.WRITE, context ) ) - { - ResultSummary resultSummary = session.writeTransaction( tx -> tx.run( "CREATE ()" ).consume() ); - assertEquals( 1, resultSummary.counters().nodesCreated() ); + public void execute(C context) { + try (Session session = newSession(AccessMode.WRITE, context)) { + ResultSummary resultSummary = + session.writeTransaction(tx -> tx.run("CREATE ()").consume()); + assertEquals(1, resultSummary.counters().nodesCreated()); context.nodeCreated(); - context.setBookmark( session.lastBookmark() ); - } - catch ( RuntimeException error ) - { - stressTest.handleWriteFailure( error, context ); + context.setBookmark(session.lastBookmark()); + } catch (RuntimeException error) { + stressTest.handleWriteFailure(error, context); throw error; } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQuery.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQuery.java index d3f304e295..21f2cb88d7 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQuery.java @@ -18,29 +18,26 @@ */ package org.neo4j.driver.stress; -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; - import static org.hamcrest.Matchers.is; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.neo4j.driver.internal.util.Matchers.syntaxError; -public class BlockingWrongQuery extends AbstractBlockingQuery -{ - public BlockingWrongQuery( Driver driver ) - { - super( driver, false ); +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Session; + +public class BlockingWrongQuery extends AbstractBlockingQuery { + public BlockingWrongQuery(Driver driver) { + super(driver, false); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { - Exception e = assertThrows( Exception.class, () -> session.run( "RETURN" ).consume() ); - assertThat( e, is( syntaxError() ) ); + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { + Exception e = + assertThrows(Exception.class, () -> session.run("RETURN").consume()); + assertThat(e, is(syntaxError())); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQueryInTx.java index 7687bdf7f3..043306aa30 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQueryInTx.java @@ -18,32 +18,27 @@ */ package org.neo4j.driver.stress; -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; -import org.neo4j.driver.Transaction; - import static org.hamcrest.Matchers.is; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.neo4j.driver.internal.util.Matchers.syntaxError; -public class BlockingWrongQueryInTx extends AbstractBlockingQuery -{ - public BlockingWrongQueryInTx( Driver driver ) - { - super( driver, false ); +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Session; +import org.neo4j.driver.Transaction; + +public class BlockingWrongQueryInTx extends AbstractBlockingQuery { + public BlockingWrongQueryInTx(Driver driver) { + super(driver, false); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { - try ( Transaction tx = beginTransaction( session, context ) ) - { - Exception e = assertThrows( Exception.class, () -> tx.run( "RETURN" ) ); - assertThat( e, is( syntaxError() ) ); + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { + try (Transaction tx = beginTransaction(session, context)) { + Exception e = assertThrows(Exception.class, () -> tx.run("RETURN")); + assertThat(e, is(syntaxError())); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQueryWithRetries.java index 1e218216a5..460aab6437 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/BlockingWrongQueryWithRetries.java @@ -18,29 +18,27 @@ */ package org.neo4j.driver.stress; -import org.neo4j.driver.AccessMode; -import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; - import static org.hamcrest.Matchers.is; import static org.hamcrest.junit.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.neo4j.driver.internal.util.Matchers.syntaxError; -public class BlockingWrongQueryWithRetries extends AbstractBlockingQuery -{ - public BlockingWrongQueryWithRetries( Driver driver ) - { - super( driver, false ); +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Session; + +public class BlockingWrongQueryWithRetries extends AbstractBlockingQuery { + public BlockingWrongQueryWithRetries(Driver driver) { + super(driver, false); } @Override - public void execute( C context ) - { - try ( Session session = newSession( AccessMode.READ, context ) ) - { - Exception e = assertThrows( Exception.class, () -> session.readTransaction( tx -> tx.run( "RETURN" ).consume() ) ); - assertThat( e, is( syntaxError() ) ); + public void execute(C context) { + try (Session session = newSession(AccessMode.READ, context)) { + Exception e = assertThrows( + Exception.class, + () -> session.readTransaction(tx -> tx.run("RETURN").consume())); + assertThat(e, is(syntaxError())); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringIT.java b/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringIT.java index 50edaa90f2..f105eb8739 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringIT.java +++ b/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringIT.java @@ -18,11 +18,12 @@ */ package org.neo4j.driver.stress; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.extension.RegisterExtension; +import static org.neo4j.driver.Logging.none; +import static org.neo4j.driver.SessionConfig.builder; import java.net.URI; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @@ -31,48 +32,37 @@ import org.neo4j.driver.integration.NestedQueries; import org.neo4j.driver.util.cc.ClusterExtension; -import static org.neo4j.driver.Logging.none; -import static org.neo4j.driver.SessionConfig.builder; - -public class CausalClusteringIT implements NestedQueries -{ +public class CausalClusteringIT implements NestedQueries { @RegisterExtension static final ClusterExtension clusterRule = new ClusterExtension(); private Driver driver; @Override - public Session newSession( AccessMode mode ) - { - if ( driver == null ) - { - driver = createDriver( clusterRule.getCluster().getRoutingUri() ); + public Session newSession(AccessMode mode) { + if (driver == null) { + driver = createDriver(clusterRule.getCluster().getRoutingUri()); } - return driver.session( builder().withDefaultAccessMode( mode ).build() ); + return driver.session(builder().withDefaultAccessMode(mode).build()); } @AfterEach - void tearDown() - { - if ( driver != null ) - { + void tearDown() { + if (driver != null) { driver.close(); } } - private Driver createDriver( URI boltUri ) - { - return createDriver( boltUri, configWithoutLogging() ); + private Driver createDriver(URI boltUri) { + return createDriver(boltUri, configWithoutLogging()); } - private Driver createDriver( URI boltUri, Config config ) - { - return GraphDatabase.driver( boltUri, clusterRule.getDefaultAuthToken(), config ); + private Driver createDriver(URI boltUri, Config config) { + return GraphDatabase.driver(boltUri, clusterRule.getDefaultAuthToken(), config); } - private static Config configWithoutLogging() - { - return Config.builder().withLogging( none() ).build(); + private static Config configWithoutLogging() { + return Config.builder().withLogging(none()).build(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringStressIT.java b/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringStressIT.java index 133fb67271..87c04d11d6 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringStressIT.java +++ b/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringStressIT.java @@ -18,55 +18,45 @@ */ package org.neo4j.driver.stress; -import org.junit.jupiter.api.extension.RegisterExtension; - import java.net.URI; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; - +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.AuthToken; import org.neo4j.driver.Config; import org.neo4j.driver.exceptions.SessionExpiredException; import org.neo4j.driver.util.cc.LocalOrRemoteClusterExtension; -class CausalClusteringStressIT extends AbstractStressTestBase -{ +class CausalClusteringStressIT extends AbstractStressTestBase { @RegisterExtension static final LocalOrRemoteClusterExtension clusterRule = new LocalOrRemoteClusterExtension(); @Override - URI databaseUri() - { + URI databaseUri() { return clusterRule.getClusterUri(); } @Override - AuthToken authToken() - { + AuthToken authToken() { return clusterRule.getAuthToken(); } @Override - Config.ConfigBuilder config( Config.ConfigBuilder builder ) - { + Config.ConfigBuilder config(Config.ConfigBuilder builder) { return builder; } @Override - Context createContext() - { + Context createContext() { return new Context(); } @Override - boolean handleWriteFailure( Throwable error, Context context ) - { - if ( error instanceof SessionExpiredException ) - { - boolean isLeaderSwitch = error.getMessage().endsWith( "no longer accepts writes" ); - if ( isLeaderSwitch ) - { + boolean handleWriteFailure(Throwable error, Context context) { + if (error instanceof SessionExpiredException) { + boolean isLeaderSwitch = error.getMessage().endsWith("no longer accepts writes"); + if (isLeaderSwitch) { context.leaderSwitch(); return true; } @@ -75,42 +65,35 @@ boolean handleWriteFailure( Throwable error, Context context ) } @Override - void printStats( Context context ) - { - System.out.println( "Nodes read: " + context.getReadNodesCount() ); - System.out.println( "Nodes created: " + context.getCreatedNodesCount() ); + void printStats(Context context) { + System.out.println("Nodes read: " + context.getReadNodesCount()); + System.out.println("Nodes created: " + context.getCreatedNodesCount()); - System.out.println( "Leader switches: " + context.getLeaderSwitchCount() ); - System.out.println( "Bookmark failures: " + context.getBookmarkFailures() ); + System.out.println("Leader switches: " + context.getLeaderSwitchCount()); + System.out.println("Bookmark failures: " + context.getBookmarkFailures()); } @Override - void dumpLogs() - { + void dumpLogs() { clusterRule.dumpClusterLogs(); } @Override - List> createTestSpecificBlockingCommands() - { + List> createTestSpecificBlockingCommands() { return Arrays.asList( - new BlockingWriteQueryUsingReadSessionWithRetries<>( driver, false ), - new BlockingWriteQueryUsingReadSessionWithRetries<>( driver, true ) ); + new BlockingWriteQueryUsingReadSessionWithRetries<>(driver, false), + new BlockingWriteQueryUsingReadSessionWithRetries<>(driver, true)); } - static class Context extends AbstractContext - { + static class Context extends AbstractContext { final AtomicInteger leaderSwitches = new AtomicInteger(); - void leaderSwitch() - { + void leaderSwitch() { leaderSwitches.incrementAndGet(); } - int getLeaderSwitchCount() - { + int getLeaderSwitchCount() { return leaderSwitches.get(); } } - } diff --git a/driver/src/test/java/org/neo4j/driver/stress/DumpLogsOnFailureWatcher.java b/driver/src/test/java/org/neo4j/driver/stress/DumpLogsOnFailureWatcher.java index 949c018927..03b0ff7e13 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/DumpLogsOnFailureWatcher.java +++ b/driver/src/test/java/org/neo4j/driver/stress/DumpLogsOnFailureWatcher.java @@ -18,37 +18,32 @@ */ package org.neo4j.driver.stress; +import java.util.Optional; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.TestWatcher; -import java.util.Optional; - -public class DumpLogsOnFailureWatcher implements TestWatcher -{ +public class DumpLogsOnFailureWatcher implements TestWatcher { @Override - public void testDisabled( ExtensionContext context, Optional reason ) - { + public void testDisabled(ExtensionContext context, Optional reason) { // do nothing } @Override - public void testSuccessful( ExtensionContext context ) - { + public void testSuccessful(ExtensionContext context) { // do nothing } @Override - public void testAborted( ExtensionContext context, Throwable cause ) - { + public void testAborted(ExtensionContext context, Throwable cause) { // do nothing } @Override - public void testFailed( ExtensionContext context, Throwable cause ) - { - if ( context.getTestInstance().isPresent() && context.getTestInstance().get() instanceof AbstractStressTestBase) - { - AbstractStressTestBase clusterTest = (AbstractStressTestBase) context.getTestInstance().get(); + public void testFailed(ExtensionContext context, Throwable cause) { + if (context.getTestInstance().isPresent() + && context.getTestInstance().get() instanceof AbstractStressTestBase) { + AbstractStressTestBase clusterTest = + (AbstractStressTestBase) context.getTestInstance().get(); clusterTest.dumpLogs(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/FailedAuth.java b/driver/src/test/java/org/neo4j/driver/stress/FailedAuth.java index 67138792fd..94fce2cfb0 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/FailedAuth.java +++ b/driver/src/test/java/org/neo4j/driver/stress/FailedAuth.java @@ -18,35 +18,31 @@ */ package org.neo4j.driver.stress; -import java.net.URI; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.neo4j.driver.AuthTokens.basic; +import java.net.URI; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.exceptions.SecurityException; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.neo4j.driver.AuthTokens.basic; - -public class FailedAuth implements BlockingCommand -{ +public class FailedAuth implements BlockingCommand { private final URI clusterUri; private final Config config; - public FailedAuth( URI clusterUri, Config config ) - { + public FailedAuth(URI clusterUri, Config config) { this.clusterUri = clusterUri; this.config = config; } @Override - public void execute( C context ) - { - final Driver driver = GraphDatabase.driver( clusterUri, basic( "wrongUsername", "wrongPassword" ), config ); - SecurityException e = assertThrows( SecurityException.class, driver::verifyConnectivity ); - assertThat( e.getMessage(), containsString( "authentication failure" ) ); + public void execute(C context) { + final Driver driver = GraphDatabase.driver(clusterUri, basic("wrongUsername", "wrongPassword"), config); + SecurityException e = assertThrows(SecurityException.class, driver::verifyConnectivity); + assertThat(e.getMessage(), containsString("authentication failure")); driver.close(); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxCommand.java b/driver/src/test/java/org/neo4j/driver/stress/RxCommand.java index f620d017cf..470ed40aad 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxCommand.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxCommand.java @@ -20,7 +20,6 @@ import java.util.concurrent.CompletionStage; -public interface RxCommand -{ - CompletionStage execute( C context ); +public interface RxCommand { + CompletionStage execute(C context); } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxFailingQuery.java b/driver/src/test/java/org/neo4j/driver/stress/RxFailingQuery.java index 66452c99cd..a5031347a0 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxFailingQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxFailingQuery.java @@ -18,45 +18,43 @@ */ package org.neo4j.driver.stress; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; +import static org.hamcrest.Matchers.either; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.neo4j.driver.internal.util.Matchers.arithmeticError; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; -import java.util.concurrent.atomic.AtomicInteger; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxSession; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -import static org.hamcrest.Matchers.either; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.neo4j.driver.internal.util.Matchers.arithmeticError; - -public class RxFailingQuery extends AbstractRxQuery -{ - public RxFailingQuery( Driver driver ) - { - super( driver, false ); +public class RxFailingQuery extends AbstractRxQuery { + public RxFailingQuery(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); - Flux.usingWhen( Mono.fromSupplier( () -> newSession( AccessMode.READ, context ) ), - session -> session.run( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ).records(), - RxSession::close ) - .subscribe( record -> { - assertThat( record.get( 0 ).asInt(), either( equalTo( 1 ) ).or( equalTo( 2 ) ) ); - }, error -> { - Throwable cause = Futures.completionExceptionCause( error ); - assertThat( cause, is( arithmeticError() ) ); - queryFinished.complete( null ); - }); + Flux.usingWhen( + Mono.fromSupplier(() -> newSession(AccessMode.READ, context)), + session -> session.run("UNWIND [10, 5, 0] AS x RETURN 10 / x") + .records(), + RxSession::close) + .subscribe( + record -> { + assertThat(record.get(0).asInt(), either(equalTo(1)).or(equalTo(2))); + }, + error -> { + Throwable cause = Futures.completionExceptionCause(error); + assertThat(cause, is(arithmeticError())); + queryFinished.complete(null); + }); return queryFinished; } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxFailingQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/RxFailingQueryInTx.java index 60e02507e0..9864390edd 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxFailingQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxFailingQueryInTx.java @@ -18,45 +18,45 @@ */ package org.neo4j.driver.stress; -import reactor.core.publisher.Flux; +import static org.hamcrest.Matchers.either; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.neo4j.driver.internal.util.Matchers.arithmeticError; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.reactive.RxTransaction; +import reactor.core.publisher.Flux; -import static org.hamcrest.Matchers.either; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.neo4j.driver.internal.util.Matchers.arithmeticError; - -public class RxFailingQueryInTx extends AbstractRxQuery -{ - public RxFailingQueryInTx( Driver driver ) - { - super( driver, false ); +public class RxFailingQueryInTx extends AbstractRxQuery { + public RxFailingQueryInTx(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); - RxSession session = newSession( AccessMode.READ, context ); - Flux.usingWhen( session.beginTransaction(), - tx -> tx.run( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ).records(), - RxTransaction::commit, ( tx, error ) -> tx.rollback(), null ) - .subscribe( record -> { - assertThat( record.get( 0 ).asInt(), either( equalTo( 1 ) ).or( equalTo( 2 ) ) ); - }, error -> { - Throwable cause = Futures.completionExceptionCause( error ); - assertThat( cause, is( arithmeticError() ) ); - queryFinished.complete( null ); - }); + RxSession session = newSession(AccessMode.READ, context); + Flux.usingWhen( + session.beginTransaction(), + tx -> tx.run("UNWIND [10, 5, 0] AS x RETURN 10 / x").records(), + RxTransaction::commit, + (tx, error) -> tx.rollback(), + null) + .subscribe( + record -> { + assertThat(record.get(0).asInt(), either(equalTo(1)).or(equalTo(2))); + }, + error -> { + Throwable cause = Futures.completionExceptionCause(error); + assertThat(cause, is(arithmeticError())); + queryFinished.complete(null); + }); return queryFinished; } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxFailingQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/RxFailingQueryWithRetries.java index 491e359ddc..8828104f66 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxFailingQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxFailingQueryWithRetries.java @@ -18,44 +18,43 @@ */ package org.neo4j.driver.stress; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; +import static org.hamcrest.Matchers.either; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.neo4j.driver.internal.util.Matchers.arithmeticError; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxSession; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -import static org.hamcrest.Matchers.either; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.neo4j.driver.internal.util.Matchers.arithmeticError; - -public class RxFailingQueryWithRetries extends AbstractRxQuery -{ - public RxFailingQueryWithRetries( Driver driver ) - { - super( driver, false ); +public class RxFailingQueryWithRetries extends AbstractRxQuery { + public RxFailingQueryWithRetries(Driver driver) { + super(driver, false); } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); - Flux.usingWhen( Mono.fromSupplier( () -> newSession( AccessMode.READ, context ) ), - session -> session.readTransaction( tx -> tx.run( "UNWIND [10, 5, 0] AS x RETURN 10 / x" ).records() ), - RxSession::close ) - .subscribe( record -> { - assertThat( record.get( 0 ).asInt(), either( equalTo( 1 ) ).or( equalTo( 2 ) ) ); - }, error -> { - Throwable cause = Futures.completionExceptionCause( error ); - assertThat( cause, is( arithmeticError() ) ); - queryFinished.complete( null ); - }); + Flux.usingWhen( + Mono.fromSupplier(() -> newSession(AccessMode.READ, context)), + session -> session.readTransaction(tx -> + tx.run("UNWIND [10, 5, 0] AS x RETURN 10 / x").records()), + RxSession::close) + .subscribe( + record -> { + assertThat(record.get(0).asInt(), either(equalTo(1)).or(equalTo(2))); + }, + error -> { + Throwable cause = Futures.completionExceptionCause(error); + assertThat(cause, is(arithmeticError())); + queryFinished.complete(null); + }); return queryFinished; } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxReadQuery.java b/driver/src/test/java/org/neo4j/driver/stress/RxReadQuery.java index bda07bafdc..fa26ac19c1 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxReadQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxReadQuery.java @@ -18,47 +18,47 @@ */ package org.neo4j.driver.stress; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.types.Node; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -public class RxReadQuery extends AbstractRxQuery -{ - public RxReadQuery( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class RxReadQuery extends AbstractRxQuery { + public RxReadQuery(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); - Flux.usingWhen( Mono.fromSupplier( () -> newSession( AccessMode.READ, context ) ), this::processAndGetSummary, RxSession::close ) - .subscribe( summary -> { - context.readCompleted( summary ); - queryFinished.complete( null ); - }, error -> { - // ignores the error - queryFinished.complete( null ); - } ); + Flux.usingWhen( + Mono.fromSupplier(() -> newSession(AccessMode.READ, context)), + this::processAndGetSummary, + RxSession::close) + .subscribe( + summary -> { + context.readCompleted(summary); + queryFinished.complete(null); + }, + error -> { + // ignores the error + queryFinished.complete(null); + }); return queryFinished; } - private Publisher processAndGetSummary( RxSession session ) - { - RxResult result = session.run( "MATCH (n) RETURN n LIMIT 1" ); - Mono records = Flux.from( result.records() ).singleOrEmpty().map( record -> record.get( 0 ).asNode() ); - Mono summaryMono = Mono.from( result.consume() ).single(); - return records.then( summaryMono ); + private Publisher processAndGetSummary(RxSession session) { + RxResult result = session.run("MATCH (n) RETURN n LIMIT 1"); + Mono records = Flux.from(result.records()).singleOrEmpty().map(record -> record.get(0) + .asNode()); + Mono summaryMono = Mono.from(result.consume()).single(); + return records.then(summaryMono); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxReadQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/RxReadQueryInTx.java index a0e25e991f..7d7f167b87 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxReadQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxReadQueryInTx.java @@ -18,13 +18,8 @@ */ package org.neo4j.driver.stress; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.reactive.RxResult; @@ -32,36 +27,42 @@ import org.neo4j.driver.reactive.RxTransaction; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.types.Node; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -public class RxReadQueryInTx extends AbstractRxQuery -{ - public RxReadQueryInTx( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class RxReadQueryInTx extends AbstractRxQuery { + public RxReadQueryInTx(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); - RxSession session = newSession( AccessMode.READ, context ); - Flux.usingWhen( session.beginTransaction(), this::processAndGetSummary, - RxTransaction::commit, ( tx, error ) -> tx.rollback(), null ) - .subscribe( summary -> { - context.readCompleted( summary ); - queryFinished.complete( null ); - }, error -> { - // ignores the error - queryFinished.complete( null ); - } ); + RxSession session = newSession(AccessMode.READ, context); + Flux.usingWhen( + session.beginTransaction(), + this::processAndGetSummary, + RxTransaction::commit, + (tx, error) -> tx.rollback(), + null) + .subscribe( + summary -> { + context.readCompleted(summary); + queryFinished.complete(null); + }, + error -> { + // ignores the error + queryFinished.complete(null); + }); return queryFinished; } - private Publisher processAndGetSummary( RxTransaction tx ) - { - RxResult result = tx.run( "MATCH (n) RETURN n LIMIT 1" ); - Mono records = Flux.from( result.records() ).singleOrEmpty().map( record -> record.get( 0 ).asNode() ); - Mono summaryMono = Mono.from( result.consume() ).single(); - return records.then( summaryMono ); + private Publisher processAndGetSummary(RxTransaction tx) { + RxResult result = tx.run("MATCH (n) RETURN n LIMIT 1"); + Mono records = Flux.from(result.records()).singleOrEmpty().map(record -> record.get(0) + .asNode()); + Mono summaryMono = Mono.from(result.consume()).single(); + return records.then(summaryMono); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxReadQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/RxReadQueryWithRetries.java index ca45537476..6030096387 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxReadQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxReadQueryWithRetries.java @@ -18,49 +18,49 @@ */ package org.neo4j.driver.stress; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.types.Node; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -public class RxReadQueryWithRetries extends AbstractRxQuery -{ - public RxReadQueryWithRetries( Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); +public class RxReadQueryWithRetries extends AbstractRxQuery { + public RxReadQueryWithRetries(Driver driver, boolean useBookmark) { + super(driver, useBookmark); } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); - Flux.usingWhen( Mono.fromSupplier( () -> newSession( AccessMode.READ, context ) ), this::processAndGetSummary, RxSession::close ) - .subscribe( summary -> { - queryFinished.complete( null ); - context.readCompleted( summary ); - }, error -> { - // ignores the error - queryFinished.complete( null ); - } ); + Flux.usingWhen( + Mono.fromSupplier(() -> newSession(AccessMode.READ, context)), + this::processAndGetSummary, + RxSession::close) + .subscribe( + summary -> { + queryFinished.complete(null); + context.readCompleted(summary); + }, + error -> { + // ignores the error + queryFinished.complete(null); + }); return queryFinished; } - private Publisher processAndGetSummary( RxSession session ) - { - return session.readTransaction( tx -> { - RxResult result = tx.run( "MATCH (n) RETURN n LIMIT 1" ); - Mono records = Flux.from( result.records() ).singleOrEmpty().map( record -> record.get( 0 ).asNode() ); - Mono summaryMono = Mono.from( result.consume() ).single(); - return records.then( summaryMono ); - } ); + private Publisher processAndGetSummary(RxSession session) { + return session.readTransaction(tx -> { + RxResult result = tx.run("MATCH (n) RETURN n LIMIT 1"); + Mono records = Flux.from(result.records()).singleOrEmpty().map(record -> record.get(0) + .asNode()); + Mono summaryMono = Mono.from(result.consume()).single(); + return records.then(summaryMono); + }); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxWriteQuery.java b/driver/src/test/java/org/neo4j/driver/stress/RxWriteQuery.java index ac85327b4c..d618287a03 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxWriteQuery.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxWriteQuery.java @@ -18,56 +18,49 @@ */ package org.neo4j.driver.stress; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxSession; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -public class RxWriteQuery extends AbstractRxQuery -{ +public class RxWriteQuery extends AbstractRxQuery { private AbstractStressTestBase stressTest; - public RxWriteQuery( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public RxWriteQuery(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); - Flux.usingWhen( Mono.fromSupplier( () -> newSession( AccessMode.WRITE, context ) ), - session -> Flux.from( session.run( "CREATE ()" ).consume() ) - .doOnComplete( () -> context.setBookmark( session.lastBookmark() ) ), - RxSession::close ) - .subscribe( summary -> { - assertEquals( 1, summary.counters().nodesCreated() ); - context.nodeCreated(); - queryFinished.complete( null ); - }, error -> handleError( Futures.completionExceptionCause( error ), context, queryFinished ) ); + Flux.usingWhen( + Mono.fromSupplier(() -> newSession(AccessMode.WRITE, context)), + session -> Flux.from(session.run("CREATE ()").consume()) + .doOnComplete(() -> context.setBookmark(session.lastBookmark())), + RxSession::close) + .subscribe( + summary -> { + assertEquals(1, summary.counters().nodesCreated()); + context.nodeCreated(); + queryFinished.complete(null); + }, + error -> handleError(Futures.completionExceptionCause(error), context, queryFinished)); return queryFinished; } - private void handleError( Throwable error, C context, CompletableFuture queryFinished ) - { - if ( !stressTest.handleWriteFailure( error, context ) ) - { - queryFinished.completeExceptionally( error ); - } - else - { - queryFinished.complete( null ); + private void handleError(Throwable error, C context, CompletableFuture queryFinished) { + if (!stressTest.handleWriteFailure(error, context)) { + queryFinished.completeExceptionally(error); + } else { + queryFinished.complete(null); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxWriteQueryInTx.java b/driver/src/test/java/org/neo4j/driver/stress/RxWriteQueryInTx.java index dc60dc345c..2535ad10ed 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxWriteQueryInTx.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxWriteQueryInTx.java @@ -18,76 +18,66 @@ */ package org.neo4j.driver.stress; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; - import org.neo4j.driver.Driver; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.reactive.RxTransaction; import org.neo4j.driver.summary.ResultSummary; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class RxWriteQueryInTx extends AbstractRxQuery -{ +public class RxWriteQueryInTx extends AbstractRxQuery { private AbstractStressTestBase stressTest; - public RxWriteQueryInTx( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public RxWriteQueryInTx(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); - Function> sessionToResultSummaryPublisher = ( RxSession session ) -> Flux.usingWhen( - Mono.from( session.beginTransaction() ), - tx -> tx.run( "CREATE ()" ).consume(), - RxTransaction::commit, - ( tx, error ) -> tx.rollback(), - RxTransaction::rollback - ); + Function> sessionToResultSummaryPublisher = + (RxSession session) -> Flux.usingWhen( + Mono.from(session.beginTransaction()), + tx -> tx.run("CREATE ()").consume(), + RxTransaction::commit, + (tx, error) -> tx.rollback(), + RxTransaction::rollback); AtomicInteger createdNodesNum = new AtomicInteger(); Flux.usingWhen( - Mono.fromSupplier( driver::rxSession ), - sessionToResultSummaryPublisher, - session -> Mono.empty(), - ( session, error ) -> session.close(), - RxSession::close - ).subscribe( - resultSummary -> createdNodesNum.addAndGet( resultSummary.counters().nodesCreated() ), - error -> handleError( Futures.completionExceptionCause( error ), context, queryFinished ), - () -> - { - assertEquals( 1, createdNodesNum.get() ); - context.nodeCreated(); - queryFinished.complete( null ); - } - ); + Mono.fromSupplier(driver::rxSession), + sessionToResultSummaryPublisher, + session -> Mono.empty(), + (session, error) -> session.close(), + RxSession::close) + .subscribe( + resultSummary -> createdNodesNum.addAndGet( + resultSummary.counters().nodesCreated()), + error -> handleError(Futures.completionExceptionCause(error), context, queryFinished), + () -> { + assertEquals(1, createdNodesNum.get()); + context.nodeCreated(); + queryFinished.complete(null); + }); return queryFinished; } - private void handleError( Throwable error, C context, CompletableFuture queryFinished ) - { - if ( !stressTest.handleWriteFailure( error, context ) ) - { - queryFinished.completeExceptionally( error ); - } - else - { - queryFinished.complete( null ); + private void handleError(Throwable error, C context, CompletableFuture queryFinished) { + if (!stressTest.handleWriteFailure(error, context)) { + queryFinished.completeExceptionally(error); + } else { + queryFinished.complete(null); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/RxWriteQueryWithRetries.java b/driver/src/test/java/org/neo4j/driver/stress/RxWriteQueryWithRetries.java index 2187a677e3..3dc4d9bf04 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/RxWriteQueryWithRetries.java +++ b/driver/src/test/java/org/neo4j/driver/stress/RxWriteQueryWithRetries.java @@ -18,58 +18,52 @@ */ package org.neo4j.driver.stress; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicInteger; - import org.neo4j.driver.Driver; import org.neo4j.driver.internal.util.Futures; import org.neo4j.driver.reactive.RxSession; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class RxWriteQueryWithRetries extends AbstractRxQuery -{ +public class RxWriteQueryWithRetries extends AbstractRxQuery { private AbstractStressTestBase stressTest; - public RxWriteQueryWithRetries( AbstractStressTestBase stressTest, Driver driver, boolean useBookmark ) - { - super( driver, useBookmark ); + public RxWriteQueryWithRetries(AbstractStressTestBase stressTest, Driver driver, boolean useBookmark) { + super(driver, useBookmark); this.stressTest = stressTest; } @Override - public CompletionStage execute( C context ) - { + public CompletionStage execute(C context) { CompletableFuture queryFinished = new CompletableFuture<>(); AtomicInteger createdNodesNum = new AtomicInteger(); Flux.usingWhen( - Mono.fromSupplier( driver::rxSession ), - session -> session.writeTransaction( tx -> tx.run( "CREATE ()" ).consume() ), - session -> Mono.empty(), - ( session, error ) -> session.close(), - RxSession::close - ).subscribe( - resultSummary -> createdNodesNum.addAndGet( resultSummary.counters().nodesCreated() ), - error -> handleError( Futures.completionExceptionCause( error ), context, queryFinished ), - () -> - { - assertEquals( 1, createdNodesNum.get() ); - context.nodeCreated(); - queryFinished.complete( null ); - } - ); + Mono.fromSupplier(driver::rxSession), + session -> session.writeTransaction( + tx -> tx.run("CREATE ()").consume()), + session -> Mono.empty(), + (session, error) -> session.close(), + RxSession::close) + .subscribe( + resultSummary -> createdNodesNum.addAndGet( + resultSummary.counters().nodesCreated()), + error -> handleError(Futures.completionExceptionCause(error), context, queryFinished), + () -> { + assertEquals(1, createdNodesNum.get()); + context.nodeCreated(); + queryFinished.complete(null); + }); return queryFinished; } - private void handleError( Throwable error, C context, CompletableFuture queryFinished ) - { - stressTest.handleWriteFailure( error, context ); - queryFinished.completeExceptionally( error ); + private void handleError(Throwable error, C context, CompletableFuture queryFinished) { + stressTest.handleWriteFailure(error, context); + queryFinished.completeExceptionally(error); } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/SessionPoolingStressIT.java b/driver/src/test/java/org/neo4j/driver/stress/SessionPoolingStressIT.java index fd6a50ecc4..fe2efff7fe 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/SessionPoolingStressIT.java +++ b/driver/src/test/java/org/neo4j/driver/stress/SessionPoolingStressIT.java @@ -18,10 +18,10 @@ */ package org.neo4j.driver.stress; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.GraphDatabase.driver; +import static org.neo4j.driver.util.DaemonThreadFactory.daemon; import java.util.List; import java.util.Random; @@ -31,137 +31,112 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; -import static java.util.Arrays.asList; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.GraphDatabase.driver; -import static org.neo4j.driver.util.DaemonThreadFactory.daemon; - @ParallelizableIT -class SessionPoolingStressIT -{ +class SessionPoolingStressIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private static final int N_THREADS = 50; private static final int TEST_TIME = 10000; - private static final List QUERIES = asList( - "RETURN 1295 + 42", "UNWIND range(1,10000) AS x CREATE (n {prop:x}) DELETE n " ); + private static final List QUERIES = + asList("RETURN 1295 + 42", "UNWIND range(1,10000) AS x CREATE (n {prop:x}) DELETE n "); private Driver driver; private ExecutorService executor; @BeforeEach - void setUp() - { - executor = Executors.newFixedThreadPool( N_THREADS, daemon( getClass().getSimpleName() + "-thread-" ) ); + void setUp() { + executor = Executors.newFixedThreadPool(N_THREADS, daemon(getClass().getSimpleName() + "-thread-")); } @AfterEach - void tearDown() - { - if ( executor != null ) - { + void tearDown() { + if (executor != null) { executor.shutdownNow(); } - if ( driver != null ) - { + if (driver != null) { driver.close(); } } @Test - void shouldWorkFine() throws Throwable - { - Config config = Config.builder() - .withoutEncryption() - .build(); + void shouldWorkFine() throws Throwable { + Config config = Config.builder().withoutEncryption().build(); - driver = driver( neo4j.uri(), neo4j.authToken(), config ); + driver = driver(neo4j.uri(), neo4j.authToken(), config); AtomicBoolean stop = new AtomicBoolean(); AtomicReference failureReference = new AtomicReference<>(); - doWork( stop, failureReference ); + doWork(stop, failureReference); - Thread.sleep( TEST_TIME ); + Thread.sleep(TEST_TIME); - stop.set( true ); + stop.set(true); executor.shutdown(); - assertTrue( executor.awaitTermination( 90, TimeUnit.SECONDS ) ); + assertTrue(executor.awaitTermination(90, TimeUnit.SECONDS)); Throwable failure = failureReference.get(); - if ( failure != null ) - { - throw new AssertionError( "Some workers have failed", failure ); + if (failure != null) { + throw new AssertionError("Some workers have failed", failure); } } - private void doWork( AtomicBoolean stop, AtomicReference failure ) - { - for ( int i = 0; i < N_THREADS; i++ ) - { - executor.execute( new Worker( driver, stop, failure ) ); + private void doWork(AtomicBoolean stop, AtomicReference failure) { + for (int i = 0; i < N_THREADS; i++) { + executor.execute(new Worker(driver, stop, failure)); } } - private class Worker implements Runnable - { + private class Worker implements Runnable { private final Random random = ThreadLocalRandom.current(); private final Driver driver; private final AtomicBoolean stop; private final AtomicReference failureReference; - Worker( Driver driver, AtomicBoolean stop, AtomicReference failureReference ) - { + Worker(Driver driver, AtomicBoolean stop, AtomicReference failureReference) { this.driver = driver; this.stop = stop; this.failureReference = failureReference; } @Override - public void run() - { - try - { - while ( !stop.get() ) - { - for ( String query : QUERIES ) - { - runQuery( query ); + public void run() { + try { + while (!stop.get()) { + for (String query : QUERIES) { + runQuery(query); } } - } - catch ( Throwable failure ) - { - if ( !failureReference.compareAndSet( null, failure ) ) - { + } catch (Throwable failure) { + if (!failureReference.compareAndSet(null, failure)) { Throwable firstFailure = failureReference.get(); - synchronized ( firstFailure ) - { - firstFailure.addSuppressed( failure ); + synchronized (firstFailure) { + firstFailure.addSuppressed(failure); } } } } - private void runQuery( String query ) throws InterruptedException - { - try ( Session session = driver.session() ) - { - Result run = session.run( query ); - Thread.sleep( random.nextInt( 100 ) ); + private void runQuery(String query) throws InterruptedException { + try (Session session = driver.session()) { + Result run = session.run(query); + Thread.sleep(random.nextInt(100)); run.consume(); - Thread.sleep( random.nextInt( 100 ) ); + Thread.sleep(random.nextInt(100)); } } } diff --git a/driver/src/test/java/org/neo4j/driver/stress/SingleInstanceStressIT.java b/driver/src/test/java/org/neo4j/driver/stress/SingleInstanceStressIT.java index 9c128467ab..a6c0d33db7 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/SingleInstanceStressIT.java +++ b/driver/src/test/java/org/neo4j/driver/stress/SingleInstanceStressIT.java @@ -18,137 +18,107 @@ */ package org.neo4j.driver.stress; -import org.junit.jupiter.api.extension.RegisterExtension; - import java.net.URI; import java.util.Arrays; import java.util.List; - +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.AuthToken; import org.neo4j.driver.Config; import org.neo4j.driver.util.DatabaseExtension; import org.neo4j.driver.util.ParallelizableIT; @ParallelizableIT -class SingleInstanceStressIT extends AbstractStressTestBase -{ +class SingleInstanceStressIT extends AbstractStressTestBase { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); @Override - URI databaseUri() - { + URI databaseUri() { return neo4j.uri(); } @Override - AuthToken authToken() - { + AuthToken authToken() { return neo4j.authToken(); } @Override - Config.ConfigBuilder config( Config.ConfigBuilder builder ) - { + Config.ConfigBuilder config(Config.ConfigBuilder builder) { return builder.withoutEncryption(); } @Override - Context createContext() - { + Context createContext() { return new Context(); } @Override - boolean handleWriteFailure( Throwable error, Context context ) - { + boolean handleWriteFailure(Throwable error, Context context) { // no write failures expected return false; } @Override - void printStats( A context ) - { - System.out.println( "Nodes read: " + context.getReadNodesCount() ); - System.out.println( "Nodes created: " + context.getCreatedNodesCount() ); + void printStats(A context) { + System.out.println("Nodes read: " + context.getReadNodesCount()); + System.out.println("Nodes created: " + context.getCreatedNodesCount()); - System.out.println( "Bookmark failures: " + context.getBookmarkFailures() ); + System.out.println("Bookmark failures: " + context.getBookmarkFailures()); } @Override - List> createTestSpecificBlockingCommands() - { + List> createTestSpecificBlockingCommands() { return Arrays.asList( - new BlockingReadQuery<>( driver, false ), - new BlockingReadQuery<>( driver, true ), - - new BlockingReadQueryInTx<>( driver, false ), - new BlockingReadQueryInTx<>( driver, true ), - - new BlockingWriteQuery<>( this, driver, false ), - new BlockingWriteQuery<>( this, driver, true ), - - new BlockingWriteQueryInTx<>( this, driver, false ), - new BlockingWriteQueryInTx<>( this, driver, true ), - - new BlockingWrongQuery<>( driver ), - new BlockingWrongQueryInTx<>( driver ), - - new BlockingFailingQuery<>( driver ), - new BlockingFailingQueryInTx<>( driver ) ); + new BlockingReadQuery<>(driver, false), + new BlockingReadQuery<>(driver, true), + new BlockingReadQueryInTx<>(driver, false), + new BlockingReadQueryInTx<>(driver, true), + new BlockingWriteQuery<>(this, driver, false), + new BlockingWriteQuery<>(this, driver, true), + new BlockingWriteQueryInTx<>(this, driver, false), + new BlockingWriteQueryInTx<>(this, driver, true), + new BlockingWrongQuery<>(driver), + new BlockingWrongQueryInTx<>(driver), + new BlockingFailingQuery<>(driver), + new BlockingFailingQueryInTx<>(driver)); } @Override - List> createTestSpecificAsyncCommands() - { + List> createTestSpecificAsyncCommands() { return Arrays.asList( - new AsyncReadQuery<>( driver, false ), - new AsyncReadQuery<>( driver, true ), - - new AsyncReadQueryInTx<>( driver, false ), - new AsyncReadQueryInTx<>( driver, true ), - - new AsyncWriteQuery<>( this, driver, false ), - new AsyncWriteQuery<>( this, driver, true ), - - new AsyncWriteQueryInTx<>( this, driver, false ), - new AsyncWriteQueryInTx<>( this, driver, true ), - - new AsyncWrongQuery<>( driver ), - new AsyncWrongQueryInTx<>( driver ), - - new AsyncFailingQuery<>( driver ), - new AsyncFailingQueryInTx<>( driver ) ); + new AsyncReadQuery<>(driver, false), + new AsyncReadQuery<>(driver, true), + new AsyncReadQueryInTx<>(driver, false), + new AsyncReadQueryInTx<>(driver, true), + new AsyncWriteQuery<>(this, driver, false), + new AsyncWriteQuery<>(this, driver, true), + new AsyncWriteQueryInTx<>(this, driver, false), + new AsyncWriteQueryInTx<>(this, driver, true), + new AsyncWrongQuery<>(driver), + new AsyncWrongQueryInTx<>(driver), + new AsyncFailingQuery<>(driver), + new AsyncFailingQueryInTx<>(driver)); } @Override - List> createTestSpecificRxCommands() - { + List> createTestSpecificRxCommands() { return Arrays.asList( - new RxReadQuery<>( driver, false ), - new RxReadQuery<>( driver, true ), - - new RxWriteQuery<>( this, driver, false ), - new RxWriteQuery<>( this, driver, true ), - - new RxReadQueryInTx<>( driver, false ), - new RxReadQueryInTx<>( driver, true ), - - new RxWriteQueryInTx<>( this, driver, false ), - new RxWriteQueryInTx<>( this, driver, true ), - - new RxFailingQuery<>( driver ), - new RxFailingQueryInTx<>( driver ) - ); + new RxReadQuery<>(driver, false), + new RxReadQuery<>(driver, true), + new RxWriteQuery<>(this, driver, false), + new RxWriteQuery<>(this, driver, true), + new RxReadQueryInTx<>(driver, false), + new RxReadQueryInTx<>(driver, true), + new RxWriteQueryInTx<>(this, driver, false), + new RxWriteQueryInTx<>(this, driver, true), + new RxFailingQuery<>(driver), + new RxFailingQueryInTx<>(driver)); } - static class Context extends AbstractContext - { - } + static class Context extends AbstractContext {} @Override - void dumpLogs() - { + void dumpLogs() { neo4j.dumpLogs(); } } diff --git a/driver/src/test/java/org/neo4j/driver/types/TypeSystemTest.java b/driver/src/test/java/org/neo4j/driver/types/TypeSystemTest.java index 48c8e83486..62ebf8a4ac 100644 --- a/driver/src/test/java/org/neo4j/driver/types/TypeSystemTest.java +++ b/driver/src/test/java/org/neo4j/driver/types/TypeSystemTest.java @@ -18,16 +18,21 @@ */ package org.neo4j.driver.types; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.junit.jupiter.api.Test; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.neo4j.driver.Values.value; +import static org.neo4j.driver.internal.types.InternalTypeSystem.TYPE_SYSTEM; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; - +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Value; import org.neo4j.driver.internal.InternalNode; import org.neo4j.driver.internal.InternalPath; import org.neo4j.driver.internal.InternalRelationship; @@ -35,242 +40,197 @@ import org.neo4j.driver.internal.value.NodeValue; import org.neo4j.driver.internal.value.PathValue; import org.neo4j.driver.internal.value.RelationshipValue; -import org.neo4j.driver.Value; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.neo4j.driver.internal.types.InternalTypeSystem.TYPE_SYSTEM; -import static org.neo4j.driver.Values.value; - -class TypeSystemTest -{ - private final InternalNode node = new InternalNode( 42L ); - private final InternalRelationship relationship = new InternalRelationship( 42L, 42L, 43L, "T" ); - - private Value integerValue = value( 13 ); - private Value floatValue = value( 13.1 ); - private Value stringValue = value( "Lalala " ); - private Value nodeValue = new NodeValue( node ); - private Value relationshipValue = new RelationshipValue( relationship ); - private Value mapValue = value( Collections.singletonMap( "type", "r" ) ); - private Value pathValue = new PathValue( new InternalPath( Arrays.asList( node, relationship, node ) ) ); - private Value booleanValue = value( true ); - private Value listValue = value( Arrays.asList( 1, 2, 3 ) ); - private Value nullValue = value( (Object) null ); +class TypeSystemTest { + private final InternalNode node = new InternalNode(42L); + private final InternalRelationship relationship = new InternalRelationship(42L, 42L, 43L, "T"); + + private Value integerValue = value(13); + private Value floatValue = value(13.1); + private Value stringValue = value("Lalala "); + private Value nodeValue = new NodeValue(node); + private Value relationshipValue = new RelationshipValue(relationship); + private Value mapValue = value(Collections.singletonMap("type", "r")); + private Value pathValue = new PathValue(new InternalPath(Arrays.asList(node, relationship, node))); + private Value booleanValue = value(true); + private Value listValue = value(Arrays.asList(1, 2, 3)); + private Value nullValue = value((Object) null); private InternalTypeSystem typeSystem = TYPE_SYSTEM; - private TypeVerifier newTypeVerifierFor( Type type ) - { + private TypeVerifier newTypeVerifierFor(Type type) { HashSet allValues = new HashSet<>(); - allValues.add( integerValue ); - allValues.add( stringValue ); - allValues.add( floatValue ); - allValues.add( nodeValue ); - allValues.add( relationshipValue ); - allValues.add( mapValue ); - allValues.add( pathValue ); - allValues.add( booleanValue ); - allValues.add( nullValue ); - allValues.add( listValue ); - return new TypeVerifier( type, allValues ); + allValues.add(integerValue); + allValues.add(stringValue); + allValues.add(floatValue); + allValues.add(nodeValue); + allValues.add(relationshipValue); + allValues.add(mapValue); + allValues.add(pathValue); + allValues.add(booleanValue); + allValues.add(nullValue); + allValues.add(listValue); + return new TypeVerifier(type, allValues); } @Test - void shouldNameTypeCorrectly() - { - assertThat( TYPE_SYSTEM.ANY().name(), is( "ANY" ) ); - assertThat( TYPE_SYSTEM.BOOLEAN().name(), is( "BOOLEAN" ) ); - assertThat( TYPE_SYSTEM.STRING().name(), is( "STRING" ) ); - assertThat( TYPE_SYSTEM.NUMBER().name(), is( "NUMBER" ) ); - assertThat( TYPE_SYSTEM.INTEGER().name(), is( "INTEGER" ) ); - assertThat( TYPE_SYSTEM.FLOAT().name(), is( "FLOAT" ) ); - assertThat( TYPE_SYSTEM.LIST().name(), is( "LIST OF ANY?" ) ); - assertThat( TYPE_SYSTEM.MAP().name(), is( "MAP" ) ); - assertThat( TYPE_SYSTEM.NODE().name(), is( "NODE" ) ); - assertThat( TYPE_SYSTEM.RELATIONSHIP().name(), is( "RELATIONSHIP" ) ); - assertThat( TYPE_SYSTEM.PATH().name(), is( "PATH" ) ); - assertThat( TYPE_SYSTEM.NULL().name(), is( "NULL" ) ); + void shouldNameTypeCorrectly() { + assertThat(TYPE_SYSTEM.ANY().name(), is("ANY")); + assertThat(TYPE_SYSTEM.BOOLEAN().name(), is("BOOLEAN")); + assertThat(TYPE_SYSTEM.STRING().name(), is("STRING")); + assertThat(TYPE_SYSTEM.NUMBER().name(), is("NUMBER")); + assertThat(TYPE_SYSTEM.INTEGER().name(), is("INTEGER")); + assertThat(TYPE_SYSTEM.FLOAT().name(), is("FLOAT")); + assertThat(TYPE_SYSTEM.LIST().name(), is("LIST OF ANY?")); + assertThat(TYPE_SYSTEM.MAP().name(), is("MAP")); + assertThat(TYPE_SYSTEM.NODE().name(), is("NODE")); + assertThat(TYPE_SYSTEM.RELATIONSHIP().name(), is("RELATIONSHIP")); + assertThat(TYPE_SYSTEM.PATH().name(), is("PATH")); + assertThat(TYPE_SYSTEM.NULL().name(), is("NULL")); } @Test - void shouldInferAnyTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.ANY() ) ) - { - verifier.assertIncludes( booleanValue ); - verifier.assertIncludes( stringValue ); - verifier.assertIncludes( integerValue ); - verifier.assertIncludes( floatValue ); - verifier.assertIncludes( listValue ); - verifier.assertIncludes( mapValue ); - verifier.assertIncludes( nodeValue ); - verifier.assertIncludes( relationshipValue ); - verifier.assertIncludes( pathValue ); + void shouldInferAnyTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.ANY())) { + verifier.assertIncludes(booleanValue); + verifier.assertIncludes(stringValue); + verifier.assertIncludes(integerValue); + verifier.assertIncludes(floatValue); + verifier.assertIncludes(listValue); + verifier.assertIncludes(mapValue); + verifier.assertIncludes(nodeValue); + verifier.assertIncludes(relationshipValue); + verifier.assertIncludes(pathValue); } } @Test - void shouldInferNumberTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.NUMBER() ) ) - { - verifier.assertIncludes( integerValue ); - verifier.assertIncludes( floatValue ); + void shouldInferNumberTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.NUMBER())) { + verifier.assertIncludes(integerValue); + verifier.assertIncludes(floatValue); } } @Test - void shouldInferNodesTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.NODE() ) ) - { - verifier.assertIncludes( nodeValue ); + void shouldInferNodesTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.NODE())) { + verifier.assertIncludes(nodeValue); } } @Test - void shouldInferRelTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.RELATIONSHIP() ) ) - { - verifier.assertIncludes( relationshipValue ); + void shouldInferRelTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.RELATIONSHIP())) { + verifier.assertIncludes(relationshipValue); } } @Test - void shouldInferStringTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.STRING() ) ) - { - verifier.assertIncludes( stringValue ); + void shouldInferStringTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.STRING())) { + verifier.assertIncludes(stringValue); } } @Test - void shouldInferMapTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.MAP() ) ) - { - verifier.assertIncludes( nodeValue ); - verifier.assertIncludes( relationshipValue ); - verifier.assertIncludes( mapValue ); + void shouldInferMapTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.MAP())) { + verifier.assertIncludes(nodeValue); + verifier.assertIncludes(relationshipValue); + verifier.assertIncludes(mapValue); } } @Test - void shouldInferPathTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.PATH() ) ) - { - verifier.assertIncludes( pathValue ); + void shouldInferPathTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.PATH())) { + verifier.assertIncludes(pathValue); } } @Test - void shouldInferNullCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.NULL() ) ) - { - verifier.assertIncludes( nullValue ); + void shouldInferNullCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.NULL())) { + verifier.assertIncludes(nullValue); } } @Test - void shouldInferBooleanTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.BOOLEAN() ) ) - { - verifier.assertIncludes( booleanValue ); + void shouldInferBooleanTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.BOOLEAN())) { + verifier.assertIncludes(booleanValue); } } @Test - void shouldIntegerTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.INTEGER() ) ) - { - verifier.assertIncludes( integerValue ); + void shouldIntegerTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.INTEGER())) { + verifier.assertIncludes(integerValue); } } @Test - void shouldInferFloatTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( TYPE_SYSTEM.FLOAT() ) ) - { - verifier.assertIncludes( floatValue ); + void shouldInferFloatTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(TYPE_SYSTEM.FLOAT())) { + verifier.assertIncludes(floatValue); } } @Test - void shouldInferListTypeCorrectly() - { - try ( TypeVerifier verifier = newTypeVerifierFor( typeSystem.LIST() ) ) - { - verifier.assertIncludes( listValue ); + void shouldInferListTypeCorrectly() { + try (TypeVerifier verifier = newTypeVerifierFor(typeSystem.LIST())) { + verifier.assertIncludes(listValue); } } @Test - void shouldDetermineTypeCorrectly() - { - assertThat( integerValue, hasType( TYPE_SYSTEM.INTEGER() ) ); - assertThat( floatValue, hasType( TYPE_SYSTEM.FLOAT() ) ); - assertThat( stringValue, hasType( TYPE_SYSTEM.STRING() ) ); - assertThat( booleanValue, hasType( TYPE_SYSTEM.BOOLEAN() ) ); - assertThat( listValue, hasType( TYPE_SYSTEM.LIST() ) ); - assertThat( mapValue, hasType( TYPE_SYSTEM.MAP() ) ); - assertThat( nodeValue, hasType( TYPE_SYSTEM.NODE() ) ); - assertThat( relationshipValue, hasType( TYPE_SYSTEM.RELATIONSHIP() ) ); - assertThat( pathValue, hasType( TYPE_SYSTEM.PATH() ) ); - assertThat( nullValue, hasType( TYPE_SYSTEM.NULL() ) ); - } - - private class TypeVerifier implements AutoCloseable - { + void shouldDetermineTypeCorrectly() { + assertThat(integerValue, hasType(TYPE_SYSTEM.INTEGER())); + assertThat(floatValue, hasType(TYPE_SYSTEM.FLOAT())); + assertThat(stringValue, hasType(TYPE_SYSTEM.STRING())); + assertThat(booleanValue, hasType(TYPE_SYSTEM.BOOLEAN())); + assertThat(listValue, hasType(TYPE_SYSTEM.LIST())); + assertThat(mapValue, hasType(TYPE_SYSTEM.MAP())); + assertThat(nodeValue, hasType(TYPE_SYSTEM.NODE())); + assertThat(relationshipValue, hasType(TYPE_SYSTEM.RELATIONSHIP())); + assertThat(pathValue, hasType(TYPE_SYSTEM.PATH())); + assertThat(nullValue, hasType(TYPE_SYSTEM.NULL())); + } + + private class TypeVerifier implements AutoCloseable { private final Type type; private final Set values; - TypeVerifier( Type type, Set values ) - { + TypeVerifier(Type type, Set values) { this.type = type; this.values = values; } - void assertIncludes( Value value ) - { - assertThat( value, hasType( type ) ); - values.remove( value ); + void assertIncludes(Value value) { + assertThat(value, hasType(type)); + values.remove(value); } @Override - public void close() - { - for ( Value value : values ) - { - assertThat( value, not( hasType( type )) ); + public void close() { + for (Value value : values) { + assertThat(value, not(hasType(type))); } } } - private Matcher hasType( final Type type ) - { - return new BaseMatcher() - { + private Matcher hasType(final Type type) { + return new BaseMatcher() { @Override - public boolean matches( Object o ) - { - return (o instanceof Value || o == null) && type.isTypeOf( (Value) o ); + public boolean matches(Object o) { + return (o instanceof Value || o == null) && type.isTypeOf((Value) o); } @Override - public void describeTo( Description description ) - { - description.appendText( type.name() ); + public void describeTo(Description description) { + description.appendText(type.name()); } }; } - } diff --git a/driver/src/test/java/org/neo4j/driver/util/CertificateExtension.java b/driver/src/test/java/org/neo4j/driver/util/CertificateExtension.java index a5d3caa063..c654729d37 100644 --- a/driver/src/test/java/org/neo4j/driver/util/CertificateExtension.java +++ b/driver/src/test/java/org/neo4j/driver/util/CertificateExtension.java @@ -18,51 +18,46 @@ */ package org.neo4j.driver.util; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; +import static org.neo4j.driver.util.Neo4jRunner.debug; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.Arrays; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; -import static org.neo4j.driver.util.Neo4jRunner.debug; - -public class CertificateExtension extends DatabaseExtension implements AfterEachCallback -{ +public class CertificateExtension extends DatabaseExtension implements AfterEachCallback { private Path originalKeyFile; private Path originalCertFile; @Override - public void beforeEach( ExtensionContext context ) throws Exception - { - super.beforeEach( context ); + public void beforeEach(ExtensionContext context) throws Exception { + super.beforeEach(context); - originalKeyFile = Files.createTempFile( "key-file-", "" ); - originalCertFile = Files.createTempFile( "cert-file-", "" ); + originalKeyFile = Files.createTempFile("key-file-", ""); + originalCertFile = Files.createTempFile("cert-file-", ""); - Files.copy( tlsKeyFile().toPath(), originalKeyFile, StandardCopyOption.REPLACE_EXISTING ); - Files.copy( tlsCertFile().toPath(), originalCertFile, StandardCopyOption.REPLACE_EXISTING ); + Files.copy(tlsKeyFile().toPath(), originalKeyFile, StandardCopyOption.REPLACE_EXISTING); + Files.copy(tlsCertFile().toPath(), originalCertFile, StandardCopyOption.REPLACE_EXISTING); } @Override - public void afterEach( ExtensionContext context ) throws Exception - { + public void afterEach(ExtensionContext context) throws Exception { // if the key and cert file changed, then we restore the file and restart the server. - if ( !smallFileContentEquals( tlsKeyFile().toPath(), originalKeyFile ) || !smallFileContentEquals( tlsCertFile().toPath(), originalCertFile ) ) - { - debug( "Restoring original key and certificate file after certificate test." ); - updateEncryptionKeyAndCert( originalKeyFile.toFile(), originalCertFile.toFile() ); + if (!smallFileContentEquals(tlsKeyFile().toPath(), originalKeyFile) + || !smallFileContentEquals(tlsCertFile().toPath(), originalCertFile)) { + debug("Restoring original key and certificate file after certificate test."); + updateEncryptionKeyAndCert(originalKeyFile.toFile(), originalCertFile.toFile()); } - Files.deleteIfExists( originalKeyFile ); - Files.deleteIfExists( originalCertFile ); + Files.deleteIfExists(originalKeyFile); + Files.deleteIfExists(originalCertFile); } - private boolean smallFileContentEquals( Path path, Path pathAnother ) throws IOException - { - byte[] fileContent = Files.readAllBytes( path ); - byte[] fileContentAnother = Files.readAllBytes( pathAnother ); - return Arrays.equals( fileContent, fileContentAnother ); + private boolean smallFileContentEquals(Path path, Path pathAnother) throws IOException { + byte[] fileContent = Files.readAllBytes(path); + byte[] fileContentAnother = Files.readAllBytes(pathAnother); + return Arrays.equals(fileContent, fileContentAnother); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/CertificateUtil.java b/driver/src/test/java/org/neo4j/driver/util/CertificateUtil.java index 5a9e29b20d..f987b5bd5f 100644 --- a/driver/src/test/java/org/neo4j/driver/util/CertificateUtil.java +++ b/driver/src/test/java/org/neo4j/driver/util/CertificateUtil.java @@ -18,25 +18,8 @@ */ package org.neo4j.driver.util; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.BasicConstraints; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.cert.CertIOException; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.X509v3CertificateBuilder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.pkcs.PKCS10CertificationRequest; -import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; -import org.bouncycastle.util.io.pem.PemObject; -import org.bouncycastle.util.io.pem.PemWriter; +import static org.neo4j.driver.internal.util.CertificateTool.saveX509Cert; +import static org.neo4j.driver.util.FileTools.tempFile; import java.io.File; import java.io.FileWriter; @@ -57,123 +40,137 @@ import java.util.Date; import java.util.Objects; import javax.security.auth.x500.X500Principal; - +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.BasicConstraints; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.pkcs.PKCS10CertificationRequest; +import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemWriter; import org.neo4j.driver.internal.InternalPair; -import static org.neo4j.driver.internal.util.CertificateTool.saveX509Cert; -import static org.neo4j.driver.util.FileTools.tempFile; - -public class CertificateUtil -{ +public class CertificateUtil { private static final String DEFAULT_HOST_NAME = "localhost"; private static final String DEFAULT_ENCRYPTION = "RSA"; private static final Provider PROVIDER = new BouncyCastleProvider(); - static - { + + static { // adds the Bouncy castle provider to java security - Security.addProvider( PROVIDER ); + Security.addProvider(PROVIDER); } - private static KeyPair generateKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException - { - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( DEFAULT_ENCRYPTION ); - keyPairGenerator.initialize( 2048, new SecureRandom() ); + private static KeyPair generateKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(DEFAULT_ENCRYPTION); + keyPairGenerator.initialize(2048, new SecureRandom()); KeyPair keyPair = keyPairGenerator.generateKeyPair(); return keyPair; } - private static X509Certificate generateCert( X500Name issuer, X500Name subject, KeyPair issuerKeys, PublicKey publicKey ) - throws GeneralSecurityException, OperatorCreationException, CertIOException - { + private static X509Certificate generateCert( + X500Name issuer, X500Name subject, KeyPair issuerKeys, PublicKey publicKey) + throws GeneralSecurityException, OperatorCreationException, CertIOException { // Create x509 certificate - Date startDate = new Date( System.currentTimeMillis() ); - Date endDate = new Date( System.currentTimeMillis() + 365L * 24L * 60L * 60L * 1000L ); - BigInteger serialNum = BigInteger.valueOf( System.currentTimeMillis() ); - X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder( issuer, serialNum, startDate, endDate, subject, publicKey ); + Date startDate = new Date(System.currentTimeMillis()); + Date endDate = new Date(System.currentTimeMillis() + 365L * 24L * 60L * 60L * 1000L); + BigInteger serialNum = BigInteger.valueOf(System.currentTimeMillis()); + X509v3CertificateBuilder certBuilder = + new JcaX509v3CertificateBuilder(issuer, serialNum, startDate, endDate, subject, publicKey); // Subject alternative name (part of SNI extension, used for hostname verification) - GeneralNames subjectAlternativeName = new GeneralNames( new GeneralName( GeneralName.dNSName, DEFAULT_HOST_NAME ) ); - certBuilder.addExtension( Extension.subjectAlternativeName, false, subjectAlternativeName ); - certBuilder.addExtension( Extension.basicConstraints, false, new BasicConstraints( true ) ); + GeneralNames subjectAlternativeName = new GeneralNames(new GeneralName(GeneralName.dNSName, DEFAULT_HOST_NAME)); + certBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAlternativeName); + certBuilder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true)); // Get the certificate back - ContentSigner signer = new JcaContentSignerBuilder( "SHA512WithRSAEncryption" ).build( issuerKeys.getPrivate() ); - X509CertificateHolder certHolder = certBuilder.build( signer ); - X509Certificate certificate = new JcaX509CertificateConverter().setProvider( "BC" ).getCertificate( certHolder ); + ContentSigner signer = new JcaContentSignerBuilder("SHA512WithRSAEncryption").build(issuerKeys.getPrivate()); + X509CertificateHolder certHolder = certBuilder.build(signer); + X509Certificate certificate = + new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder); - certificate.verify( issuerKeys.getPublic() ); + certificate.verify(issuerKeys.getPublic()); return certificate; } - public static class SelfSignedCertificateGenerator - { + public static class SelfSignedCertificateGenerator { private final KeyPair keyPair; private final X509Certificate certificate; - public SelfSignedCertificateGenerator() throws GeneralSecurityException, OperatorCreationException, CertIOException - { + public SelfSignedCertificateGenerator() + throws GeneralSecurityException, OperatorCreationException, CertIOException { // Create the public/private rsa key pair keyPair = generateKeyPair(); // Create x509 certificate - certificate = generateCert( new X500Name( "CN=" + DEFAULT_HOST_NAME ), new X500Name( "CN=" + DEFAULT_HOST_NAME ), keyPair, - keyPair.getPublic() ); + certificate = generateCert( + new X500Name("CN=" + DEFAULT_HOST_NAME), + new X500Name("CN=" + DEFAULT_HOST_NAME), + keyPair, + keyPair.getPublic()); } - public void savePrivateKey( File saveTo ) throws IOException - { - writePem( "PRIVATE KEY", keyPair.getPrivate().getEncoded(), saveTo ); + public void savePrivateKey(File saveTo) throws IOException { + writePem("PRIVATE KEY", keyPair.getPrivate().getEncoded(), saveTo); } - public void saveSelfSignedCertificate( File saveTo ) throws CertificateEncodingException, IOException - { - writePem( "CERTIFICATE", certificate.getEncoded(), saveTo ); + public void saveSelfSignedCertificate(File saveTo) throws CertificateEncodingException, IOException { + writePem("CERTIFICATE", certificate.getEncoded(), saveTo); } - public X509Certificate sign( PKCS10CertificationRequest csr, PublicKey csrPublicKey ) - throws GeneralSecurityException, OperatorCreationException, CertIOException - { - return generateCert( X500Name.getInstance( this.certificate.getSubjectX500Principal().getEncoded() ), csr.getSubject(), keyPair, csrPublicKey ); + public X509Certificate sign(PKCS10CertificationRequest csr, PublicKey csrPublicKey) + throws GeneralSecurityException, OperatorCreationException, CertIOException { + return generateCert( + X500Name.getInstance( + this.certificate.getSubjectX500Principal().getEncoded()), + csr.getSubject(), + keyPair, + csrPublicKey); } } - public static class CertificateSigningRequestGenerator - { + public static class CertificateSigningRequestGenerator { // ref: http://senthadev.com/generating-csr-using-java-and-bouncycastle-api.html private final KeyPair keyPair; private final PKCS10CertificationRequest csr; - public CertificateSigningRequestGenerator() throws NoSuchAlgorithmException, OperatorCreationException - { - KeyPairGenerator gen = KeyPairGenerator.getInstance( DEFAULT_ENCRYPTION ); - gen.initialize( 2048, new SecureRandom() ); + public CertificateSigningRequestGenerator() throws NoSuchAlgorithmException, OperatorCreationException { + KeyPairGenerator gen = KeyPairGenerator.getInstance(DEFAULT_ENCRYPTION); + gen.initialize(2048, new SecureRandom()); keyPair = gen.generateKeyPair(); - X500Principal subject = new X500Principal( "CN=" + DEFAULT_HOST_NAME ); - ContentSigner signGen = new JcaContentSignerBuilder( "SHA512WithRSAEncryption" ).build( keyPair.getPrivate() ); + X500Principal subject = new X500Principal("CN=" + DEFAULT_HOST_NAME); + ContentSigner signGen = new JcaContentSignerBuilder("SHA512WithRSAEncryption").build(keyPair.getPrivate()); - PKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder( subject, keyPair.getPublic() ); - csr = builder.build( signGen ); + PKCS10CertificationRequestBuilder builder = + new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic()); + csr = builder.build(signGen); } - public PrivateKey privateKey() - { + public PrivateKey privateKey() { return keyPair.getPrivate(); } - public PublicKey publicKey() - { + public PublicKey publicKey() { return keyPair.getPublic(); } - public PKCS10CertificationRequest certificateSigningRequest() - { + public PKCS10CertificationRequest certificateSigningRequest() { return csr; } - public void savePrivateKey( File saveTo ) throws IOException - { - writePem( "PRIVATE KEY", keyPair.getPrivate().getEncoded(), saveTo ); + public void savePrivateKey(File saveTo) throws IOException { + writePem("PRIVATE KEY", keyPair.getPrivate().getEncoded(), saveTo); } } @@ -183,105 +180,93 @@ public void savePrivateKey( File saveTo ) throws IOException * @return a random certificate * @throws GeneralSecurityException, OperatorCreationException */ - public static X509Certificate generateSelfSignedCertificate() throws GeneralSecurityException, OperatorCreationException, CertIOException - { + public static X509Certificate generateSelfSignedCertificate() + throws GeneralSecurityException, OperatorCreationException, CertIOException { return new SelfSignedCertificateGenerator().certificate; } - private static void writePem( String type, byte[] encodedContent, File path ) throws IOException - { - if ( path.getParentFile() != null && path.getParentFile().exists() ) - { + private static void writePem(String type, byte[] encodedContent, File path) throws IOException { + if (path.getParentFile() != null && path.getParentFile().exists()) { path.getParentFile().mkdirs(); } - try ( PemWriter writer = new PemWriter( new FileWriter( path ) ) ) - { - writer.writeObject( new PemObject( type, encodedContent ) ); + try (PemWriter writer = new PemWriter(new FileWriter(path))) { + writer.writeObject(new PemObject(type, encodedContent)); writer.flush(); } } - public static CertificateKeyPair createNewCertificateAndKeySignedBy( CertificateKeyPair root ) throws Throwable - { - Objects.requireNonNull( root.certGenerator ); - File cert = tempFile( "driver", ".cert" ); - File key = tempFile( "driver", ".key" ); - CertificateUtil.CertificateSigningRequestGenerator csrGenerator = new CertificateUtil.CertificateSigningRequestGenerator(); - X509Certificate signedCert = root.certGenerator.sign( csrGenerator.certificateSigningRequest(), csrGenerator.publicKey() ); - csrGenerator.savePrivateKey( key ); - saveX509Cert( signedCert, cert ); - - return new CertificateKeyPair<>( cert, key ); + public static CertificateKeyPair createNewCertificateAndKeySignedBy(CertificateKeyPair root) + throws Throwable { + Objects.requireNonNull(root.certGenerator); + File cert = tempFile("driver", ".cert"); + File key = tempFile("driver", ".key"); + CertificateUtil.CertificateSigningRequestGenerator csrGenerator = + new CertificateUtil.CertificateSigningRequestGenerator(); + X509Certificate signedCert = + root.certGenerator.sign(csrGenerator.certificateSigningRequest(), csrGenerator.publicKey()); + csrGenerator.savePrivateKey(key); + saveX509Cert(signedCert, cert); + + return new CertificateKeyPair<>(cert, key); } - public static CertificateKeyPair createNewCertificateAndKey() throws Throwable - { - File cert = tempFile( "driver", ".cert" ); - File key = tempFile( "driver", ".key" ); - CertificateUtil.SelfSignedCertificateGenerator certGenerator = new CertificateUtil.SelfSignedCertificateGenerator(); - certGenerator.saveSelfSignedCertificate( cert ); - certGenerator.savePrivateKey( key ); + public static CertificateKeyPair createNewCertificateAndKey() throws Throwable { + File cert = tempFile("driver", ".cert"); + File key = tempFile("driver", ".key"); + CertificateUtil.SelfSignedCertificateGenerator certGenerator = + new CertificateUtil.SelfSignedCertificateGenerator(); + certGenerator.saveSelfSignedCertificate(cert); + certGenerator.savePrivateKey(key); - return new CertificateKeyPair<>( cert, key, certGenerator ); + return new CertificateKeyPair<>(cert, key, certGenerator); } - public static class CertificateKeyPair - { - private final Pair pair; + public static class CertificateKeyPair { + private final Pair pair; private final CertificateUtil.SelfSignedCertificateGenerator certGenerator; - public CertificateKeyPair( C cert, K key ) - { - this( cert, key, null ); + public CertificateKeyPair(C cert, K key) { + this(cert, key, null); } - public CertificateKeyPair( C cert, K key, CertificateUtil.SelfSignedCertificateGenerator certGenerator ) - { - this.pair = InternalPair.of( cert, key ); + public CertificateKeyPair(C cert, K key, CertificateUtil.SelfSignedCertificateGenerator certGenerator) { + this.pair = InternalPair.of(cert, key); this.certGenerator = certGenerator; } - public K key() - { + public K key() { return pair.value(); } - public C cert() - { + public C cert() { return pair.key(); } - public CertificateUtil.SelfSignedCertificateGenerator certGenerator() - { + public CertificateUtil.SelfSignedCertificateGenerator certGenerator() { return this.certGenerator; } @Override - public String toString() - { + public String toString() { return pair.toString(); } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } - CertificateKeyPair that = (CertificateKeyPair) o; + CertificateKeyPair that = (CertificateKeyPair) o; - return pair.equals( that.pair ); + return pair.equals(that.pair); } @Override - public int hashCode() - { + public int hashCode() { return pair.hashCode(); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/CertificateUtilTest.java b/driver/src/test/java/org/neo4j/driver/util/CertificateUtilTest.java index 5b50334be1..14bfb9165d 100644 --- a/driver/src/test/java/org/neo4j/driver/util/CertificateUtilTest.java +++ b/driver/src/test/java/org/neo4j/driver/util/CertificateUtilTest.java @@ -18,7 +18,10 @@ */ package org.neo4j.driver.util; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.neo4j.driver.internal.util.CertificateTool.saveX509Cert; +import static org.neo4j.driver.util.CertificateUtil.generateSelfSignedCertificate; import java.io.File; import java.security.KeyStore; @@ -26,43 +29,36 @@ import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Enumeration; - +import org.junit.jupiter.api.Test; import org.neo4j.driver.internal.util.CertificateTool; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.neo4j.driver.internal.util.CertificateTool.saveX509Cert; -import static org.neo4j.driver.util.CertificateUtil.generateSelfSignedCertificate; - -public class CertificateUtilTest -{ +public class CertificateUtilTest { @Test - void shouldLoadMultipleCertsIntoKeyStore() throws Throwable - { + void shouldLoadMultipleCertsIntoKeyStore() throws Throwable { // Given - File certFile = File.createTempFile( "3random", ".cer" ); + File certFile = File.createTempFile("3random", ".cer"); certFile.deleteOnExit(); X509Certificate cert1 = generateSelfSignedCertificate(); X509Certificate cert2 = generateSelfSignedCertificate(); X509Certificate cert3 = generateSelfSignedCertificate(); - saveX509Cert( new Certificate[] {cert1, cert2, cert3}, certFile ); + saveX509Cert(new Certificate[] {cert1, cert2, cert3}, certFile); - KeyStore keyStore = KeyStore.getInstance( "JKS" ); - keyStore.load( null, null ); + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(null, null); // When - CertificateTool.loadX509Cert( Collections.singletonList( certFile ), keyStore ); + CertificateTool.loadX509Cert(Collections.singletonList(certFile), keyStore); // Then Enumeration aliases = keyStore.aliases(); - assertTrue( aliases.hasMoreElements() ); - assertTrue( aliases.nextElement().startsWith( "neo4j.javadriver.trustedcert" ) ); - assertTrue( aliases.hasMoreElements() ); - assertTrue( aliases.nextElement().startsWith( "neo4j.javadriver.trustedcert" ) ); - assertTrue( aliases.hasMoreElements() ); - assertTrue( aliases.nextElement().startsWith( "neo4j.javadriver.trustedcert" ) ); - assertFalse( aliases.hasMoreElements() ); + assertTrue(aliases.hasMoreElements()); + assertTrue(aliases.nextElement().startsWith("neo4j.javadriver.trustedcert")); + assertTrue(aliases.hasMoreElements()); + assertTrue(aliases.nextElement().startsWith("neo4j.javadriver.trustedcert")); + assertTrue(aliases.hasMoreElements()); + assertTrue(aliases.nextElement().startsWith("neo4j.javadriver.trustedcert")); + assertFalse(aliases.hasMoreElements()); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/DaemonThreadFactory.java b/driver/src/test/java/org/neo4j/driver/util/DaemonThreadFactory.java index 8818836989..41825a47fd 100644 --- a/driver/src/test/java/org/neo4j/driver/util/DaemonThreadFactory.java +++ b/driver/src/test/java/org/neo4j/driver/util/DaemonThreadFactory.java @@ -18,33 +18,29 @@ */ package org.neo4j.driver.util; +import static java.util.Objects.requireNonNull; + import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; -import static java.util.Objects.requireNonNull; - -public class DaemonThreadFactory implements ThreadFactory -{ +public class DaemonThreadFactory implements ThreadFactory { private final String namePrefix; private final AtomicInteger threadId; - public DaemonThreadFactory( String namePrefix ) - { - this.namePrefix = requireNonNull( namePrefix ); + public DaemonThreadFactory(String namePrefix) { + this.namePrefix = requireNonNull(namePrefix); this.threadId = new AtomicInteger(); } - public static ThreadFactory daemon( String namePrefix ) - { - return new DaemonThreadFactory( namePrefix ); + public static ThreadFactory daemon(String namePrefix) { + return new DaemonThreadFactory(namePrefix); } @Override - public Thread newThread( Runnable runnable ) - { - Thread thread = new Thread( runnable ); - thread.setName( namePrefix + threadId.incrementAndGet() ); - thread.setDaemon( true ); + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable); + thread.setName(namePrefix + threadId.incrementAndGet()); + thread.setDaemon(true); return thread; } } diff --git a/driver/src/test/java/org/neo4j/driver/util/DatabaseExtension.java b/driver/src/test/java/org/neo4j/driver/util/DatabaseExtension.java index 49c6cd5e4b..929770eabf 100644 --- a/driver/src/test/java/org/neo4j/driver/util/DatabaseExtension.java +++ b/driver/src/test/java/org/neo4j/driver/util/DatabaseExtension.java @@ -18,169 +18,141 @@ */ package org.neo4j.driver.util; -import org.junit.jupiter.api.extension.AfterAllCallback; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.neo4j.driver.util.Neo4jRunner.DEFAULT_AUTH_TOKEN; +import static org.neo4j.driver.util.Neo4jRunner.HOME_DIR; +import static org.neo4j.driver.util.Neo4jRunner.debug; +import static org.neo4j.driver.util.Neo4jRunner.getOrCreateGlobalRunner; +import static org.neo4j.driver.util.Neo4jSettings.DEFAULT_TLS_CERT_PATH; +import static org.neo4j.driver.util.Neo4jSettings.DEFAULT_TLS_KEY_PATH; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.net.URI; import java.net.URL; - +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; import org.neo4j.driver.AuthToken; import org.neo4j.driver.Driver; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.types.TypeSystem; -import static org.junit.jupiter.api.Assumptions.assumeTrue; -import static org.neo4j.driver.util.Neo4jRunner.DEFAULT_AUTH_TOKEN; -import static org.neo4j.driver.util.Neo4jRunner.HOME_DIR; -import static org.neo4j.driver.util.Neo4jRunner.debug; -import static org.neo4j.driver.util.Neo4jRunner.getOrCreateGlobalRunner; -import static org.neo4j.driver.util.Neo4jSettings.DEFAULT_TLS_CERT_PATH; -import static org.neo4j.driver.util.Neo4jSettings.DEFAULT_TLS_KEY_PATH; - -public class DatabaseExtension implements BeforeEachCallback, AfterAllCallback -{ +public class DatabaseExtension implements BeforeEachCallback, AfterAllCallback { static final String TEST_RESOURCE_FOLDER_PATH = "src/test/resources"; private final Neo4jSettings settings; private Neo4jRunner runner; - public DatabaseExtension() - { - this( Neo4jSettings.TEST_SETTINGS ); + public DatabaseExtension() { + this(Neo4jSettings.TEST_SETTINGS); } - public DatabaseExtension( Neo4jSettings settings ) - { + public DatabaseExtension(Neo4jSettings settings) { this.settings = settings; } @Override - public void beforeEach( ExtensionContext context ) throws Exception - { + public void beforeEach(ExtensionContext context) throws Exception { runner = getOrCreateGlobalRunner(); - runner.ensureRunning( settings ); - TestUtil.cleanDb( driver() ); + runner.ensureRunning(settings); + TestUtil.cleanDb(driver()); } @Override - public void afterAll( ExtensionContext context ) - { - if ( runner != null ) - { + public void afterAll(ExtensionContext context) { + if (runner != null) { runner.stopNeo4j(); } } - public Driver driver() - { + public Driver driver() { return runner.driver(); } - public TypeSystem typeSystem() - { + public TypeSystem typeSystem() { return driver().defaultTypeSystem(); } - public void forceRestartDb() - { + public void forceRestartDb() { runner.forceToRestart(); } - public void restartDb( Neo4jSettings neo4jSettings ) - { - runner.restartNeo4j( neo4jSettings ); + public void restartDb(Neo4jSettings neo4jSettings) { + runner.restartNeo4j(neo4jSettings); } - public URL putTmpFile( String prefix, String suffix, String contents ) throws IOException - { - File tmpFile = File.createTempFile( prefix, suffix, null ); + public URL putTmpFile(String prefix, String suffix, String contents) throws IOException { + File tmpFile = File.createTempFile(prefix, suffix, null); tmpFile.deleteOnExit(); - try ( PrintWriter out = new PrintWriter( tmpFile ) ) - { - out.println( contents ); + try (PrintWriter out = new PrintWriter(tmpFile)) { + out.println(contents); } return tmpFile.toURI().toURL(); } - public URI uri() - { + public URI uri() { return runner.boltUri(); } - public int httpPort() - { + public int httpPort() { return runner.httpPort(); } - public int boltPort() - { + public int boltPort() { return runner.boltPort(); } - public AuthToken authToken() - { + public AuthToken authToken() { return DEFAULT_AUTH_TOKEN; } - public BoltServerAddress address() - { + public BoltServerAddress address() { return runner.boltAddress(); } - public void updateEncryptionKeyAndCert( File key, File cert ) throws Exception - { - FileTools.copyFile( key, tlsKeyFile() ); - FileTools.copyFile( cert, tlsCertFile() ); - debug( "Updated neo4j key and certificate file." ); + public void updateEncryptionKeyAndCert(File key, File cert) throws Exception { + FileTools.copyFile(key, tlsKeyFile()); + FileTools.copyFile(cert, tlsCertFile()); + debug("Updated neo4j key and certificate file."); runner.forceToRestart(); // needs to force to restart as no configuration changed } - public File tlsCertFile() - { - return new File( HOME_DIR, DEFAULT_TLS_CERT_PATH ); + public File tlsCertFile() { + return new File(HOME_DIR, DEFAULT_TLS_CERT_PATH); } - public File tlsKeyFile() - { - return new File( HOME_DIR, DEFAULT_TLS_KEY_PATH ); + public File tlsKeyFile() { + return new File(HOME_DIR, DEFAULT_TLS_KEY_PATH); } - public void ensureProcedures( String jarName ) throws IOException - { + public void ensureProcedures(String jarName) throws IOException { // These procedures was written against 3.x API. // As graph database service API is totally changed since 4.0. These procedures are no long valid. - assumeTrue( version().lessThan( ServerVersion.v4_0_0 ) ); - File procedureJar = new File( HOME_DIR, "plugins/" + jarName ); - if ( !procedureJar.exists() ) - { - FileTools.copyFile( new File( TEST_RESOURCE_FOLDER_PATH, jarName ), procedureJar ); - debug( "Added a new procedure `%s`", jarName ); + assumeTrue(version().lessThan(ServerVersion.v4_0_0)); + File procedureJar = new File(HOME_DIR, "plugins/" + jarName); + if (!procedureJar.exists()) { + FileTools.copyFile(new File(TEST_RESOURCE_FOLDER_PATH, jarName), procedureJar); + debug("Added a new procedure `%s`", jarName); runner.forceToRestart(); // needs to force to restart as no configuration changed } } - public void startDb() - { + public void startDb() { runner.startNeo4j(); } - public void stopDb() - { + public void stopDb() { runner.stopNeo4j(); } - public ServerVersion version() - { - return ServerVersion.version( driver() ); + public ServerVersion version() { + return ServerVersion.version(driver()); } - public void dumpLogs() - { + public void dumpLogs() { runner.dumpDebugLog(); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/DriverExtension.java b/driver/src/test/java/org/neo4j/driver/util/DriverExtension.java index 7c5001af12..c541b36375 100644 --- a/driver/src/test/java/org/neo4j/driver/util/DriverExtension.java +++ b/driver/src/test/java/org/neo4j/driver/util/DriverExtension.java @@ -18,51 +18,43 @@ */ package org.neo4j.driver.util; +import static org.neo4j.driver.util.TestUtil.await; + import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; - import org.neo4j.driver.Session; import org.neo4j.driver.async.AsyncSession; -import static org.neo4j.driver.util.TestUtil.await; - /** * A little utility for integration testing, this provides tests with sessions they can work with. * If you want more direct control, have a look at {@link DatabaseExtension} instead. */ -public class DriverExtension extends DatabaseExtension implements BeforeEachCallback, AfterEachCallback -{ +public class DriverExtension extends DatabaseExtension implements BeforeEachCallback, AfterEachCallback { private AsyncSession asyncSession; private Session session; - public AsyncSession asyncSession() - { + public AsyncSession asyncSession() { return asyncSession; } - public Session session() - { + public Session session() { return session; } @Override - public void beforeEach( ExtensionContext context ) throws Exception - { - super.beforeEach( context ); + public void beforeEach(ExtensionContext context) throws Exception { + super.beforeEach(context); asyncSession = driver().asyncSession(); session = driver().session(); } @Override - public void afterEach( ExtensionContext context ) - { - if ( asyncSession != null ) - { - await( asyncSession.closeAsync() ); + public void afterEach(ExtensionContext context) { + if (asyncSession != null) { + await(asyncSession.closeAsync()); } - if ( session != null ) - { + if (session != null) { session.close(); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/FileTools.java b/driver/src/test/java/org/neo4j/driver/util/FileTools.java index e34d7a1053..d6162129bd 100644 --- a/driver/src/test/java/org/neo4j/driver/util/FileTools.java +++ b/driver/src/test/java/org/neo4j/driver/util/FileTools.java @@ -18,6 +18,8 @@ */ package org.neo4j.driver.util; +import static java.io.File.createTempFile; + import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; @@ -33,22 +35,15 @@ import java.util.Scanner; import java.util.Set; -import static java.io.File.createTempFile; - -public class FileTools -{ +public class FileTools { private static final int WINDOWS_RETRY_COUNT = 5; - public static void deleteRecursively( File file ) - { - if ( file.isDirectory() ) - { + public static void deleteRecursively(File file) { + if (file.isDirectory()) { File[] files = file.listFiles(); - if ( files != null ) - { - for ( File sub : files ) - { - deleteRecursively( sub ); + if (files != null) { + for (File sub : files) { + deleteRecursively(sub); } } } @@ -57,120 +52,92 @@ public static void deleteRecursively( File file ) file.delete(); } - public static File tempFile( String prefix, String suffix ) throws Throwable - { - File file = createTempFile( prefix, suffix ); + public static File tempFile(String prefix, String suffix) throws Throwable { + File file = createTempFile(prefix, suffix); file.deleteOnExit(); return file; } - public static File tempFile( String prefix ) throws Throwable - { - return tempFile( prefix, ".tmp" ); + public static File tempFile(String prefix) throws Throwable { + return tempFile(prefix, ".tmp"); } - public static boolean deleteFile( File file ) - { - if ( !file.exists() ) - { + public static boolean deleteFile(File file) { + if (!file.exists()) { return true; } int count = 0; boolean deleted; - do - { + do { deleted = file.delete(); - if ( !deleted ) - { + if (!deleted) { count++; waitAndThenTriggerGC(); } - } - while ( !deleted && count <= WINDOWS_RETRY_COUNT ); + } while (!deleted && count <= WINDOWS_RETRY_COUNT); return deleted; } - public static void moveFile( File toMove, File target ) throws IOException - { - if ( !toMove.exists() ) - { - throw new FileNotFoundException( "Source file[" + toMove.getAbsolutePath() + "] not found" ); + public static void moveFile(File toMove, File target) throws IOException { + if (!toMove.exists()) { + throw new FileNotFoundException("Source file[" + toMove.getAbsolutePath() + "] not found"); } - if ( target.exists() ) - { - throw new IOException( "Target file[" + target.getAbsolutePath() + "] already exists" ); + if (target.exists()) { + throw new IOException("Target file[" + target.getAbsolutePath() + "] already exists"); } - if ( toMove.renameTo( target ) ) - { + if (toMove.renameTo(target)) { return; } - if ( toMove.isDirectory() ) - { - Files.createDirectories( target.toPath() ); - copyRecursively( toMove, target, null ); - deleteRecursively( toMove ); - } - else - { - copyFile( toMove, target ); - deleteFile( toMove ); + if (toMove.isDirectory()) { + Files.createDirectories(target.toPath()); + copyRecursively(toMove, target, null); + deleteRecursively(toMove); + } else { + copyFile(toMove, target); + deleteFile(toMove); } } - public static void copyRecursively( File fromDirectory, File toDirectory, FileFilter filter) throws IOException - { - for ( File fromFile : fromDirectory.listFiles( filter ) ) - { - File toFile = new File( toDirectory, fromFile.getName() ); - if ( fromFile.isDirectory() ) - { - Files.createDirectories( toFile.toPath() ); - copyRecursively( fromFile, toFile, filter ); - } - else - { - copyFile( fromFile, toFile ); + public static void copyRecursively(File fromDirectory, File toDirectory, FileFilter filter) throws IOException { + for (File fromFile : fromDirectory.listFiles(filter)) { + File toFile = new File(toDirectory, fromFile.getName()); + if (fromFile.isDirectory()) { + Files.createDirectories(toFile.toPath()); + copyRecursively(fromFile, toFile, filter); + } else { + copyFile(fromFile, toFile); } } } - public static void copyFile( File srcFile, File dstFile ) throws IOException - { + public static void copyFile(File srcFile, File dstFile) throws IOException { //noinspection ResultOfMethodCallIgnored File parentFile = dstFile.getParentFile(); - if (parentFile!=null) - { + if (parentFile != null) { parentFile.mkdirs(); } FileInputStream input = null; FileOutputStream output = null; - try - { - input = new FileInputStream( srcFile ); - output = new FileOutputStream( dstFile ); + try { + input = new FileInputStream(srcFile); + output = new FileOutputStream(dstFile); int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; int bytesRead; - while ( (bytesRead = input.read( buffer )) != -1 ) - { - output.write( buffer, 0, bytesRead ); + while ((bytesRead = input.read(buffer)) != -1) { + output.write(buffer, 0, bytesRead); } - } - catch ( IOException e ) - { + } catch (IOException e) { // Because the message from this cause may not mention which file it's about - throw new IOException( "Could not copy '" + srcFile.getCanonicalPath() + "' to '" + dstFile.getCanonicalPath() + "'", e ); - } - finally - { - if ( input != null ) - { + throw new IOException( + "Could not copy '" + srcFile.getCanonicalPath() + "' to '" + dstFile.getCanonicalPath() + "'", e); + } finally { + if (input != null) { input.close(); } - if ( output != null ) - { + if (output != null) { output.close(); } } @@ -179,106 +146,84 @@ public static void copyFile( File srcFile, File dstFile ) throws IOException /* * See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4715154. */ - private static void waitAndThenTriggerGC() - { - try - { - Thread.sleep( 500 ); - } - catch ( InterruptedException ee ) - { + private static void waitAndThenTriggerGC() { + try { + Thread.sleep(500); + } catch (InterruptedException ee) { Thread.interrupted(); } // ok System.gc(); } - public static void updateProperty( File propFile, String key, String value ) throws IOException - { - Map propertiesMap = new HashMap<>( 1 ); - propertiesMap.put( key, value ); - updateProperties( propFile, propertiesMap, Collections.emptySet() ); + public static void updateProperty(File propFile, String key, String value) throws IOException { + Map propertiesMap = new HashMap<>(1); + propertiesMap.put(key, value); + updateProperties(propFile, propertiesMap, Collections.emptySet()); } - public static void updateProperties( File propFile, Map propertiesMap, Set excludes ) throws IOException - { - Scanner in = new Scanner( propFile ); + public static void updateProperties(File propFile, Map propertiesMap, Set excludes) + throws IOException { + Scanner in = new Scanner(propFile); - Set updatedProperties = new HashSet<>( propertiesMap.size() ); - File newPropFile = File.createTempFile( propFile.getName(), null ); + Set updatedProperties = new HashSet<>(propertiesMap.size()); + File newPropFile = File.createTempFile(propFile.getName(), null); - try - { - FileOutputStream outStream = new FileOutputStream( newPropFile ); - PrintWriter out = new PrintWriter( outStream ); + try { + FileOutputStream outStream = new FileOutputStream(newPropFile); + PrintWriter out = new PrintWriter(outStream); - while ( in.hasNextLine() ) - { + while (in.hasNextLine()) { String line = in.nextLine(); - if ( !line.trim().startsWith( "#" ) ) - { - String[] tokens = line.split( "=" ); - if ( tokens.length == 2 ) - { + if (!line.trim().startsWith("#")) { + String[] tokens = line.split("="); + if (tokens.length == 2) { String name = tokens[0].trim(); - if (excludes.contains( name )) - { + if (excludes.contains(name)) { continue; } - Object value = propertiesMap.get( name ); - if ( value != null && !updatedProperties.contains( name ) ) - { + Object value = propertiesMap.get(name); + if (value != null && !updatedProperties.contains(name)) { // found property and set it to the new value - printlnProperty( out, name, value ); - updatedProperties.add( name ); - } - else - { + printlnProperty(out, name, value); + updatedProperties.add(name); + } else { // not the property that we are looking for, print it as original - out.println( line ); + out.println(line); } - } - else - { + } else { // not the property that we are looking for, print it as original - out.println( line ); + out.println(line); } - } - else - { + } else { // comments, print as original - out.println( line ); + out.println(line); } } - for ( Map.Entry entry : propertiesMap.entrySet() ) - { + for (Map.Entry entry : propertiesMap.entrySet()) { String name = entry.getKey(); Object value = entry.getValue(); - if ( value != null && !updatedProperties.contains( name ) ) - { + if (value != null && !updatedProperties.contains(name)) { // add this as a new prop - printlnProperty( out, name, value ); + printlnProperty(out, name, value); } } in.close(); out.flush(); out.close(); - deleteFile( propFile ); - moveFile( newPropFile, propFile ); - } - catch ( IOException | RuntimeException e ) - { + deleteFile(propFile); + moveFile(newPropFile, propFile); + } catch (IOException | RuntimeException e) { newPropFile.deleteOnExit(); throw e; } } - private static void printlnProperty( PrintWriter out, String name, Object value ) - { - out.print( name ); - out.print( '=' ); - out.println( value ); + private static void printlnProperty(PrintWriter out, String name, Object value) { + out.print(name); + out.print('='); + out.println(value); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/FileToolsTest.java b/driver/src/test/java/org/neo4j/driver/util/FileToolsTest.java index e1abc10f7b..a855edf022 100644 --- a/driver/src/test/java/org/neo4j/driver/util/FileToolsTest.java +++ b/driver/src/test/java/org/neo4j/driver/util/FileToolsTest.java @@ -18,102 +18,85 @@ */ package org.neo4j.driver.util; -import org.junit.jupiter.api.Test; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.util.Scanner; +import org.junit.jupiter.api.Test; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.junit.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -class FileToolsTest -{ +class FileToolsTest { @Test - void shouldBeAbleToCreateTemporaryFile() throws Throwable - { + void shouldBeAbleToCreateTemporaryFile() throws Throwable { // Given - File file = FileTools.tempFile( "test" ); + File file = FileTools.tempFile("test"); // Then - try - { - assertThat( file.exists(), equalTo( true ) ); - } - finally - { - assertThat( FileTools.deleteFile( file ), equalTo( true ) ); + try { + assertThat(file.exists(), equalTo(true)); + } finally { + assertThat(FileTools.deleteFile(file), equalTo(true)); } } @Test - void shouldAddPropertyAtBottom() throws IOException - { + void shouldAddPropertyAtBottom() throws IOException { // Given File propertyFile = createPropertyFile(); // When - FileTools.updateProperty( propertyFile, "cat.name", "mimi" ); + FileTools.updateProperty(propertyFile, "cat.name", "mimi"); // Then - try( Scanner in = new Scanner( propertyFile ) ) - { - assertEquals( "#Wow wow", in.nextLine() ); - assertEquals( "Meow meow", in.nextLine() ); - assertEquals( "color=black", in.nextLine() ); - assertEquals( "cat.age=3", in.nextLine() ); - assertEquals( "cat.name=mimi", in.nextLine() ); - - assertFalse( in.hasNextLine() ); - } - finally - { - assertThat( FileTools.deleteFile( propertyFile ), equalTo( true ) ); + try (Scanner in = new Scanner(propertyFile)) { + assertEquals("#Wow wow", in.nextLine()); + assertEquals("Meow meow", in.nextLine()); + assertEquals("color=black", in.nextLine()); + assertEquals("cat.age=3", in.nextLine()); + assertEquals("cat.name=mimi", in.nextLine()); + + assertFalse(in.hasNextLine()); + } finally { + assertThat(FileTools.deleteFile(propertyFile), equalTo(true)); } } @Test - void shouldResetPropertyAtTheSameLine() throws IOException - { + void shouldResetPropertyAtTheSameLine() throws IOException { // Given File propertyFile = createPropertyFile(); // When - FileTools.updateProperty( propertyFile, "color", "white" ); + FileTools.updateProperty(propertyFile, "color", "white"); // Then - try( Scanner in = new Scanner( propertyFile ) ) - { - assertEquals( "#Wow wow", in.nextLine() ); - assertEquals( "Meow meow", in.nextLine() ); - assertEquals( "color=white", in.nextLine() ); - assertEquals( "cat.age=3", in.nextLine() ); - - assertFalse( in.hasNextLine() ); - } - finally - { - assertThat( FileTools.deleteFile( propertyFile ), equalTo( true ) ); + try (Scanner in = new Scanner(propertyFile)) { + assertEquals("#Wow wow", in.nextLine()); + assertEquals("Meow meow", in.nextLine()); + assertEquals("color=white", in.nextLine()); + assertEquals("cat.age=3", in.nextLine()); + + assertFalse(in.hasNextLine()); + } finally { + assertThat(FileTools.deleteFile(propertyFile), equalTo(true)); } } + private File createPropertyFile() throws FileNotFoundException { + File propFile = new File("Cat"); + PrintWriter out = new PrintWriter(propFile); - private File createPropertyFile() throws FileNotFoundException - { - File propFile = new File( "Cat" ); - PrintWriter out = new PrintWriter( propFile ); - - out.println( "#Wow wow" ); - out.println( "Meow meow" ); - out.println( "color=black" ); - out.println( "cat.age=3" ); + out.println("#Wow wow"); + out.println("Meow meow"); + out.println("color=black"); + out.println("cat.age=3"); out.close(); return propFile; } - } diff --git a/driver/src/test/java/org/neo4j/driver/util/Neo4jRunner.java b/driver/src/test/java/org/neo4j/driver/util/Neo4jRunner.java index 4db2773451..5116ad243d 100644 --- a/driver/src/test/java/org/neo4j/driver/util/Neo4jRunner.java +++ b/driver/src/test/java/org/neo4j/driver/util/Neo4jRunner.java @@ -18,6 +18,19 @@ */ package org.neo4j.driver.util; +import static java.util.Arrays.asList; +import static java.util.logging.Level.INFO; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.neo4j.driver.AuthTokens.basic; +import static org.neo4j.driver.Logging.console; +import static org.neo4j.driver.util.FileTools.moveFile; +import static org.neo4j.driver.util.FileTools.updateProperties; +import static org.neo4j.driver.util.Neo4jSettings.CURRENT_BOLT_PORT; +import static org.neo4j.driver.util.Neo4jSettings.CURRENT_HTTP_PORT; +import static org.neo4j.driver.util.Neo4jSettings.TEST_JVM_ID; +import static org.neo4j.driver.util.cc.CommandLineUtil.boltKitAvailable; +import static org.neo4j.driver.util.cc.CommandLineUtil.executeCommand; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -29,7 +42,6 @@ import java.util.List; import java.util.Map; import java.util.Scanner; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @@ -37,198 +49,157 @@ import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.ErrorUtil; -import static java.util.Arrays.asList; -import static java.util.logging.Level.INFO; -import static org.junit.jupiter.api.Assumptions.assumeTrue; -import static org.neo4j.driver.AuthTokens.basic; -import static org.neo4j.driver.Logging.console; -import static org.neo4j.driver.util.FileTools.moveFile; -import static org.neo4j.driver.util.FileTools.updateProperties; -import static org.neo4j.driver.util.Neo4jSettings.CURRENT_BOLT_PORT; -import static org.neo4j.driver.util.Neo4jSettings.CURRENT_HTTP_PORT; -import static org.neo4j.driver.util.Neo4jSettings.TEST_JVM_ID; -import static org.neo4j.driver.util.cc.CommandLineUtil.boltKitAvailable; -import static org.neo4j.driver.util.cc.CommandLineUtil.executeCommand; - /** * This class wraps the neo4j stand-alone jar in some code to help pulling it in from a remote URL and then launching * it in a separate process. */ -public class Neo4jRunner -{ +public class Neo4jRunner { private static Neo4jRunner globalInstance; private static final String DEFAULT_NEOCTRL_ARGS = "-e 3.5.11"; - private static final String ENV_NEOCTRL_ARGS = System.getenv( "JAVA_DRIVER_NEOCTRL_ARGS" ); - public static final String NEOCTRL_ARGS = System.getProperty( "neoctrl.args", ENV_NEOCTRL_ARGS == null ? DEFAULT_NEOCTRL_ARGS : ENV_NEOCTRL_ARGS ); - public static final Config DEFAULT_CONFIG = Config.builder().withLogging( console( INFO ) ).withoutEncryption().build(); + private static final String ENV_NEOCTRL_ARGS = System.getenv("JAVA_DRIVER_NEOCTRL_ARGS"); + public static final String NEOCTRL_ARGS = + System.getProperty("neoctrl.args", ENV_NEOCTRL_ARGS == null ? DEFAULT_NEOCTRL_ARGS : ENV_NEOCTRL_ARGS); + public static final Config DEFAULT_CONFIG = + Config.builder().withLogging(console(INFO)).withoutEncryption().build(); public static final String USER = "neo4j"; public static final String PASSWORD = "password"; - public static final AuthToken DEFAULT_AUTH_TOKEN = basic( USER, PASSWORD ); + public static final AuthToken DEFAULT_AUTH_TOKEN = basic(USER, PASSWORD); private Neo4jSettings currentSettings = Neo4jSettings.TEST_SETTINGS; - public static final String TARGET_DIR = new File( "../target" ).getAbsolutePath(); - private static final String NEO4J_DIR = new File( TARGET_DIR, "test-server-" + TEST_JVM_ID ).getAbsolutePath(); - public static final String HOME_DIR = new File( NEO4J_DIR, "neo4jHome" ).getAbsolutePath(); + public static final String TARGET_DIR = new File("../target").getAbsolutePath(); + private static final String NEO4J_DIR = new File(TARGET_DIR, "test-server-" + TEST_JVM_ID).getAbsolutePath(); + public static final String HOME_DIR = new File(NEO4J_DIR, "neo4jHome").getAbsolutePath(); private Driver driver; private boolean restartDriver; - public int httpPort() - { + public int httpPort() { return CURRENT_HTTP_PORT; } - public int boltPort() - { + public int boltPort() { return CURRENT_BOLT_PORT; } - public BoltServerAddress boltAddress() - { - return new BoltServerAddress( boltUri() ); + public BoltServerAddress boltAddress() { + return new BoltServerAddress(boltUri()); } - public URI boltUri() - { - return URI.create( "bolt://localhost:" + boltPort() ); + public URI boltUri() { + return URI.create("bolt://localhost:" + boltPort()); } /** Global runner controlling a single server, used to avoid having to restart the server between tests */ - public static synchronized Neo4jRunner getOrCreateGlobalRunner() throws IOException - { - assumeTrue( boltKitAvailable(), "BoltKit support unavailable" ); - if ( globalInstance == null ) - { + public static synchronized Neo4jRunner getOrCreateGlobalRunner() throws IOException { + assumeTrue(boltKitAvailable(), "BoltKit support unavailable"); + if (globalInstance == null) { globalInstance = new Neo4jRunner(); } return globalInstance; } - public static synchronized boolean globalRunnerExists() - { + public static synchronized boolean globalRunnerExists() { return globalInstance != null; } - private Neo4jRunner() throws IOException - { - try - { + private Neo4jRunner() throws IOException { + try { installNeo4j(); updateServerSettingsFile(); - try - { + try { startNeo4j(); - } - catch ( Exception e ) - { - debug( "Failed to start server first time due to error: " + ErrorUtil.getRootCause( e ).getMessage() ); - debug( "Retry to start server again." ); + } catch (Exception e) { + debug("Failed to start server first time due to error: " + + ErrorUtil.getRootCause(e).getMessage()); + debug("Retry to start server again."); startNeo4j(); } - } - finally - { + } finally { // Make sure we stop on JVM exit even if start failed installShutdownHook(); } } - public void ensureRunning( Neo4jSettings neo4jSettings ) - { + public void ensureRunning(Neo4jSettings neo4jSettings) { ServerStatus status = serverStatus(); - switch( status ) - { - case OFFLINE: - updateServerSettings( neo4jSettings ); - startNeo4j(); - break; - case ONLINE: - restartNeo4j( neo4jSettings ); - break; + switch (status) { + case OFFLINE: + updateServerSettings(neo4jSettings); + startNeo4j(); + break; + case ONLINE: + restartNeo4j(neo4jSettings); + break; } } - public Driver driver() - { - if ( restartDriver ) - { + public Driver driver() { + if (restartDriver) { restartDriver = false; - if ( driver != null ) - { + if (driver != null) { driver.close(); driver = null; } } - if ( driver == null ) - { - driver = GraphDatabase.driver( boltUri(), DEFAULT_AUTH_TOKEN, DEFAULT_CONFIG ); + if (driver == null) { + driver = GraphDatabase.driver(boltUri(), DEFAULT_AUTH_TOKEN, DEFAULT_CONFIG); } return driver; } - private void installNeo4j() throws IOException - { - File targetHomeFile = new File( HOME_DIR ); - if( targetHomeFile.exists() ) - { - debug( "Found and using server installed at `%s`. ", HOME_DIR ); - } - else - { + private void installNeo4j() throws IOException { + File targetHomeFile = new File(HOME_DIR); + if (targetHomeFile.exists()) { + debug("Found and using server installed at `%s`. ", HOME_DIR); + } else { List commands = new ArrayList<>(); - commands.add( "neoctrl-install" ); - String[] split = NEOCTRL_ARGS.trim().split( "\\s+" ); - commands.addAll( asList( split ) ); - commands.add( NEO4J_DIR ); + commands.add("neoctrl-install"); + String[] split = NEOCTRL_ARGS.trim().split("\\s+"); + commands.addAll(asList(split)); + commands.add(NEO4J_DIR); - String tempHomeDir = executeCommand( commands ).trim(); - debug( "Downloaded server at `%s`, now renaming to `%s`.", tempHomeDir, HOME_DIR ); + String tempHomeDir = executeCommand(commands).trim(); + debug("Downloaded server at `%s`, now renaming to `%s`.", tempHomeDir, HOME_DIR); - moveFile( new File( tempHomeDir ), targetHomeFile ); - debug( "Installed server at `%s`.", HOME_DIR ); - executeCommand( "neoctrl-create-user", HOME_DIR, USER, PASSWORD ); + moveFile(new File(tempHomeDir), targetHomeFile); + debug("Installed server at `%s`.", HOME_DIR); + executeCommand("neoctrl-create-user", HOME_DIR, USER, PASSWORD); } } - public void startNeo4j() - { - debug( "Starting server..." ); - executeCommand( "neoctrl-start", HOME_DIR, "-v" ); - debug( "Server started." ); + public void startNeo4j() { + debug("Starting server..."); + executeCommand("neoctrl-start", HOME_DIR, "-v"); + debug("Server started."); } - public synchronized void stopNeo4j() - { - if( serverStatus() == ServerStatus.OFFLINE ) - { + public synchronized void stopNeo4j() { + if (serverStatus() == ServerStatus.OFFLINE) { return; } restartDriver = true; - debug( "Stopping server..." ); - executeCommand( "neoctrl-stop", HOME_DIR ); - debug( "Server stopped." ); + debug("Stopping server..."); + executeCommand("neoctrl-stop", HOME_DIR); + debug("Server stopped."); } - public void killNeo4j() - { - if ( serverStatus() == ServerStatus.OFFLINE ) - { + public void killNeo4j() { + if (serverStatus() == ServerStatus.OFFLINE) { return; } restartDriver = true; - debug( "Killing server..." ); - executeCommand( "neoctrl-stop", "-k", HOME_DIR ); - debug( "Server killed." ); + debug("Killing server..."); + executeCommand("neoctrl-stop", "-k", HOME_DIR); + debug("Server killed."); } - public void forceToRestart() - { + public void forceToRestart() { stopNeo4j(); startNeo4j(); } @@ -236,18 +207,16 @@ public void forceToRestart() /** * Restart the server with default testing server configuration */ - public void restartNeo4j() - { - restartNeo4j( Neo4jSettings.TEST_SETTINGS ); + public void restartNeo4j() { + restartNeo4j(Neo4jSettings.TEST_SETTINGS); } /** * Will only restart the server if any configuration changes happens * @param neo4jSettings */ - public void restartNeo4j( Neo4jSettings neo4jSettings ) - { - if( updateServerSettings( neo4jSettings ) ) // needs to update server setting files + public void restartNeo4j(Neo4jSettings neo4jSettings) { + if (updateServerSettings(neo4jSettings)) // needs to update server setting files { forceToRestart(); } @@ -256,56 +225,42 @@ public void restartNeo4j( Neo4jSettings neo4jSettings ) /** * prints the debug log contents to stdOut */ - public void dumpDebugLog() - { - try - { - System.out.println( "Debug log for: " + HOME_DIR ); - Scanner input = new Scanner( new File( HOME_DIR + "/logs/debug.log" )); + public void dumpDebugLog() { + try { + System.out.println("Debug log for: " + HOME_DIR); + Scanner input = new Scanner(new File(HOME_DIR + "/logs/debug.log")); - while (input.hasNextLine()) - { + while (input.hasNextLine()) { System.out.println(input.nextLine()); } - } - catch ( FileNotFoundException e ) - { + } catch (FileNotFoundException e) { System.out.println("Unable to find debug log file for: " + HOME_DIR); e.printStackTrace(); } - } - private enum ServerStatus - { - ONLINE, OFFLINE + private enum ServerStatus { + ONLINE, + OFFLINE } - private ServerStatus serverStatus() - { - try - { + private ServerStatus serverStatus() { + try { SocketChannel soChannel = SocketChannel.open(); - soChannel.setOption( StandardSocketOptions.SO_REUSEADDR, true ); + soChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true); BoltServerAddress address = boltAddress(); - soChannel.connect( new InetSocketAddress( address.connectionHost(), address.port() ) ); + soChannel.connect(new InetSocketAddress(address.connectionHost(), address.port())); soChannel.close(); return ServerStatus.ONLINE; - } - catch ( IOException e ) - { + } catch (IOException e) { return ServerStatus.OFFLINE; } } - private boolean updateServerSettings( Neo4jSettings newSetting ) - { - if ( currentSettings.equals( newSetting ) ) - { + private boolean updateServerSettings(Neo4jSettings newSetting) { + if (currentSettings.equals(newSetting)) { return false; - } - else - { + } else { currentSettings = newSetting; } updateServerSettingsFile(); @@ -315,63 +270,48 @@ private boolean updateServerSettings( Neo4jSettings newSetting ) /** * Write updated neo4j settings into neo4j-server.properties for use by the next start */ - private void updateServerSettingsFile() - { + private void updateServerSettingsFile() { Map propertiesMap = currentSettings.propertiesMap(); - if ( propertiesMap.isEmpty() ) - { + if (propertiesMap.isEmpty()) { return; } - File oldFile = new File( HOME_DIR, "conf/neo4j.conf" ); - try - { - debug( "Changing server properties file (for next start): %s", oldFile.getCanonicalPath() ); - for ( Map.Entry property : propertiesMap.entrySet() ) - { + File oldFile = new File(HOME_DIR, "conf/neo4j.conf"); + try { + debug("Changing server properties file (for next start): %s", oldFile.getCanonicalPath()); + for (Map.Entry property : propertiesMap.entrySet()) { String name = property.getKey(); Object value = property.getValue(); - debug( "%s=%s", name, value ); + debug("%s=%s", name, value); } - updateProperties( oldFile, propertiesMap, currentSettings.excludes() ); - } - catch ( Exception e ) - { - throw new RuntimeException( e ); + updateProperties(oldFile, propertiesMap, currentSettings.excludes()); + } catch (Exception e) { + throw new RuntimeException(e); } } - private void installShutdownHook() - { - Runtime.getRuntime().addShutdownHook( new Thread( () -> - { - try - { - debug( "Starting shutdown hook" ); - if ( driver != null ) - { + private void installShutdownHook() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + debug("Starting shutdown hook"); + if (driver != null) { driver.close(); } stopNeo4j(); - debug( "Finished shutdown hook" ); - } - catch ( Exception e ) - { + debug("Finished shutdown hook"); + } catch (Exception e) { e.printStackTrace(); } - } ) ); + })); } - public static void debug( String text, Object... args ) - { - System.out.println( String.format( text, args ) ); + public static void debug(String text, Object... args) { + System.out.println(String.format(text, args)); } - public static void debug( String text ) - { - System.out.println( text ); + public static void debug(String text) { + System.out.println(text); } } - diff --git a/driver/src/test/java/org/neo4j/driver/util/Neo4jSettings.java b/driver/src/test/java/org/neo4j/driver/util/Neo4jSettings.java index 27f7ee72b3..20c7fa1d3a 100644 --- a/driver/src/test/java/org/neo4j/driver/util/Neo4jSettings.java +++ b/driver/src/test/java/org/neo4j/driver/util/Neo4jSettings.java @@ -18,16 +18,15 @@ */ package org.neo4j.driver.util; +import static org.neo4j.driver.internal.util.Iterables.map; + import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import static org.neo4j.driver.internal.util.Iterables.map; - -public class Neo4jSettings -{ +public class Neo4jSettings { public static final String DATA_DIR = "dbms.directories.data"; public static final String IMPORT_DIR = "dbms.directories.import"; public static final String LISTEN_ADDR = "dbms.connectors.default_listen_address"; @@ -42,7 +41,7 @@ public class Neo4jSettings public static final String DEFAULT_DATA_DIR = "data"; - static final int TEST_JVM_ID = Integer.getInteger( "testJvmId", 0 ); + static final int TEST_JVM_ID = Integer.getInteger("testJvmId", 0); private static final int DEFAULT_HTTP_PORT = 7000; private static final int DEFAULT_HTTPS_PORT = 8000; @@ -57,88 +56,88 @@ public class Neo4jSettings private final Map settings; private final Set excludes; - public static final Neo4jSettings TEST_SETTINGS = new Neo4jSettings( map( - "dbms.connector.http.listen_address", ":" + CURRENT_HTTP_PORT, - "dbms.connector.https.listen_address", ":" + CURRENT_HTTPS_PORT, - "dbms.connector.bolt.listen_address", ":" + CURRENT_BOLT_PORT, - "dbms.windows_service_name", WINDOWS_SERVICE_NAME, - - DATA_DIR, DEFAULT_DATA_DIR, - IMPORT_DIR, DEFAULT_IMPORT_DIR, - BOLT_TLS_LEVEL, DEFAULT_BOLT_TLS_LEVEL, - LISTEN_ADDR, IPV6_ENABLED_ADDR ), Collections.emptySet() ); - - public enum BoltTlsLevel - { + public static final Neo4jSettings TEST_SETTINGS = new Neo4jSettings( + map( + "dbms.connector.http.listen_address", + ":" + CURRENT_HTTP_PORT, + "dbms.connector.https.listen_address", + ":" + CURRENT_HTTPS_PORT, + "dbms.connector.bolt.listen_address", + ":" + CURRENT_BOLT_PORT, + "dbms.windows_service_name", + WINDOWS_SERVICE_NAME, + DATA_DIR, + DEFAULT_DATA_DIR, + IMPORT_DIR, + DEFAULT_IMPORT_DIR, + BOLT_TLS_LEVEL, + DEFAULT_BOLT_TLS_LEVEL, + LISTEN_ADDR, + IPV6_ENABLED_ADDR), + Collections.emptySet()); + + public enum BoltTlsLevel { OPTIONAL, REQUIRED, DISABLED } - private Neo4jSettings( Map settings, Set excludes ) - { + private Neo4jSettings(Map settings, Set excludes) { this.settings = settings; this.excludes = excludes; } - public Map propertiesMap() - { + public Map propertiesMap() { return settings; } - public Neo4jSettings updateWith( String key, String value ) - { - return updateWith( map(key, value), excludes ); + public Neo4jSettings updateWith(String key, String value) { + return updateWith(map(key, value), excludes); } - private Neo4jSettings updateWith( Map updates, Set excludes ) - { - HashMap newSettings = new HashMap<>( settings ); - for ( Map.Entry entry : updates.entrySet() ) - { - newSettings.put( entry.getKey(), entry.getValue() ); + private Neo4jSettings updateWith(Map updates, Set excludes) { + HashMap newSettings = new HashMap<>(settings); + for (Map.Entry entry : updates.entrySet()) { + newSettings.put(entry.getKey(), entry.getValue()); } - for ( String exclude : excludes ) - { - newSettings.remove( exclude ); + for (String exclude : excludes) { + newSettings.remove(exclude); } - return new Neo4jSettings( newSettings, excludes ); + return new Neo4jSettings(newSettings, excludes); } - public Neo4jSettings without(String key) - { - Set newExcludes = new HashSet<>( excludes ); - newExcludes.add( key ); - Map newMap = new HashMap<>( this.settings ); - newMap.remove( key ); - Neo4jSettings newSettings = new Neo4jSettings( newMap, newExcludes ); + public Neo4jSettings without(String key) { + Set newExcludes = new HashSet<>(excludes); + newExcludes.add(key); + Map newMap = new HashMap<>(this.settings); + newMap.remove(key); + Neo4jSettings newSettings = new Neo4jSettings(newMap, newExcludes); return newSettings; } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { return true; } - if ( o == null || getClass() != o.getClass() ) - { return false; } + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Neo4jSettings that = (Neo4jSettings) o; - if ( !settings.equals( that.settings ) ) - { return false; } - return excludes.equals( that.excludes ); - + if (!settings.equals(that.settings)) { + return false; + } + return excludes.equals(that.excludes); } @Override - public int hashCode() - { + public int hashCode() { return settings.hashCode(); } - public Set excludes() - { + public Set excludes() { return excludes; } } diff --git a/driver/src/test/java/org/neo4j/driver/util/ParallelizableIT.java b/driver/src/test/java/org/neo4j/driver/util/ParallelizableIT.java index 965effb26b..db2a5c76f4 100644 --- a/driver/src/test/java/org/neo4j/driver/util/ParallelizableIT.java +++ b/driver/src/test/java/org/neo4j/driver/util/ParallelizableIT.java @@ -18,20 +18,17 @@ */ package org.neo4j.driver.util; -import org.junit.jupiter.api.Tag; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.junit.jupiter.api.Tag; /** * Marker annotation for the Maven Failsafe plugin saying that the annotated test class can be executed in parallel with other tests. * It will get executed in a separately forked JVM. All tests will be split between a fixed number of JVMs. */ -@Target( ElementType.TYPE ) -@Retention( RetentionPolicy.RUNTIME ) -@Tag( "parallelizableIT" ) -public @interface ParallelizableIT -{ -} +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Tag("parallelizableIT") +public @interface ParallelizableIT {} diff --git a/driver/src/test/java/org/neo4j/driver/util/ProcessEnvConfigurator.java b/driver/src/test/java/org/neo4j/driver/util/ProcessEnvConfigurator.java index 96dfad6fee..7c60e7e02c 100644 --- a/driver/src/test/java/org/neo4j/driver/util/ProcessEnvConfigurator.java +++ b/driver/src/test/java/org/neo4j/driver/util/ProcessEnvConfigurator.java @@ -18,8 +18,7 @@ */ package org.neo4j.driver.util; -public final class ProcessEnvConfigurator -{ +public final class ProcessEnvConfigurator { /** * Name of environment variable used by the Neo4j database. */ @@ -34,18 +33,14 @@ public final class ProcessEnvConfigurator */ private static final String BOLTKIT_LOCAL_PACKAGE = "NEOCTRL_LOCAL_PACKAGE"; - private ProcessEnvConfigurator() - { - } + private ProcessEnvConfigurator() {} - public static void configure( ProcessBuilder processBuilder ) - { - processBuilder.environment().put( JAVA_HOME, determineJavaHome() ); + public static void configure(ProcessBuilder processBuilder) { + processBuilder.environment().put(JAVA_HOME, determineJavaHome()); String localPackage = determineLocalPackage(); - if ( localPackage != null ) - { - processBuilder.environment().put( BOLTKIT_LOCAL_PACKAGE, localPackage ); + if (localPackage != null) { + processBuilder.environment().put(BOLTKIT_LOCAL_PACKAGE, localPackage); } } @@ -58,14 +53,12 @@ public static void configure( ProcessBuilder processBuilder ) * * @return path to the java home. */ - private static String determineJavaHome() - { - return System.getenv().getOrDefault( NEO4J_JAVA, System.getProperties().getProperty( "java.home" ) ); + private static String determineJavaHome() { + return System.getenv().getOrDefault(NEO4J_JAVA, System.getProperties().getProperty("java.home")); } - private static String determineLocalPackage() - { - String value = System.getenv().getOrDefault( BOLTKIT_LOCAL_PACKAGE, "" ).trim(); + private static String determineLocalPackage() { + String value = System.getenv().getOrDefault(BOLTKIT_LOCAL_PACKAGE, "").trim(); return value.isEmpty() ? null : value; } } diff --git a/driver/src/test/java/org/neo4j/driver/util/SessionExtension.java b/driver/src/test/java/org/neo4j/driver/util/SessionExtension.java index de38139a5d..457f03e336 100644 --- a/driver/src/test/java/org/neo4j/driver/util/SessionExtension.java +++ b/driver/src/test/java/org/neo4j/driver/util/SessionExtension.java @@ -18,152 +18,128 @@ */ package org.neo4j.driver.util; +import java.util.Map; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; - -import java.util.Map; - +import org.neo4j.driver.Bookmark; import org.neo4j.driver.Query; import org.neo4j.driver.Record; -import org.neo4j.driver.Session; import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.TransactionWork; import org.neo4j.driver.Value; -import org.neo4j.driver.Bookmark; /** * A little utility for integration testing, this provides tests with a session they can work with. * If you want more direct control, have a look at {@link DatabaseExtension} instead. */ -public class SessionExtension extends DatabaseExtension implements Session, BeforeEachCallback, AfterEachCallback -{ +public class SessionExtension extends DatabaseExtension implements Session, BeforeEachCallback, AfterEachCallback { private Session realSession; @Override - public void beforeEach( ExtensionContext context ) throws Exception - { - super.beforeEach( context ); + public void beforeEach(ExtensionContext context) throws Exception { + super.beforeEach(context); realSession = driver().session(); } @Override - public void afterEach( ExtensionContext context ) - { - if ( realSession != null ) - { + public void afterEach(ExtensionContext context) { + if (realSession != null) { realSession.close(); } } @Override - public boolean isOpen() - { + public boolean isOpen() { return realSession.isOpen(); } @Override - public void close() - { - throw new UnsupportedOperationException( "Disallowed on this test session" ); + public void close() { + throw new UnsupportedOperationException("Disallowed on this test session"); } @Override - public Transaction beginTransaction() - { + public Transaction beginTransaction() { return realSession.beginTransaction(); } @Override - public Transaction beginTransaction( TransactionConfig config ) - { - return realSession.beginTransaction( config ); + public Transaction beginTransaction(TransactionConfig config) { + return realSession.beginTransaction(config); } @Override - public T readTransaction( TransactionWork work ) - { - return realSession.readTransaction( work ); + public T readTransaction(TransactionWork work) { + return realSession.readTransaction(work); } @Override - public T readTransaction( TransactionWork work, TransactionConfig config ) - { - return realSession.readTransaction( work, config ); + public T readTransaction(TransactionWork work, TransactionConfig config) { + return realSession.readTransaction(work, config); } @Override - public T writeTransaction( TransactionWork work ) - { - return realSession.writeTransaction( work ); + public T writeTransaction(TransactionWork work) { + return realSession.writeTransaction(work); } @Override - public T writeTransaction( TransactionWork work, TransactionConfig config ) - { - return realSession.writeTransaction( work, config ); + public T writeTransaction(TransactionWork work, TransactionConfig config) { + return realSession.writeTransaction(work, config); } @Override - public Bookmark lastBookmark() - { + public Bookmark lastBookmark() { return realSession.lastBookmark(); } @Deprecated @Override - public void reset() - { + public void reset() { realSession.reset(); } @Override - public Result run(String query, Map parameters) - { + public Result run(String query, Map parameters) { return realSession.run(query, parameters); } @Override - public Result run(String query, Value parameters ) - { - return realSession.run(query, parameters ); + public Result run(String query, Value parameters) { + return realSession.run(query, parameters); } @Override - public Result run(String query, Record parameters ) - { - return realSession.run(query, parameters ); + public Result run(String query, Record parameters) { + return realSession.run(query, parameters); } @Override - public Result run(String query) - { + public Result run(String query) { return realSession.run(query); } @Override - public Result run(Query query) - { - return realSession.run( query.text(), query.parameters() ); + public Result run(Query query) { + return realSession.run(query.text(), query.parameters()); } @Override - public Result run(String query, TransactionConfig config ) - { - return realSession.run(query, config ); + public Result run(String query, TransactionConfig config) { + return realSession.run(query, config); } @Override - public Result run(String query, Map parameters, TransactionConfig config ) - { - return realSession.run(query, parameters, config ); + public Result run(String query, Map parameters, TransactionConfig config) { + return realSession.run(query, parameters, config); } @Override - public Result run(Query query, TransactionConfig config ) - { - return realSession.run(query, config ); + public Result run(Query query, TransactionConfig config) { + return realSession.run(query, config); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/StdIOCapture.java b/driver/src/test/java/org/neo4j/driver/util/StdIOCapture.java index abe4241683..7494b7eba5 100644 --- a/driver/src/test/java/org/neo4j/driver/util/StdIOCapture.java +++ b/driver/src/test/java/org/neo4j/driver/util/StdIOCapture.java @@ -18,48 +18,43 @@ */ package org.neo4j.driver.util; +import static java.util.Arrays.asList; + import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import static java.util.Arrays.asList; - /** * Utility that can be used to temporarily capture and store process-wide stdout and stderr output. */ -public class StdIOCapture -{ +public class StdIOCapture { private final List stdout = new CopyOnWriteArrayList<>(); private final List stderr = new CopyOnWriteArrayList<>(); /** Put this in a try-with-resources block to capture all standard io that happens within the try block */ - public AutoCloseable capture() - { + public AutoCloseable capture() { final PrintStream originalStdOut = System.out; final PrintStream originalStdErr = System.err; final ByteArrayOutputStream capturedStdOut = new ByteArrayOutputStream(); final ByteArrayOutputStream capturedStdErr = new ByteArrayOutputStream(); - System.setOut( new PrintStream( capturedStdOut ) ); - System.setErr( new PrintStream( capturedStdErr ) ); + System.setOut(new PrintStream(capturedStdOut)); + System.setErr(new PrintStream(capturedStdErr)); - return () -> - { - System.setOut( originalStdOut ); - System.setErr( originalStdErr ); - stdout.addAll( asList( capturedStdOut.toString( "UTF-8" ).split( System.lineSeparator() ) ) ); - stderr.addAll( asList( capturedStdErr.toString( "UTF-8" ).split( System.lineSeparator() ) ) ); + return () -> { + System.setOut(originalStdOut); + System.setErr(originalStdErr); + stdout.addAll(asList(capturedStdOut.toString("UTF-8").split(System.lineSeparator()))); + stderr.addAll(asList(capturedStdErr.toString("UTF-8").split(System.lineSeparator()))); }; } - public List stdout() - { + public List stdout() { return stdout; } - public List stderr() - { + public List stderr() { return stderr; } } diff --git a/driver/src/test/java/org/neo4j/driver/util/TemporalUtil.java b/driver/src/test/java/org/neo4j/driver/util/TemporalUtil.java index 892fb34aad..c2cfa51904 100644 --- a/driver/src/test/java/org/neo4j/driver/util/TemporalUtil.java +++ b/driver/src/test/java/org/neo4j/driver/util/TemporalUtil.java @@ -18,6 +18,15 @@ */ package org.neo4j.driver.util; +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.NANO_OF_SECOND; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; +import static java.time.temporal.ChronoField.YEAR; +import static java.util.stream.Collectors.toSet; + import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -32,21 +41,10 @@ import java.util.List; import java.util.Set; import java.util.concurrent.ThreadLocalRandom; - import org.neo4j.driver.internal.InternalIsoDuration; import org.neo4j.driver.types.IsoDuration; -import static java.time.temporal.ChronoField.DAY_OF_MONTH; -import static java.time.temporal.ChronoField.HOUR_OF_DAY; -import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; -import static java.time.temporal.ChronoField.MONTH_OF_YEAR; -import static java.time.temporal.ChronoField.NANO_OF_SECOND; -import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; -import static java.time.temporal.ChronoField.YEAR; -import static java.util.stream.Collectors.toSet; - -public final class TemporalUtil -{ +public final class TemporalUtil { /** * A list of zone ids whose use might lead to unexpected results. *

@@ -60,110 +58,107 @@ public final class TemporalUtil "Africa/Casablanca", "tzid", "Asia/Qostanay", - "America/Santiago",// Can cause flakyness on windows, see https://stackoverflow.com/questions/37533796/java-calendar-returns-wrong-hour-in-ms-windows-for-america-santiago-zone. - "US/Pacific-New", // Appeared out of nowhere in windows, does not test reliable "org.neo4j.driver.exceptions.ClientException: Unable to construct ZonedDateTime value: `Unknown time-zone ID: US/Pacific-New`" - "Pacific/Easter" - ); + "America/Santiago", // Can cause flakyness on windows, see + // https://stackoverflow.com/questions/37533796/java-calendar-returns-wrong-hour-in-ms-windows-for-america-santiago-zone. + "US/Pacific-New", // Appeared out of nowhere in windows, does not test reliable + // "org.neo4j.driver.exceptions.ClientException: Unable to construct ZonedDateTime value: + // `Unknown time-zone ID: US/Pacific-New`" + "Pacific/Easter"); - private TemporalUtil() - { - } + private TemporalUtil() {} - public static LocalDate randomLocalDate() - { - return LocalDate.of( random( YEAR ), random( MONTH_OF_YEAR ), random( DAY_OF_MONTH ) ); + public static LocalDate randomLocalDate() { + return LocalDate.of(random(YEAR), random(MONTH_OF_YEAR), random(DAY_OF_MONTH)); } - public static OffsetTime randomOffsetTime() - { + public static OffsetTime randomOffsetTime() { ZoneOffset offset = randomZoneOffset(); - return OffsetTime.of( random( HOUR_OF_DAY ), random( MINUTE_OF_HOUR ), random( SECOND_OF_MINUTE ), random( NANO_OF_SECOND ), offset ); + return OffsetTime.of( + random(HOUR_OF_DAY), random(MINUTE_OF_HOUR), random(SECOND_OF_MINUTE), random(NANO_OF_SECOND), offset); } - public static LocalTime randomLocalTime() - { - return LocalTime.of( random( HOUR_OF_DAY ), random( MINUTE_OF_HOUR ), random( SECOND_OF_MINUTE ), random( NANO_OF_SECOND ) ); + public static LocalTime randomLocalTime() { + return LocalTime.of( + random(HOUR_OF_DAY), random(MINUTE_OF_HOUR), random(SECOND_OF_MINUTE), random(NANO_OF_SECOND)); } - public static LocalDateTime randomLocalDateTime() - { - return LocalDateTime.of( random( YEAR ), random( MONTH_OF_YEAR ), random( DAY_OF_MONTH ), random( HOUR_OF_DAY ), - random( MINUTE_OF_HOUR ), random( SECOND_OF_MINUTE ), random( NANO_OF_SECOND ) ); + public static LocalDateTime randomLocalDateTime() { + return LocalDateTime.of( + random(YEAR), + random(MONTH_OF_YEAR), + random(DAY_OF_MONTH), + random(HOUR_OF_DAY), + random(MINUTE_OF_HOUR), + random(SECOND_OF_MINUTE), + random(NANO_OF_SECOND)); } - public static OffsetDateTime randomOffsetDateTime() - { + public static OffsetDateTime randomOffsetDateTime() { return randomZonedDateTimeWithOffset().toOffsetDateTime(); } - public static ZonedDateTime randomZonedDateTimeWithOffset() - { - return randomZonedDateTime( randomZoneOffset() ); + public static ZonedDateTime randomZonedDateTimeWithOffset() { + return randomZonedDateTime(randomZoneOffset()); } - public static ZonedDateTime randomZonedDateTimeWithZoneId() - { - return randomZonedDateTime( randomZoneId() ); + public static ZonedDateTime randomZonedDateTimeWithZoneId() { + return randomZonedDateTime(randomZoneId()); } - public static IsoDuration randomDuration() - { + public static IsoDuration randomDuration() { int sign = random().nextBoolean() ? 1 : -1; // duration can be negative - return new InternalIsoDuration( sign * randomInt(), sign * randomInt(), sign * randomInt(), Math.abs( random( NANO_OF_SECOND ) ) ); + return new InternalIsoDuration( + sign * randomInt(), sign * randomInt(), sign * randomInt(), Math.abs(random(NANO_OF_SECOND))); } - private static ZonedDateTime randomZonedDateTime( ZoneId zoneId ) - { - return ZonedDateTime.of( random( YEAR ), random( MONTH_OF_YEAR ), random( DAY_OF_MONTH ), random( HOUR_OF_DAY ), - random( MINUTE_OF_HOUR ), random( SECOND_OF_MINUTE ), random( NANO_OF_SECOND ), zoneId ); + private static ZonedDateTime randomZonedDateTime(ZoneId zoneId) { + return ZonedDateTime.of( + random(YEAR), + random(MONTH_OF_YEAR), + random(DAY_OF_MONTH), + random(HOUR_OF_DAY), + random(MINUTE_OF_HOUR), + random(SECOND_OF_MINUTE), + random(NANO_OF_SECOND), + zoneId); } - private static ZoneOffset randomZoneOffset() - { + private static ZoneOffset randomZoneOffset() { int min = ZoneOffset.MIN.getTotalSeconds(); int max = ZoneOffset.MAX.getTotalSeconds(); - return ZoneOffset.ofTotalSeconds( random().nextInt( min, max ) ); + return ZoneOffset.ofTotalSeconds(random().nextInt(min, max)); } - private static ZoneId randomZoneId() - { - Set availableZoneIds = ZoneId.getAvailableZoneIds() - .stream() - .filter( id -> !EXCLUDED_ZONE_IDS.contains( id ) ) - .collect( toSet() ); + private static ZoneId randomZoneId() { + Set availableZoneIds = ZoneId.getAvailableZoneIds().stream() + .filter(id -> !EXCLUDED_ZONE_IDS.contains(id)) + .collect(toSet()); - int randomIndex = random().nextInt( availableZoneIds.size() ); + int randomIndex = random().nextInt(availableZoneIds.size()); int index = 0; - for ( String id : availableZoneIds ) - { - if ( index == randomIndex ) - { - return ZoneId.of( id ); - } - else - { + for (String id : availableZoneIds) { + if (index == randomIndex) { + return ZoneId.of(id); + } else { index++; } } - throw new AssertionError( "Unable to pick random ZoneId from the set of available ids: " + availableZoneIds ); + throw new AssertionError("Unable to pick random ZoneId from the set of available ids: " + availableZoneIds); } - private static int random( ChronoField field ) - { + private static int random(ChronoField field) { ValueRange range = field.range(); long min = range.getMinimum(); long max = range.getSmallestMaximum(); - long value = random().nextLong( min, max ); - return Math.toIntExact( value ); + long value = random().nextLong(min, max); + return Math.toIntExact(value); } - private static int randomInt() - { - return random().nextInt( 0, Integer.MAX_VALUE ); + private static int randomInt() { + return random().nextInt(0, Integer.MAX_VALUE); } - private static ThreadLocalRandom random() - { + private static ThreadLocalRandom random() { return ThreadLocalRandom.current(); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/TestUtil.java b/driver/src/test/java/org/neo4j/driver/util/TestUtil.java index a8270fe450..1170e2a3d5 100644 --- a/driver/src/test/java/org/neo4j/driver/util/TestUtil.java +++ b/driver/src/test/java/org/neo4j/driver/util/TestUtil.java @@ -18,16 +18,32 @@ */ package org.neo4j.driver.util; +import static java.util.Collections.emptyMap; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +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.neo4j.driver.AccessMode.WRITE; +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.SessionConfig.forDatabase; +import static org.neo4j.driver.internal.DatabaseNameUtil.database; +import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.driver.internal.InternalBookmark.empty; +import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.util.Futures.completedWithNull; + import io.netty.buffer.ByteBuf; import io.netty.util.internal.PlatformDependent; -import org.mockito.ArgumentMatcher; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.mockito.verification.VerificationMode; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -51,7 +67,10 @@ import java.util.concurrent.TimeoutException; import java.util.function.BooleanSupplier; import java.util.function.Predicate; - +import org.mockito.ArgumentMatcher; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.mockito.verification.VerificationMode; import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Driver; @@ -84,706 +103,559 @@ import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.internal.util.FixedRetryLogic; import org.neo4j.driver.internal.util.ServerVersion; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -import static java.util.Collections.emptyMap; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.MINUTES; -import static java.util.stream.Collectors.toList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -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.neo4j.driver.AccessMode.WRITE; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.SessionConfig.forDatabase; -import static org.neo4j.driver.internal.DatabaseNameUtil.database; -import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase; -import static org.neo4j.driver.internal.InternalBookmark.empty; -import static org.neo4j.driver.internal.handlers.pulln.FetchSizeUtil.UNLIMITED_FETCH_SIZE; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.util.Futures.completedWithNull; - -public final class TestUtil -{ +public final class TestUtil { public static final BoltProtocolVersion DEFAULT_TEST_PROTOCOL_VERSION = BoltProtocolV4.VERSION; - public static final BoltProtocol DEFAULT_TEST_PROTOCOL = BoltProtocol.forVersion( DEFAULT_TEST_PROTOCOL_VERSION ); + public static final BoltProtocol DEFAULT_TEST_PROTOCOL = BoltProtocol.forVersion(DEFAULT_TEST_PROTOCOL_VERSION); - private static final long DEFAULT_WAIT_TIME_MS = MINUTES.toMillis( 2 ); + private static final long DEFAULT_WAIT_TIME_MS = MINUTES.toMillis(2); private static final String ALPHANUMERICS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789"; - public static final Duration TX_TIMEOUT_TEST_TIMEOUT = Duration.ofSeconds( 10 ); + public static final Duration TX_TIMEOUT_TEST_TIMEOUT = Duration.ofSeconds(10); - private TestUtil() - { - } + private TestUtil() {} - public static List await( Publisher publisher ) - { - return await( Flux.from( publisher ) ); + public static List await(Publisher publisher) { + return await(Flux.from(publisher)); } - public static T await( Mono publisher ) - { + public static T await(Mono publisher) { EventLoopGroupFactory.assertNotInEventLoopThread(); - return publisher.block( Duration.ofMillis( DEFAULT_WAIT_TIME_MS ) ); + return publisher.block(Duration.ofMillis(DEFAULT_WAIT_TIME_MS)); } - public static List await( Flux publisher ) - { + public static List await(Flux publisher) { EventLoopGroupFactory.assertNotInEventLoopThread(); - return publisher.collectList().block( Duration.ofMillis( DEFAULT_WAIT_TIME_MS ) ); + return publisher.collectList().block(Duration.ofMillis(DEFAULT_WAIT_TIME_MS)); } @SafeVarargs - public static List awaitAll( CompletionStage... stages ) - { - return awaitAll( Arrays.asList( stages ) ); + public static List awaitAll(CompletionStage... stages) { + return awaitAll(Arrays.asList(stages)); } - public static List awaitAll( List> stages ) - { - return stages.stream().map( TestUtil::await ).collect( toList() ); + public static List awaitAll(List> stages) { + return stages.stream().map(TestUtil::await).collect(toList()); } - public static T await( CompletionStage stage ) - { - return await( (Future) stage.toCompletableFuture() ); + public static T await(CompletionStage stage) { + return await((Future) stage.toCompletableFuture()); } - public static T await( CompletableFuture future ) - { - return await( (Future) future ); + public static T await(CompletableFuture future) { + return await((Future) future); } - public static void awaitAllFutures( List> futures ) - { - for ( Future future : futures ) - { - await( future ); + public static void awaitAllFutures(List> futures) { + for (Future future : futures) { + await(future); } } - public static > T await( U future ) - { - try - { - return future.get( DEFAULT_WAIT_TIME_MS, MILLISECONDS ); - } - catch ( InterruptedException e ) - { + public static > T await(U future) { + try { + return future.get(DEFAULT_WAIT_TIME_MS, MILLISECONDS); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new AssertionError( "Interrupted while waiting for future: " + future, e ); - } - catch ( ExecutionException e ) - { - PlatformDependent.throwException( e.getCause() ); + throw new AssertionError("Interrupted while waiting for future: " + future, e); + } catch (ExecutionException e) { + PlatformDependent.throwException(e.getCause()); return null; - } - catch ( TimeoutException e ) - { - throw new AssertionError( "Given future did not complete in time: " + future ); + } catch (TimeoutException e) { + throw new AssertionError("Given future did not complete in time: " + future); } } - public static void assertByteBufContains( ByteBuf buf, Number... values ) - { - try - { - assertNotNull( buf ); + public static void assertByteBufContains(ByteBuf buf, Number... values) { + try { + assertNotNull(buf); int expectedReadableBytes = 0; - for ( Number value : values ) - { - expectedReadableBytes += bytesCount( value ); + for (Number value : values) { + expectedReadableBytes += bytesCount(value); } - assertEquals( expectedReadableBytes, buf.readableBytes(), "Unexpected number of bytes" ); - for ( Number expectedValue : values ) - { - Number actualValue = read( buf, expectedValue.getClass() ); + assertEquals(expectedReadableBytes, buf.readableBytes(), "Unexpected number of bytes"); + for (Number expectedValue : values) { + Number actualValue = read(buf, expectedValue.getClass()); String valueType = actualValue.getClass().getSimpleName(); - assertEquals( expectedValue, actualValue, valueType + " values not equal" ); + assertEquals(expectedValue, actualValue, valueType + " values not equal"); } - } - finally - { - releaseIfPossible( buf ); + } finally { + releaseIfPossible(buf); } } - public static void assertByteBufEquals( ByteBuf expected, ByteBuf actual ) - { - try - { - assertEquals( expected, actual ); - } - finally - { - releaseIfPossible( expected ); - releaseIfPossible( actual ); + public static void assertByteBufEquals(ByteBuf expected, ByteBuf actual) { + try { + assertEquals(expected, actual); + } finally { + releaseIfPossible(expected); + releaseIfPossible(actual); } } @SafeVarargs - public static Set asOrderedSet( T... elements ) - { - return new LinkedHashSet<>( Arrays.asList( elements ) ); + public static Set asOrderedSet(T... elements) { + return new LinkedHashSet<>(Arrays.asList(elements)); } @SafeVarargs - public static Set asSet( T... elements ) - { - return new HashSet<>( Arrays.asList( elements ) ); + public static Set asSet(T... elements) { + return new HashSet<>(Arrays.asList(elements)); } - public static long countNodes( Driver driver, Bookmark bookmark ) - { - try ( Session session = driver.session( builder().withBookmarks( bookmark ).build() ) ) - { - return session.readTransaction( tx -> tx.run( "MATCH (n) RETURN count(n)" ).single().get( 0 ).asLong() ); + public static long countNodes(Driver driver, Bookmark bookmark) { + try (Session session = driver.session(builder().withBookmarks(bookmark).build())) { + return session.readTransaction( + tx -> tx.run("MATCH (n) RETURN count(n)").single().get(0).asLong()); } } - public static Bookmark cleanDb( Driver driver ) - { - try ( Session session = driver.session() ) - { - cleanDb( session ); + public static Bookmark cleanDb(Driver driver) { + try (Session session = driver.session()) { + cleanDb(session); return session.lastBookmark(); } } - public static void dropDatabase( Driver driver, String database ) - { - boolean databaseExists = databaseExists( driver, database ); - if ( !databaseExists ) - { + public static void dropDatabase(Driver driver, String database) { + boolean databaseExists = databaseExists(driver, database); + if (!databaseExists) { return; } - try ( Session session = driver.session( forDatabase( "system" ) ) ) - { - session.run( "DROP DATABASE " + database ).consume(); + try (Session session = driver.session(forDatabase("system"))) { + session.run("DROP DATABASE " + database).consume(); } } - public static void createDatabase( Driver driver, String database ) - { - boolean databaseExists = databaseExists( driver, database ); - if ( databaseExists ) - { + public static void createDatabase(Driver driver, String database) { + boolean databaseExists = databaseExists(driver, database); + if (databaseExists) { return; } - try ( Session session = driver.session( SessionConfig.forDatabase( "system" ) ) ) - { - session.run( "CREATE DATABASE " + database ).consume(); + try (Session session = driver.session(SessionConfig.forDatabase("system"))) { + session.run("CREATE DATABASE " + database).consume(); } } - public static boolean databaseExists( Driver driver, String database ) - { - try ( Session session = driver.session( forDatabase( "system" ) ) ) - { - // No procedure equivalent and `call dbms.database.state("db")` also throws an exception when db doesn't exist - return session.run( "SHOW DATABASES" ).stream().anyMatch( r -> r.get( "name" ).asString().equals( database ) ); + public static boolean databaseExists(Driver driver, String database) { + try (Session session = driver.session(forDatabase("system"))) { + // No procedure equivalent and `call dbms.database.state("db")` also throws an exception when db doesn't + // exist + return session.run("SHOW DATABASES").stream() + .anyMatch(r -> r.get("name").asString().equals(database)); } } - public static NetworkSession newSession( ConnectionProvider connectionProvider, Bookmark x ) - { - return newSession( connectionProvider, WRITE, x ); + public static NetworkSession newSession(ConnectionProvider connectionProvider, Bookmark x) { + return newSession(connectionProvider, WRITE, x); } - private static NetworkSession newSession( ConnectionProvider connectionProvider, AccessMode mode, Bookmark x ) - { - return newSession( connectionProvider, mode, new FixedRetryLogic( 0 ), x ); + private static NetworkSession newSession(ConnectionProvider connectionProvider, AccessMode mode, Bookmark x) { + return newSession(connectionProvider, mode, new FixedRetryLogic(0), x); } - public static NetworkSession newSession( ConnectionProvider connectionProvider, AccessMode mode ) - { - return newSession( connectionProvider, mode, empty() ); + public static NetworkSession newSession(ConnectionProvider connectionProvider, AccessMode mode) { + return newSession(connectionProvider, mode, empty()); } - public static NetworkSession newSession( ConnectionProvider connectionProvider, RetryLogic logic ) - { - return newSession( connectionProvider, WRITE, logic, empty() ); + public static NetworkSession newSession(ConnectionProvider connectionProvider, RetryLogic logic) { + return newSession(connectionProvider, WRITE, logic, empty()); } - public static NetworkSession newSession( ConnectionProvider connectionProvider ) - { - return newSession( connectionProvider, WRITE, empty() ); + public static NetworkSession newSession(ConnectionProvider connectionProvider) { + return newSession(connectionProvider, WRITE, empty()); } - public static NetworkSession newSession( ConnectionProvider connectionProvider, AccessMode mode, - RetryLogic retryLogic, Bookmark bookmark ) - { - return new NetworkSession( connectionProvider, retryLogic, defaultDatabase(), mode, new DefaultBookmarkHolder( bookmark ), null, UNLIMITED_FETCH_SIZE, - DEV_NULL_LOGGING ); + public static NetworkSession newSession( + ConnectionProvider connectionProvider, AccessMode mode, RetryLogic retryLogic, Bookmark bookmark) { + return new NetworkSession( + connectionProvider, + retryLogic, + defaultDatabase(), + mode, + new DefaultBookmarkHolder(bookmark), + null, + UNLIMITED_FETCH_SIZE, + DEV_NULL_LOGGING); } - public static void verifyRunRx( Connection connection, String query ) - { - verify( connection ).writeAndFlush( argThat( runWithMetaMessageWithQueryMatcher( query ) ), any() ); + public static void verifyRunRx(Connection connection, String query) { + verify(connection).writeAndFlush(argThat(runWithMetaMessageWithQueryMatcher(query)), any()); } - public static void verifyRunAndPull( Connection connection, String query ) - { - verify( connection ).write( argThat( runWithMetaMessageWithQueryMatcher( query ) ), any() ); - verify( connection ).writeAndFlush( any( PullMessage.class ), any() ); + public static void verifyRunAndPull(Connection connection, String query) { + verify(connection).write(argThat(runWithMetaMessageWithQueryMatcher(query)), any()); + verify(connection).writeAndFlush(any(PullMessage.class), any()); } - public static void verifyCommitTx( Connection connection, VerificationMode mode ) - { - verify( connection, mode ).writeAndFlush( any( CommitMessage.class ), any() ); + public static void verifyCommitTx(Connection connection, VerificationMode mode) { + verify(connection, mode).writeAndFlush(any(CommitMessage.class), any()); } - public static void verifyCommitTx( Connection connection ) - { - verifyCommitTx( connection, times( 1 ) ); + public static void verifyCommitTx(Connection connection) { + verifyCommitTx(connection, times(1)); } - public static void verifyRollbackTx( Connection connection, VerificationMode mode ) - { - verify( connection, mode ).writeAndFlush( any( RollbackMessage.class ), any() ); + public static void verifyRollbackTx(Connection connection, VerificationMode mode) { + verify(connection, mode).writeAndFlush(any(RollbackMessage.class), any()); } - public static void verifyRollbackTx( Connection connection ) - { - verifyRollbackTx( connection, times( 1 ) ); + public static void verifyRollbackTx(Connection connection) { + verifyRollbackTx(connection, times(1)); } - public static void verifyBeginTx( Connection connectionMock ) - { - verifyBeginTx( connectionMock, 1 ); + public static void verifyBeginTx(Connection connectionMock) { + verifyBeginTx(connectionMock, 1); } - public static void verifyBeginTx( Connection connectionMock, int times ) - { - verify( connectionMock, times( times ) ).writeAndFlush( any( BeginMessage.class ), any( BeginTxResponseHandler.class ) ); + public static void verifyBeginTx(Connection connectionMock, int times) { + verify(connectionMock, times(times)).writeAndFlush(any(BeginMessage.class), any(BeginTxResponseHandler.class)); } - public static void setupFailingRun( Connection connection, Throwable error ) - { - doAnswer( invocation -> - { - ResponseHandler runHandler = invocation.getArgument( 1 ); - runHandler.onFailure( error ); - return null; - } ).when( connection ).write( any( RunWithMetadataMessage.class ), any() ); + public static void setupFailingRun(Connection connection, Throwable error) { + doAnswer(invocation -> { + ResponseHandler runHandler = invocation.getArgument(1); + runHandler.onFailure(error); + return null; + }) + .when(connection) + .write(any(RunWithMetadataMessage.class), any()); - doAnswer( invocation -> - { - ResponseHandler pullHandler = invocation.getArgument( 1 ); - pullHandler.onFailure( error ); - return null; - } ).when( connection ).writeAndFlush( any( PullMessage.class ), any() ); + doAnswer(invocation -> { + ResponseHandler pullHandler = invocation.getArgument(1); + pullHandler.onFailure(error); + return null; + }) + .when(connection) + .writeAndFlush(any(PullMessage.class), any()); } - public static void setupFailingBegin( Connection connection, Throwable error ) - { + public static void setupFailingBegin(Connection connection, Throwable error) { // with bookmarks - doAnswer( invocation -> - { - ResponseHandler handler = invocation.getArgument( 1 ); - handler.onFailure( error ); - return null; - } ).when( connection ).writeAndFlush( any( BeginMessage.class ), any( BeginTxResponseHandler.class ) ); - } - - public static void setupFailingCommit( Connection connection ) - { - setupFailingCommit( connection, 1 ); - } - - public static void setupFailingCommit( Connection connection, int times ) - { - doAnswer( new Answer() - { - int invoked; - - @Override - public Void answer( InvocationOnMock invocation ) - { - ResponseHandler handler = invocation.getArgument( 1 ); - if ( invoked++ < times ) - { - handler.onFailure( new ServiceUnavailableException( "" ) ); - } - else - { - handler.onSuccess( emptyMap() ); - } - return null; - } - } ).when( connection ).writeAndFlush( any( CommitMessage.class ), any() ); - } - - public static void setupFailingRollback( Connection connection ) - { - setupFailingRollback( connection, 1 ); - } - - public static void setupFailingRollback( Connection connection, int times ) - { - doAnswer( new Answer() - { - int invoked; - - @Override - public Void answer( InvocationOnMock invocation ) - { - ResponseHandler handler = invocation.getArgument( 1 ); - if ( invoked++ < times ) - { - handler.onFailure( new ServiceUnavailableException( "" ) ); - } - else - { - handler.onSuccess( emptyMap() ); - } - return null; - } - } ).when( connection ).writeAndFlush( any( RollbackMessage.class ), any() ); - } - - public static void setupSuccessfulRunAndPull( Connection connection ) - { - doAnswer( invocation -> - { - ResponseHandler runHandler = invocation.getArgument( 1 ); - runHandler.onSuccess( emptyMap() ); - return null; - } ).when( connection ).write( any( RunWithMetadataMessage.class ), any() ); - - doAnswer( invocation -> - { - ResponseHandler pullHandler = invocation.getArgument( 1 ); - pullHandler.onSuccess( emptyMap() ); - return null; - } ).when( connection ).writeAndFlush( any( PullMessage.class ), any() ); - } - - public static void setupSuccessfulRunRx( Connection connection ) - { - doAnswer( invocation -> - { - ResponseHandler runHandler = invocation.getArgument( 1 ); - runHandler.onSuccess( emptyMap() ); - return null; - } ).when( connection ).writeAndFlush( any( RunWithMetadataMessage.class ), any() ); - } - - public static void setupSuccessfulRunAndPull( Connection connection, String query ) - { - doAnswer( invocation -> - { - ResponseHandler runHandler = invocation.getArgument( 1 ); - runHandler.onSuccess( emptyMap() ); - return null; - } ).when( connection ).write( argThat( runWithMetaMessageWithQueryMatcher( query ) ), any() ); - - doAnswer( invocation -> - { - ResponseHandler pullHandler = invocation.getArgument( 1 ); - pullHandler.onSuccess( emptyMap() ); - return null; - } ).when( connection ).writeAndFlush( any( PullMessage.class ), any() ); - } - - public static Connection connectionMock() - { - return connectionMock( BoltProtocolV42.INSTANCE ); - } - - public static Connection connectionMock( BoltProtocol protocol ) - { - return connectionMock( WRITE, protocol ); - } - - public static Connection connectionMock( AccessMode mode, BoltProtocol protocol ) - { - return connectionMock( null, mode, protocol ); - } - - public static Connection connectionMock( String databaseName, BoltProtocol protocol ) - { - return connectionMock( databaseName, WRITE, protocol ); - } - - public static Connection connectionMock( String databaseName, AccessMode mode, BoltProtocol protocol ) - { - Connection connection = mock( Connection.class ); - when( connection.serverAddress() ).thenReturn( BoltServerAddress.LOCAL_DEFAULT ); - when( connection.serverVersion() ).thenReturn( ServerVersion.vInDev ); - when( connection.protocol() ).thenReturn( protocol ); - when( connection.mode() ).thenReturn( mode ); - when( connection.databaseName() ).thenReturn( database( databaseName ) ); + doAnswer(invocation -> { + ResponseHandler handler = invocation.getArgument(1); + handler.onFailure(error); + return null; + }) + .when(connection) + .writeAndFlush(any(BeginMessage.class), any(BeginTxResponseHandler.class)); + } + + public static void setupFailingCommit(Connection connection) { + setupFailingCommit(connection, 1); + } + + public static void setupFailingCommit(Connection connection, int times) { + doAnswer(new Answer() { + int invoked; + + @Override + public Void answer(InvocationOnMock invocation) { + ResponseHandler handler = invocation.getArgument(1); + if (invoked++ < times) { + handler.onFailure(new ServiceUnavailableException("")); + } else { + handler.onSuccess(emptyMap()); + } + return null; + } + }) + .when(connection) + .writeAndFlush(any(CommitMessage.class), any()); + } + + public static void setupFailingRollback(Connection connection) { + setupFailingRollback(connection, 1); + } + + public static void setupFailingRollback(Connection connection, int times) { + doAnswer(new Answer() { + int invoked; + + @Override + public Void answer(InvocationOnMock invocation) { + ResponseHandler handler = invocation.getArgument(1); + if (invoked++ < times) { + handler.onFailure(new ServiceUnavailableException("")); + } else { + handler.onSuccess(emptyMap()); + } + return null; + } + }) + .when(connection) + .writeAndFlush(any(RollbackMessage.class), any()); + } + + public static void setupSuccessfulRunAndPull(Connection connection) { + doAnswer(invocation -> { + ResponseHandler runHandler = invocation.getArgument(1); + runHandler.onSuccess(emptyMap()); + return null; + }) + .when(connection) + .write(any(RunWithMetadataMessage.class), any()); + + doAnswer(invocation -> { + ResponseHandler pullHandler = invocation.getArgument(1); + pullHandler.onSuccess(emptyMap()); + return null; + }) + .when(connection) + .writeAndFlush(any(PullMessage.class), any()); + } + + public static void setupSuccessfulRunRx(Connection connection) { + doAnswer(invocation -> { + ResponseHandler runHandler = invocation.getArgument(1); + runHandler.onSuccess(emptyMap()); + return null; + }) + .when(connection) + .writeAndFlush(any(RunWithMetadataMessage.class), any()); + } + + public static void setupSuccessfulRunAndPull(Connection connection, String query) { + doAnswer(invocation -> { + ResponseHandler runHandler = invocation.getArgument(1); + runHandler.onSuccess(emptyMap()); + return null; + }) + .when(connection) + .write(argThat(runWithMetaMessageWithQueryMatcher(query)), any()); + + doAnswer(invocation -> { + ResponseHandler pullHandler = invocation.getArgument(1); + pullHandler.onSuccess(emptyMap()); + return null; + }) + .when(connection) + .writeAndFlush(any(PullMessage.class), any()); + } + + public static Connection connectionMock() { + return connectionMock(BoltProtocolV42.INSTANCE); + } + + public static Connection connectionMock(BoltProtocol protocol) { + return connectionMock(WRITE, protocol); + } + + public static Connection connectionMock(AccessMode mode, BoltProtocol protocol) { + return connectionMock(null, mode, protocol); + } + + public static Connection connectionMock(String databaseName, BoltProtocol protocol) { + return connectionMock(databaseName, WRITE, protocol); + } + + public static Connection connectionMock(String databaseName, AccessMode mode, BoltProtocol protocol) { + Connection connection = mock(Connection.class); + when(connection.serverAddress()).thenReturn(BoltServerAddress.LOCAL_DEFAULT); + when(connection.serverVersion()).thenReturn(ServerVersion.vInDev); + when(connection.protocol()).thenReturn(protocol); + when(connection.mode()).thenReturn(mode); + when(connection.databaseName()).thenReturn(database(databaseName)); BoltProtocolVersion version = protocol.version(); - if ( version.equals( BoltProtocolV3.VERSION ) || version.equals( BoltProtocolV4.VERSION ) || - version.equals( BoltProtocolV41.VERSION ) || version.equals( BoltProtocolV42.VERSION ) || - version.equals( BoltProtocolV43.VERSION ) || version.equals( BoltProtocolV44.VERSION ) ) - { - setupSuccessResponse( connection, CommitMessage.class ); - setupSuccessResponse( connection, RollbackMessage.class ); - setupSuccessResponse( connection, BeginMessage.class ); - when( connection.release() ).thenReturn( completedWithNull() ); - when( connection.reset() ).thenReturn( completedWithNull() ); - } - else - { - throw new IllegalArgumentException( "Unsupported bolt protocol version: " + version ); + if (version.equals(BoltProtocolV3.VERSION) + || version.equals(BoltProtocolV4.VERSION) + || version.equals(BoltProtocolV41.VERSION) + || version.equals(BoltProtocolV42.VERSION) + || version.equals(BoltProtocolV43.VERSION) + || version.equals(BoltProtocolV44.VERSION)) { + setupSuccessResponse(connection, CommitMessage.class); + setupSuccessResponse(connection, RollbackMessage.class); + setupSuccessResponse(connection, BeginMessage.class); + when(connection.release()).thenReturn(completedWithNull()); + when(connection.reset()).thenReturn(completedWithNull()); + } else { + throw new IllegalArgumentException("Unsupported bolt protocol version: " + version); } return connection; } - public static void sleep( int millis ) - { - try - { - Thread.sleep( millis ); - } - catch ( InterruptedException e ) - { + public static void sleep(int millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException( e ); + throw new RuntimeException(e); } } - public static void interruptWhenInWaitingState( Thread thread ) - { - CompletableFuture.runAsync( () -> - { + public static void interruptWhenInWaitingState(Thread thread) { + CompletableFuture.runAsync(() -> { // spin until given thread moves to WAITING state - do - { - sleep( 500 ); - } - while ( thread.getState() != Thread.State.WAITING ); + do { + sleep(500); + } while (thread.getState() != Thread.State.WAITING); thread.interrupt(); - } ); + }); } - public static int activeQueryCount( Driver driver ) - { - return activeQueryNames( driver ).size(); + public static int activeQueryCount(Driver driver) { + return activeQueryNames(driver).size(); } - public static List activeQueryNames( Driver driver ) - { - try ( Session session = driver.session() ) - { - return session.run( "CALL dbms.listQueries() YIELD query RETURN query" ) - .list() - .stream() - .map( record -> record.get( 0 ).asString() ) - .filter( query -> !query.contains( "dbms.listQueries" ) ) // do not include listQueries procedure - .collect( toList() ); + public static List activeQueryNames(Driver driver) { + try (Session session = driver.session()) { + return session.run("CALL dbms.listQueries() YIELD query RETURN query").list().stream() + .map(record -> record.get(0).asString()) + .filter(query -> !query.contains("dbms.listQueries")) // do not include listQueries procedure + .collect(toList()); } } - public static void awaitCondition( BooleanSupplier condition ) - { - awaitCondition( condition, DEFAULT_WAIT_TIME_MS, MILLISECONDS ); + public static void awaitCondition(BooleanSupplier condition) { + awaitCondition(condition, DEFAULT_WAIT_TIME_MS, MILLISECONDS); } - public static void awaitCondition( BooleanSupplier condition, long value, TimeUnit unit ) - { - long deadline = System.currentTimeMillis() + unit.toMillis( value ); - while ( !condition.getAsBoolean() ) - { - if ( System.currentTimeMillis() > deadline ) - { - fail( "Condition was not met in time" ); - } - try - { - MILLISECONDS.sleep( 100 ); + public static void awaitCondition(BooleanSupplier condition, long value, TimeUnit unit) { + long deadline = System.currentTimeMillis() + unit.toMillis(value); + while (!condition.getAsBoolean()) { + if (System.currentTimeMillis() > deadline) { + fail("Condition was not met in time"); } - catch ( InterruptedException e ) - { + try { + MILLISECONDS.sleep(100); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - fail( "Interrupted while waiting" ); + fail("Interrupted while waiting"); } } } - public static String randomString( int size ) - { - StringBuilder sb = new StringBuilder( size ); + public static String randomString(int size) { + StringBuilder sb = new StringBuilder(size); ThreadLocalRandom random = ThreadLocalRandom.current(); - for ( int i = 0; i < size; i++ ) - { - sb.append( ALPHANUMERICS.charAt( random.nextInt( ALPHANUMERICS.length() ) ) ); + for (int i = 0; i < size; i++) { + sb.append(ALPHANUMERICS.charAt(random.nextInt(ALPHANUMERICS.length()))); } return sb.toString(); } - public static ArgumentMatcher runWithMetaMessageWithQueryMatcher( String query ) - { - return message -> message instanceof RunWithMetadataMessage && Objects.equals( query, ((RunWithMetadataMessage) message).query() ); + public static ArgumentMatcher runWithMetaMessageWithQueryMatcher(String query) { + return message -> message instanceof RunWithMetadataMessage + && Objects.equals(query, ((RunWithMetadataMessage) message).query()); } - public static ArgumentMatcher beginMessage() - { - return beginMessageWithPredicate( ignored -> true ); + public static ArgumentMatcher beginMessage() { + return beginMessageWithPredicate(ignored -> true); } - public static ArgumentMatcher beginMessageWithPredicate( Predicate predicate ) - { - return message -> message instanceof BeginMessage && predicate.test( (BeginMessage) message ); + public static ArgumentMatcher beginMessageWithPredicate(Predicate predicate) { + return message -> message instanceof BeginMessage && predicate.test((BeginMessage) message); } /** * Used in tests that expect a server version but the tests do not depend on server version to behave differently. */ - public static ServerVersion anyServerVersion() - { + public static ServerVersion anyServerVersion() { return ServerVersion.v4_0_0; } - public static void assertNoCircularReferences(Throwable ex) - { - assertNoCircularReferences( ex, new ArrayList<>() ); + public static void assertNoCircularReferences(Throwable ex) { + assertNoCircularReferences(ex, new ArrayList<>()); } - private static void assertNoCircularReferences(Throwable ex, List list) - { - list.add( ex ); - if (ex.getCause() != null ) { - if (list.contains( ex.getCause() )) { + private static void assertNoCircularReferences(Throwable ex, List list) { + list.add(ex); + if (ex.getCause() != null) { + if (list.contains(ex.getCause())) { throw new AssertionError("Circular reference detected", ex.getCause()); } assertNoCircularReferences(ex.getCause(), list); } - for ( Throwable suppressed: ex.getSuppressed() ) - { - if(list.contains( suppressed )) { + for (Throwable suppressed : ex.getSuppressed()) { + if (list.contains(suppressed)) { throw new AssertionError("Circular reference detected", suppressed); } - assertNoCircularReferences( suppressed, list ); + assertNoCircularReferences(suppressed, list); } } - private static void setupSuccessResponse( Connection connection, Class messageType ) - { - doAnswer( invocation -> - { - ResponseHandler handler = invocation.getArgument( 1 ); - handler.onSuccess( emptyMap() ); - return null; - } ).when( connection ).writeAndFlush( any( messageType ), any() ); + private static void setupSuccessResponse(Connection connection, Class messageType) { + doAnswer(invocation -> { + ResponseHandler handler = invocation.getArgument(1); + handler.onSuccess(emptyMap()); + return null; + }) + .when(connection) + .writeAndFlush(any(messageType), any()); } - private static void cleanDb( Session session ) - { + private static void cleanDb(Session session) { int nodesDeleted; - do - { - nodesDeleted = deleteBatchOfNodes( session ); - } - while ( nodesDeleted > 0 ); + do { + nodesDeleted = deleteBatchOfNodes(session); + } while (nodesDeleted > 0); } - private static int deleteBatchOfNodes( Session session ) - { - return session.writeTransaction( tx -> - { - Result result = tx.run( "MATCH (n) WITH n LIMIT 1000 DETACH DELETE n RETURN count(n)" ); - return result.single().get( 0 ).asInt(); - } ); + private static int deleteBatchOfNodes(Session session) { + return session.writeTransaction(tx -> { + Result result = tx.run("MATCH (n) WITH n LIMIT 1000 DETACH DELETE n RETURN count(n)"); + return result.single().get(0).asInt(); + }); } - private static Number read( ByteBuf buf, Class type ) - { - if ( type == Byte.class ) - { + private static Number read(ByteBuf buf, Class type) { + if (type == Byte.class) { return buf.readByte(); - } - else if ( type == Short.class ) - { + } else if (type == Short.class) { return buf.readShort(); - } - else if ( type == Integer.class ) - { + } else if (type == Integer.class) { return buf.readInt(); - } - else if ( type == Long.class ) - { + } else if (type == Long.class) { return buf.readLong(); - } - else if ( type == Float.class ) - { + } else if (type == Float.class) { return buf.readFloat(); - } - else if ( type == Double.class ) - { + } else if (type == Double.class) { return buf.readDouble(); - } - else - { - throw new IllegalArgumentException( "Unexpected numeric type: " + type ); + } else { + throw new IllegalArgumentException("Unexpected numeric type: " + type); } } - private static int bytesCount( Number value ) - { - if ( value instanceof Byte ) - { + private static int bytesCount(Number value) { + if (value instanceof Byte) { return 1; - } - else if ( value instanceof Short ) - { + } else if (value instanceof Short) { return 2; - } - else if ( value instanceof Integer ) - { + } else if (value instanceof Integer) { return 4; - } - else if ( value instanceof Long ) - { + } else if (value instanceof Long) { return 8; - } - else if ( value instanceof Float ) - { + } else if (value instanceof Float) { return 4; - } - else if ( value instanceof Double ) - { + } else if (value instanceof Double) { return 8; - } - else - { - throw new IllegalArgumentException( - "Unexpected number: '" + value + "' or type" + value.getClass() ); + } else { + throw new IllegalArgumentException("Unexpected number: '" + value + "' or type" + value.getClass()); } } - private static void releaseIfPossible( ByteBuf buf ) - { - if ( buf.refCnt() > 0 ) - { + private static void releaseIfPossible(ByteBuf buf) { + if (buf.refCnt() > 0) { buf.release(); } } - public static T serializeAndReadBack( T instance, Class targetClass ) throws IOException, ClassNotFoundException - { + public static T serializeAndReadBack(T instance, Class targetClass) + throws IOException, ClassNotFoundException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try ( ObjectOutputStream oos = new ObjectOutputStream( bos ) ) - { - oos.writeObject( instance ); + try (ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(instance); } bos.close(); - try ( ObjectInputStream oos = new ObjectInputStream( new ByteArrayInputStream( bos.toByteArray() ) ) ) - { - return targetClass.cast( oos.readObject() ); + try (ObjectInputStream oos = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()))) { + return targetClass.cast(oos.readObject()); } } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/Cluster.java b/driver/src/test/java/org/neo4j/driver/util/cc/Cluster.java index 81079cce95..8ec1b67574 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/Cluster.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/Cluster.java @@ -18,6 +18,10 @@ */ package org.neo4j.driver.util.cc; +import static java.util.Collections.emptySet; +import static java.util.Collections.unmodifiableSet; +import static org.neo4j.driver.util.TestUtil.sleep; + import java.io.FileNotFoundException; import java.net.URI; import java.nio.file.Path; @@ -26,19 +30,13 @@ import java.util.Set; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Driver; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.util.TestUtil; import org.neo4j.driver.util.cc.ClusterMemberRoleDiscoveryFactory.ClusterMemberRoleDiscovery; -import static java.util.Collections.emptySet; -import static java.util.Collections.unmodifiableSet; -import static org.neo4j.driver.util.TestUtil.sleep; - -public class Cluster implements AutoCloseable -{ +public class Cluster implements AutoCloseable { private static final String ADMIN_USER = "neo4j"; private static final int STARTUP_TIMEOUT_SECONDS = 120; private static final int ONLINE_MEMBERS_CHECK_SLEEP_MS = 500; @@ -48,334 +46,265 @@ public class Cluster implements AutoCloseable private final Set offlineMembers; private final ClusterDrivers clusterDrivers; - public Cluster( Path path, String password ) - { - this( path, emptySet(), new ClusterDrivers( ADMIN_USER, password ) ); + public Cluster(Path path, String password) { + this(path, emptySet(), new ClusterDrivers(ADMIN_USER, password)); } - private Cluster( Path path, Set members, ClusterDrivers clusterDrivers ) - { + private Cluster(Path path, Set members, ClusterDrivers clusterDrivers) { this.path = path; this.members = members; this.offlineMembers = new HashSet<>(); this.clusterDrivers = clusterDrivers; } - Cluster withMembers( Set newMembers ) throws ClusterUnavailableException - { - waitForMembersToBeOnline( newMembers, clusterDrivers ); - return new Cluster( path, newMembers, clusterDrivers ); + Cluster withMembers(Set newMembers) throws ClusterUnavailableException { + waitForMembersToBeOnline(newMembers, clusterDrivers); + return new Cluster(path, newMembers, clusterDrivers); } - public URI getRoutingUri() - { - return randomOf( cores() ).getRoutingUri(); + public URI getRoutingUri() { + return randomOf(cores()).getRoutingUri(); } - public Path getPath() - { + public Path getPath() { return path; } - public void deleteData() - { + public void deleteData() { // execute write query to remove all nodes and retrieve bookmark - Driver driverToLeader = clusterDrivers.getDriver( leader() ); - Bookmark bookmark = TestUtil.cleanDb( driverToLeader ); - if ( bookmark == null ) - { - throw new IllegalStateException( "Cleanup of the database did not produce a bookmark" ); + Driver driverToLeader = clusterDrivers.getDriver(leader()); + Bookmark bookmark = TestUtil.cleanDb(driverToLeader); + if (bookmark == null) { + throw new IllegalStateException("Cleanup of the database did not produce a bookmark"); } // ensure that every cluster member is up-to-date and contains no nodes - for ( ClusterMember member : members ) - { - Driver driver = clusterDrivers.getDriver( member ); - long nodeCount = TestUtil.countNodes( driver, bookmark ); - if ( nodeCount != 0 ) - { - throw new IllegalStateException( "Not all nodes have been deleted. " + nodeCount + " still there somehow" ); + for (ClusterMember member : members) { + Driver driver = clusterDrivers.getDriver(member); + long nodeCount = TestUtil.countNodes(driver, bookmark); + if (nodeCount != 0) { + throw new IllegalStateException( + "Not all nodes have been deleted. " + nodeCount + " still there somehow"); } } } - public Set members() - { - return unmodifiableSet( members ); + public Set members() { + return unmodifiableSet(members); } - public ClusterMember leader() - { - Set leaders = membersWithRole( ClusterMemberRole.LEADER ); - if ( leaders.size() != 1 ) - { - throw new IllegalStateException( "Single leader expected. " + leaders ); + public ClusterMember leader() { + Set leaders = membersWithRole(ClusterMemberRole.LEADER); + if (leaders.size() != 1) { + throw new IllegalStateException("Single leader expected. " + leaders); } return leaders.iterator().next(); } - public ClusterMember anyFollower() - { - return randomOf( followers() ); + public ClusterMember anyFollower() { + return randomOf(followers()); } - public Set followers() - { - return membersWithRole( ClusterMemberRole.FOLLOWER ); + public Set followers() { + return membersWithRole(ClusterMemberRole.FOLLOWER); } - public ClusterMember anyReadReplica() - { - return randomOf( readReplicas() ); + public ClusterMember anyReadReplica() { + return randomOf(readReplicas()); } - public Set cores() - { - Set readReplicas = membersWithRole( ClusterMemberRole.READ_REPLICA ); - Set cores = new HashSet<>( members ); - cores.removeAll( readReplicas ); + public Set cores() { + Set readReplicas = membersWithRole(ClusterMemberRole.READ_REPLICA); + Set cores = new HashSet<>(members); + cores.removeAll(readReplicas); return cores; } - public Set readReplicas() - { - return membersWithRole( ClusterMemberRole.READ_REPLICA ); + public Set readReplicas() { + return membersWithRole(ClusterMemberRole.READ_REPLICA); } - public void start( ClusterMember member ) - { - startNoWait( member ); + public void start(ClusterMember member) { + startNoWait(member); waitForMembersToBeOnline(); } - public Driver getDirectDriver( ClusterMember member ) - { - return clusterDrivers.getDriver( member ); + public Driver getDirectDriver(ClusterMember member) { + return clusterDrivers.getDriver(member); } - public void dumpClusterDebugLog() - { - for ( ClusterMember member : members ) - { + public void dumpClusterDebugLog() { + for (ClusterMember member : members) { - System.out.println( "Debug log for: " + member.getPath().toString() ); - try - { + System.out.println("Debug log for: " + member.getPath().toString()); + try { member.dumpDebugLog(); - } - catch ( FileNotFoundException e ) - { - System.out.println("Unable to find debug log file for: " + member.getPath().toString()); + } catch (FileNotFoundException e) { + System.out.println( + "Unable to find debug log file for: " + member.getPath().toString()); e.printStackTrace(); } } } @Override - public void close() - { + public void close() { clusterDrivers.close(); } @Override - public String toString() - { - return "Cluster{" + - "path=" + path + - ", members=" + members + - "}"; + public String toString() { + return "Cluster{" + "path=" + path + ", members=" + members + "}"; } - private void addOfflineMember( ClusterMember member ) - { - if ( !offlineMembers.remove( member ) ) - { - throw new IllegalArgumentException( "Cluster member is not offline: " + member ); + private void addOfflineMember(ClusterMember member) { + if (!offlineMembers.remove(member)) { + throw new IllegalArgumentException("Cluster member is not offline: " + member); } - members.add( member ); + members.add(member); } - private void startNoWait( ClusterMember member ) - { - addOfflineMember( member ); - SharedCluster.start( member ); + private void startNoWait(ClusterMember member) { + addOfflineMember(member); + SharedCluster.start(member); } - private Set membersWithRole( ClusterMemberRole role ) - { + private Set membersWithRole(ClusterMemberRole role) { Set membersWithRole = new HashSet<>(); int retryCount = 0; - while ( membersWithRole.isEmpty() && retryCount < 10 ) - { - Driver driver = driverToAnyCore( members, clusterDrivers ); + while (membersWithRole.isEmpty() && retryCount < 10) { + Driver driver = driverToAnyCore(members, clusterDrivers); final ClusterMemberRoleDiscovery discovery = clusterDrivers.getDiscovery(); - final Map clusterOverview = discovery.findClusterOverview( driver ); - for ( BoltServerAddress boltAddress : clusterOverview.keySet() ) - { - if ( role == clusterOverview.get( boltAddress ) ) - { - ClusterMember member = findByBoltAddress( boltAddress, members ); - if ( member == null ) - { - throw new IllegalStateException( "Unknown cluster member: '" + boltAddress + "'\n" + this ); + final Map clusterOverview = discovery.findClusterOverview(driver); + for (BoltServerAddress boltAddress : clusterOverview.keySet()) { + if (role == clusterOverview.get(boltAddress)) { + ClusterMember member = findByBoltAddress(boltAddress, members); + if (member == null) { + throw new IllegalStateException("Unknown cluster member: '" + boltAddress + "'\n" + this); } - membersWithRole.add( member ); + membersWithRole.add(member); } } retryCount++; - if ( !membersWithRole.isEmpty() ) - { + if (!membersWithRole.isEmpty()) { break; - } - else - { - try - { + } else { + try { // give some time for cluster to stabilise - Thread.sleep( 2000 ); - } - catch ( InterruptedException ignored ) - { + Thread.sleep(2000); + } catch (InterruptedException ignored) { } } } - if ( membersWithRole.isEmpty() ) - { - throw new IllegalStateException( "No cluster members with role '" + role + " " + this ); + if (membersWithRole.isEmpty()) { + throw new IllegalStateException("No cluster members with role '" + role + " " + this); } return membersWithRole; } - private void waitForMembersToBeOnline() - { - try - { - waitForMembersToBeOnline( members, clusterDrivers ); - } - catch ( ClusterUnavailableException e ) - { - throw new RuntimeException( e ); + private void waitForMembersToBeOnline() { + try { + waitForMembersToBeOnline(members, clusterDrivers); + } catch (ClusterUnavailableException e) { + throw new RuntimeException(e); } } - private static void waitForMembersToBeOnline( Set members, ClusterDrivers clusterDrivers ) - throws ClusterUnavailableException - { - if ( members.isEmpty() ) - { - throw new IllegalArgumentException( "No members to wait for" ); + private static void waitForMembersToBeOnline(Set members, ClusterDrivers clusterDrivers) + throws ClusterUnavailableException { + if (members.isEmpty()) { + throw new IllegalArgumentException("No members to wait for"); } - Set expectedOnlineAddresses = extractBoltAddresses( members ); + Set expectedOnlineAddresses = extractBoltAddresses(members); Set actualOnlineAddresses = emptySet(); - long deadline = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis( STARTUP_TIMEOUT_SECONDS ); + long deadline = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(STARTUP_TIMEOUT_SECONDS); Throwable error = null; - while ( !expectedOnlineAddresses.equals( actualOnlineAddresses ) ) - { - sleep( ONLINE_MEMBERS_CHECK_SLEEP_MS ); - assertDeadlineNotReached( deadline, expectedOnlineAddresses, actualOnlineAddresses, error ); + while (!expectedOnlineAddresses.equals(actualOnlineAddresses)) { + sleep(ONLINE_MEMBERS_CHECK_SLEEP_MS); + assertDeadlineNotReached(deadline, expectedOnlineAddresses, actualOnlineAddresses, error); - Driver driver = driverToAnyCore( members, clusterDrivers ); + Driver driver = driverToAnyCore(members, clusterDrivers); final ClusterMemberRoleDiscovery discovery = clusterDrivers.getDiscovery(); - try - { - final Map clusterOverview = discovery.findClusterOverview( driver ); + try { + final Map clusterOverview = discovery.findClusterOverview(driver); actualOnlineAddresses = clusterOverview.keySet(); - } - catch ( Throwable t ) - { + } catch (Throwable t) { t.printStackTrace(); - if ( error == null ) - { + if (error == null) { error = t; - } - else - { - error.addSuppressed( t ); + } else { + error.addSuppressed(t); } } } } - private static Driver driverToAnyCore( Set members, ClusterDrivers clusterDrivers ) - { - if ( members.isEmpty() ) - { - throw new IllegalArgumentException( "No members, can't create driver" ); + private static Driver driverToAnyCore(Set members, ClusterDrivers clusterDrivers) { + if (members.isEmpty()) { + throw new IllegalArgumentException("No members, can't create driver"); } - for ( ClusterMember member : members ) - { - Driver driver = clusterDrivers.getDriver( member ); + for (ClusterMember member : members) { + Driver driver = clusterDrivers.getDriver(member); final ClusterMemberRoleDiscovery discovery = clusterDrivers.getDiscovery(); - if ( discovery.isCoreMember( driver ) ) - { + if (discovery.isCoreMember(driver)) { return driver; } } - throw new IllegalStateException( "No core members found among: " + members ); + throw new IllegalStateException("No core members found among: " + members); } - private static void assertDeadlineNotReached( long deadline, Set expectedAddresses, Set actualAddresses, - Throwable error ) throws ClusterUnavailableException - { - if ( System.currentTimeMillis() > deadline ) - { + private static void assertDeadlineNotReached( + long deadline, Set expectedAddresses, Set actualAddresses, Throwable error) + throws ClusterUnavailableException { + if (System.currentTimeMillis() > deadline) { String baseMessage = "Cluster did not become available in " + STARTUP_TIMEOUT_SECONDS + " seconds.\n"; String errorMessage = error == null ? "" : "There were errors checking cluster members.\n"; String expectedAddressesMessage = "Expected online addresses: " + expectedAddresses + "\n"; String actualAddressesMessage = "Actual last seen online addresses: " + actualAddresses + "\n"; String message = baseMessage + errorMessage + expectedAddressesMessage + actualAddressesMessage; - ClusterUnavailableException clusterUnavailable = new ClusterUnavailableException( message ); + ClusterUnavailableException clusterUnavailable = new ClusterUnavailableException(message); - if ( error != null ) - { - clusterUnavailable.addSuppressed( error ); + if (error != null) { + clusterUnavailable.addSuppressed(error); } throw clusterUnavailable; } } - private static Set extractBoltAddresses( Set members ) - { + private static Set extractBoltAddresses(Set members) { Set addresses = new HashSet<>(); - for ( ClusterMember member : members ) - { - addresses.add( member.getBoltAddress() ); + for (ClusterMember member : members) { + addresses.add(member.getBoltAddress()); } return addresses; } - private static ClusterMember findByBoltAddress( BoltServerAddress boltAddress, Set members ) - { - for ( ClusterMember member : members ) - { - if ( member.getBoltAddress().equals( boltAddress ) ) - { + private static ClusterMember findByBoltAddress(BoltServerAddress boltAddress, Set members) { + for (ClusterMember member : members) { + if (member.getBoltAddress().equals(boltAddress)) { return member; } } return null; } - private static ClusterMember randomOf( Set members ) - { - int randomIndex = ThreadLocalRandom.current().nextInt( members.size() ); + private static ClusterMember randomOf(Set members) { + int randomIndex = ThreadLocalRandom.current().nextInt(members.size()); int currentIndex = 0; - for ( ClusterMember member : members ) - { - if ( currentIndex == randomIndex ) - { + for (ClusterMember member : members) { + if (currentIndex == randomIndex) { return member; } currentIndex++; diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterControl.java b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterControl.java index ae6d1329c0..d297bb8401 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterControl.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterControl.java @@ -18,43 +18,42 @@ */ package org.neo4j.driver.util.cc; -import java.nio.file.Path; - import static org.neo4j.driver.util.cc.CommandLineUtil.executeCommand; -final class ClusterControl -{ - private ClusterControl() - { - } +import java.nio.file.Path; - static void installCluster( String neo4jVersion, int cores, int readReplicas, String password, int port, - Path path ) - { - executeCommand( "neoctrl-cluster", "install", - "--cores", String.valueOf( cores ), "--read-replicas", String.valueOf( readReplicas ), - "--password", password, "--initial-port", String.valueOf( port ), - neo4jVersion, path.toString() ); +final class ClusterControl { + private ClusterControl() {} + + static void installCluster(String neo4jVersion, int cores, int readReplicas, String password, int port, Path path) { + executeCommand( + "neoctrl-cluster", + "install", + "--cores", + String.valueOf(cores), + "--read-replicas", + String.valueOf(readReplicas), + "--password", + password, + "--initial-port", + String.valueOf(port), + neo4jVersion, + path.toString()); } - static String startCluster( Path path ) - { - return executeCommand( "neoctrl-cluster", "start", path.toString() ); + static String startCluster(Path path) { + return executeCommand("neoctrl-cluster", "start", path.toString()); } - static String startClusterMember( Path path ) - { - return executeCommand( "neoctrl-start", path.toString() ); + static String startClusterMember(Path path) { + return executeCommand("neoctrl-start", path.toString()); } - static void stopCluster( Path path ) - { - executeCommand( "neoctrl-cluster", "stop", path.toString() ); + static void stopCluster(Path path) { + executeCommand("neoctrl-cluster", "stop", path.toString()); } - static void killCluster( Path path ) - { - executeCommand( "neoctrl-cluster", "stop", "--kill", path.toString() ); + static void killCluster(Path path) { + executeCommand("neoctrl-cluster", "stop", "--kill", path.toString()); } - } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterDrivers.java b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterDrivers.java index c1a058348b..8e037566fa 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterDrivers.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterDrivers.java @@ -18,70 +18,60 @@ */ package org.neo4j.driver.util.cc; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; +import static org.neo4j.driver.internal.util.ServerVersion.version; + import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; - import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.util.cc.ClusterMemberRoleDiscoveryFactory.ClusterMemberRoleDiscovery; -import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; -import static org.neo4j.driver.internal.util.ServerVersion.version; - -public class ClusterDrivers implements AutoCloseable -{ +public class ClusterDrivers implements AutoCloseable { private final String user; private final String password; - private final Map membersWithDrivers; + private final Map membersWithDrivers; private ClusterMemberRoleDiscovery discovery; - public ClusterDrivers( String user, String password ) - { + public ClusterDrivers(String user, String password) { this.user = user; this.password = password; this.membersWithDrivers = new ConcurrentHashMap<>(); } - public Driver getDriver( ClusterMember member ) - { - final Driver driver = membersWithDrivers.computeIfAbsent( member, this::createDriver ); - if ( discovery == null ) - { - discovery = ClusterMemberRoleDiscoveryFactory.newInstance( version( driver ) ); + public Driver getDriver(ClusterMember member) { + final Driver driver = membersWithDrivers.computeIfAbsent(member, this::createDriver); + if (discovery == null) { + discovery = ClusterMemberRoleDiscoveryFactory.newInstance(version(driver)); } return driver; } - public ClusterMemberRoleDiscovery getDiscovery() - { + public ClusterMemberRoleDiscovery getDiscovery() { return discovery; } @Override - public void close() - { - for ( Driver driver : membersWithDrivers.values() ) - { + public void close() { + for (Driver driver : membersWithDrivers.values()) { driver.close(); } } - private Driver createDriver( ClusterMember member ) - { - return GraphDatabase.driver( member.getBoltUri(), AuthTokens.basic( user, password ), driverConfig() ); + private Driver createDriver(ClusterMember member) { + return GraphDatabase.driver(member.getBoltUri(), AuthTokens.basic(user, password), driverConfig()); } - private static Config driverConfig() - { + private static Config driverConfig() { return Config.builder() - .withLogging( DEV_NULL_LOGGING ) + .withLogging(DEV_NULL_LOGGING) .withoutEncryption() - .withMaxConnectionPoolSize( 1 ) - .withConnectionLivenessCheckTimeout( 0, TimeUnit.MILLISECONDS ) - .withEventLoopThreads( 1 ) + .withMaxConnectionPoolSize(1) + .withConnectionLivenessCheckTimeout(0, TimeUnit.MILLISECONDS) + .withEventLoopThreads(1) .build(); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterExtension.java b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterExtension.java index add7438fc0..f2e90f576c 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterExtension.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterExtension.java @@ -18,77 +18,61 @@ */ package org.neo4j.driver.util.cc; -import org.junit.jupiter.api.extension.AfterAllCallback; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeAllCallback; -import org.junit.jupiter.api.extension.ExtensionContext; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.neo4j.driver.util.Neo4jRunner.PASSWORD; +import static org.neo4j.driver.util.Neo4jRunner.TARGET_DIR; +import static org.neo4j.driver.util.Neo4jRunner.USER; +import static org.neo4j.driver.util.cc.CommandLineUtil.boltKitAvailable; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; - +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.util.Neo4jRunner; -import static org.junit.jupiter.api.Assumptions.assumeTrue; -import static org.neo4j.driver.util.Neo4jRunner.PASSWORD; -import static org.neo4j.driver.util.Neo4jRunner.TARGET_DIR; -import static org.neo4j.driver.util.Neo4jRunner.USER; -import static org.neo4j.driver.util.cc.CommandLineUtil.boltKitAvailable; - -public class ClusterExtension implements BeforeAllCallback, AfterEachCallback, AfterAllCallback -{ - private static final Path CLUSTER_DIR = Paths.get( TARGET_DIR, "test-cluster" ).toAbsolutePath(); +public class ClusterExtension implements BeforeAllCallback, AfterEachCallback, AfterAllCallback { + private static final Path CLUSTER_DIR = + Paths.get(TARGET_DIR, "test-cluster").toAbsolutePath(); private static final int INITIAL_PORT = 20_000; public static final int CORE_COUNT = 3; public static final int READ_REPLICA_COUNT = 2; - public Cluster getCluster() - { + public Cluster getCluster() { return SharedCluster.get(); } - public AuthToken getDefaultAuthToken() - { - return AuthTokens.basic( USER, PASSWORD ); + public AuthToken getDefaultAuthToken() { + return AuthTokens.basic(USER, PASSWORD); } @Override - public void beforeAll( ExtensionContext context ) throws Exception - { - assumeTrue( boltKitAvailable(), "BoltKit cluster support unavailable" ); + public void beforeAll(ExtensionContext context) throws Exception { + assumeTrue(boltKitAvailable(), "BoltKit cluster support unavailable"); stopSingleInstanceDatabase(); - if ( !SharedCluster.exists() ) - { - SharedCluster.install( parseNeo4jVersion(), - CORE_COUNT, READ_REPLICA_COUNT, PASSWORD, INITIAL_PORT, CLUSTER_DIR ); + if (!SharedCluster.exists()) { + SharedCluster.install( + parseNeo4jVersion(), CORE_COUNT, READ_REPLICA_COUNT, PASSWORD, INITIAL_PORT, CLUSTER_DIR); - try - { + try { SharedCluster.start(); - } - catch ( Throwable startError ) - { - try - { + } catch (Throwable startError) { + try { SharedCluster.kill(); - } - catch ( Throwable killError ) - { - startError.addSuppressed( killError ); - } - finally - { + } catch (Throwable killError) { + startError.addSuppressed(killError); + } finally { SharedCluster.remove(); } throw startError; - } - finally - { + } finally { addShutdownHookToStopCluster(); } } @@ -97,58 +81,43 @@ public void beforeAll( ExtensionContext context ) throws Exception } @Override - public void afterEach( ExtensionContext context ) - { + public void afterEach(ExtensionContext context) { Cluster cluster = getCluster(); cluster.deleteData(); } @Override - public void afterAll( ExtensionContext context ) - { - if ( SharedCluster.exists() ) - { - try - { + public void afterAll(ExtensionContext context) { + if (SharedCluster.exists()) { + try { SharedCluster.stop(); - } - finally - { + } finally { SharedCluster.remove(); } } } - private static String parseNeo4jVersion() - { - String[] split = Neo4jRunner.NEOCTRL_ARGS.split( "\\s+" ); + private static String parseNeo4jVersion() { + String[] split = Neo4jRunner.NEOCTRL_ARGS.split("\\s+"); return split[split.length - 1]; } - private static void stopSingleInstanceDatabase() throws IOException - { - if ( Neo4jRunner.globalRunnerExists() ) - { + private static void stopSingleInstanceDatabase() throws IOException { + if (Neo4jRunner.globalRunnerExists()) { Neo4jRunner.getOrCreateGlobalRunner().stopNeo4j(); } } - private static void addShutdownHookToStopCluster() - { - Runtime.getRuntime().addShutdownHook( new Thread( () -> - { - try - { - if ( SharedCluster.exists() ) - { + private static void addShutdownHookToStopCluster() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + if (SharedCluster.exists()) { SharedCluster.kill(); } - } - catch ( Throwable t ) - { - System.err.println( "Cluster stopping shutdown hook failed" ); + } catch (Throwable t) { + System.err.println("Cluster stopping shutdown hook failed"); t.printStackTrace(); } - } ) ); + })); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMember.java b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMember.java index 68ec80aa1f..66bf616c70 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMember.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMember.java @@ -18,6 +18,8 @@ */ package org.neo4j.driver.util.cc; +import static java.util.Objects.requireNonNull; + import java.io.File; import java.io.FileNotFoundException; import java.net.InetAddress; @@ -26,13 +28,9 @@ import java.nio.file.Path; import java.util.Objects; import java.util.Scanner; - import org.neo4j.driver.internal.BoltServerAddress; -import static java.util.Objects.requireNonNull; - -public class ClusterMember -{ +public class ClusterMember { public static final String SIMPLE_SCHEME = "bolt://"; public static final String ROUTING_SCHEME = "neo4j://"; @@ -40,83 +38,63 @@ public class ClusterMember private final BoltServerAddress boltAddress; private final Path path; - public ClusterMember( URI boltUri, Path path ) - { - this.boltUri = requireNonNull( boltUri ); - this.boltAddress = newBoltServerAddress( boltUri ); - this.path = requireNonNull( path ); + public ClusterMember(URI boltUri, Path path) { + this.boltUri = requireNonNull(boltUri); + this.boltAddress = newBoltServerAddress(boltUri); + this.path = requireNonNull(path); } - public URI getBoltUri() - { + public URI getBoltUri() { return boltUri; } - public URI getRoutingUri() - { - return URI.create( boltUri.toString().replace( SIMPLE_SCHEME, ROUTING_SCHEME ) ); + public URI getRoutingUri() { + return URI.create(boltUri.toString().replace(SIMPLE_SCHEME, ROUTING_SCHEME)); } - public BoltServerAddress getBoltAddress() - { + public BoltServerAddress getBoltAddress() { return boltAddress; } - public Path getPath() - { + public Path getPath() { return path; } - public void dumpDebugLog() throws FileNotFoundException - { - Scanner input = new Scanner( new File( path.toAbsolutePath().toString() + "/logs/debug.log" )); + public void dumpDebugLog() throws FileNotFoundException { + Scanner input = new Scanner(new File(path.toAbsolutePath().toString() + "/logs/debug.log")); - while (input.hasNextLine()) - { + while (input.hasNextLine()) { System.out.println(input.nextLine()); } } @Override - public boolean equals( Object o ) - { - if ( this == o ) - { + public boolean equals(Object o) { + if (this == o) { return true; } - if ( o == null || getClass() != o.getClass() ) - { + if (o == null || getClass() != o.getClass()) { return false; } ClusterMember that = (ClusterMember) o; - return Objects.equals( boltAddress, that.boltAddress ); + return Objects.equals(boltAddress, that.boltAddress); } @Override - public int hashCode() - { - return Objects.hash( boltAddress ); + public int hashCode() { + return Objects.hash(boltAddress); } @Override - public String toString() - { - return "ClusterMember{" + - "boltUri=" + boltUri + - ", boltAddress=" + boltAddress + - ", path=" + path + - '}'; + public String toString() { + return "ClusterMember{" + "boltUri=" + boltUri + ", boltAddress=" + boltAddress + ", path=" + path + '}'; } - private static BoltServerAddress newBoltServerAddress( URI uri ) - { - try - { - return new BoltServerAddress( InetAddress.getByName( uri.getHost() ).getHostAddress(), uri.getPort() ); - } - catch ( UnknownHostException e ) - { - throw new RuntimeException( e ); + private static BoltServerAddress newBoltServerAddress(URI uri) { + try { + return new BoltServerAddress(InetAddress.getByName(uri.getHost()).getHostAddress(), uri.getPort()); + } catch (UnknownHostException e) { + throw new RuntimeException(e); } } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMemberRole.java b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMemberRole.java index bd81c9fd79..7c0a6f7074 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMemberRole.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMemberRole.java @@ -18,8 +18,7 @@ */ package org.neo4j.driver.util.cc; -public enum ClusterMemberRole -{ +public enum ClusterMemberRole { LEADER, FOLLOWER, READ_REPLICA, diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMemberRoleDiscoveryFactory.java b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMemberRoleDiscoveryFactory.java index 0b48f2a299..f1e273de5b 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMemberRoleDiscoveryFactory.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterMemberRoleDiscoveryFactory.java @@ -18,13 +18,16 @@ */ package org.neo4j.driver.util.cc; +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.internal.util.Iterables.single; + import java.net.InetAddress; import java.net.URI; import java.net.UnknownHostException; import java.util.HashMap; import java.util.List; import java.util.Map; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Driver; import org.neo4j.driver.Record; @@ -34,92 +37,75 @@ import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.ServerVersion; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.internal.util.Iterables.single; - -public class ClusterMemberRoleDiscoveryFactory -{ - public static ClusterMemberRoleDiscovery newInstance( ServerVersion version ) - { - if ( version.greaterThanOrEqual( ServerVersion.v4_0_0 ) ) - { +public class ClusterMemberRoleDiscoveryFactory { + public static ClusterMemberRoleDiscovery newInstance(ServerVersion version) { + if (version.greaterThanOrEqual(ServerVersion.v4_0_0)) { return new SimpleClusterMemberRoleDiscovery(); - } - else - { + } else { return new LegacyClusterMemberRoleDiscovery(); } } - public interface ClusterMemberRoleDiscovery - { - boolean isCoreMember( Driver driver ); + public interface ClusterMemberRoleDiscovery { + boolean isCoreMember(Driver driver); - Map findClusterOverview( Driver driver ); + Map findClusterOverview(Driver driver); } - public static class LegacyClusterMemberRoleDiscovery implements ClusterMemberRoleDiscovery - { + public static class LegacyClusterMemberRoleDiscovery implements ClusterMemberRoleDiscovery { @Override - public boolean isCoreMember( Driver driver ) - { - try ( Session session = driver.session( builder().withDefaultAccessMode( AccessMode.READ ).build() ) ) - { - Record record = single( session.run( "CALL dbms.cluster.role()" ).list() ); - ClusterMemberRole role = extractRole( record ); + public boolean isCoreMember(Driver driver) { + try (Session session = driver.session( + builder().withDefaultAccessMode(AccessMode.READ).build())) { + Record record = single(session.run("CALL dbms.cluster.role()").list()); + ClusterMemberRole role = extractRole(record); return role == ClusterMemberRole.LEADER || role == ClusterMemberRole.FOLLOWER; } } @Override - public Map findClusterOverview( Driver driver ) - { - try ( Session session = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ) ) - { - Result result = session.run( "CALL dbms.cluster.overview()" ); - Map overview = new HashMap<>(); - for ( Record record : result.list() ) - { - final BoltServerAddress address = extractBoltAddress( record ); - final ClusterMemberRole role = extractRole( record ); - overview.put( address, role ); + public Map findClusterOverview(Driver driver) { + try (Session session = driver.session( + builder().withDefaultAccessMode(AccessMode.WRITE).build())) { + Result result = session.run("CALL dbms.cluster.overview()"); + Map overview = new HashMap<>(); + for (Record record : result.list()) { + final BoltServerAddress address = extractBoltAddress(record); + final ClusterMemberRole role = extractRole(record); + overview.put(address, role); } return overview; } } } - public static class SimpleClusterMemberRoleDiscovery implements ClusterMemberRoleDiscovery - { + public static class SimpleClusterMemberRoleDiscovery implements ClusterMemberRoleDiscovery { private static final String DEFAULT_DATABASE = "neo4j"; @Override - public boolean isCoreMember( Driver driver ) - { - try ( Session session = driver.session( builder().withDefaultAccessMode( AccessMode.READ ).build() ) ) - { - Record record = single( session.run( "CALL dbms.cluster.role($database)", - parameters( "database", DEFAULT_DATABASE ) ).list() ); - ClusterMemberRole role = extractRole( record ); + public boolean isCoreMember(Driver driver) { + try (Session session = driver.session( + builder().withDefaultAccessMode(AccessMode.READ).build())) { + Record record = single( + session.run("CALL dbms.cluster.role($database)", parameters("database", DEFAULT_DATABASE)) + .list()); + ClusterMemberRole role = extractRole(record); return role == ClusterMemberRole.LEADER || role == ClusterMemberRole.FOLLOWER; } } @Override - public Map findClusterOverview( Driver driver ) - { - try ( Session session = driver.session( builder().withDefaultAccessMode( AccessMode.READ ).build() ) ) - { - Result result = session.run( "CALL dbms.cluster.overview()" ); - Map overview = new HashMap<>(); - for ( Record record : result.list() ) - { - final BoltServerAddress address = extractBoltAddress( record ); - final ClusterMemberRole role = extractRoleForDatabase( record, DEFAULT_DATABASE ); - if ( role != ClusterMemberRole.UNKNOWN ) // the unknown ones has not fully come online + public Map findClusterOverview(Driver driver) { + try (Session session = driver.session( + builder().withDefaultAccessMode(AccessMode.READ).build())) { + Result result = session.run("CALL dbms.cluster.overview()"); + Map overview = new HashMap<>(); + for (Record record : result.list()) { + final BoltServerAddress address = extractBoltAddress(record); + final ClusterMemberRole role = extractRoleForDatabase(record, DEFAULT_DATABASE); + if (role != ClusterMemberRole.UNKNOWN) // the unknown ones has not fully come online { - overview.put( address, role ); + overview.put(address, role); } } return overview; @@ -127,36 +113,29 @@ public Map findClusterOverview( Driver driv } } - private static ClusterMemberRole extractRoleForDatabase( Record record, String database ) - { - final Map databases = record.get( "databases" ).asMap( Values.ofString() ); - final String roleString = databases.get( database ); - return ClusterMemberRole.valueOf( roleString.toUpperCase() ); + private static ClusterMemberRole extractRoleForDatabase(Record record, String database) { + final Map databases = record.get("databases").asMap(Values.ofString()); + final String roleString = databases.get(database); + return ClusterMemberRole.valueOf(roleString.toUpperCase()); } - private static BoltServerAddress extractBoltAddress( Record record ) - { - List addresses = record.get( "addresses" ).asList(); - String boltUriString = (String) addresses.get( 0 ); - URI boltUri = URI.create( boltUriString ); - return newBoltServerAddress( boltUri ); + private static BoltServerAddress extractBoltAddress(Record record) { + List addresses = record.get("addresses").asList(); + String boltUriString = (String) addresses.get(0); + URI boltUri = URI.create(boltUriString); + return newBoltServerAddress(boltUri); } - private static BoltServerAddress newBoltServerAddress( URI uri ) - { - try - { - return new BoltServerAddress( InetAddress.getByName( uri.getHost() ).getHostAddress(), uri.getPort() ); - } - catch ( UnknownHostException e ) - { - throw new RuntimeException( "Unable to resolve host to IP in URI: '" + uri + "'" ); + private static BoltServerAddress newBoltServerAddress(URI uri) { + try { + return new BoltServerAddress(InetAddress.getByName(uri.getHost()).getHostAddress(), uri.getPort()); + } catch (UnknownHostException e) { + throw new RuntimeException("Unable to resolve host to IP in URI: '" + uri + "'"); } } - private static ClusterMemberRole extractRole( Record record ) - { - String roleString = record.get( "role" ).asString(); - return ClusterMemberRole.valueOf( roleString.toUpperCase() ); + private static ClusterMemberRole extractRole(Record record) { + String roleString = record.get("role").asString(); + return ClusterMemberRole.valueOf(roleString.toUpperCase()); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterUnavailableException.java b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterUnavailableException.java index 675dc383ea..64a53a2091 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterUnavailableException.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterUnavailableException.java @@ -18,10 +18,8 @@ */ package org.neo4j.driver.util.cc; -class ClusterUnavailableException extends Exception -{ - ClusterUnavailableException( String message ) - { - super( message ); +class ClusterUnavailableException extends Exception { + ClusterUnavailableException(String message) { + super(message); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/CommandLineException.java b/driver/src/test/java/org/neo4j/driver/util/cc/CommandLineException.java index e79a03a092..d245aaaee0 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/CommandLineException.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/CommandLineException.java @@ -18,15 +18,12 @@ */ package org.neo4j.driver.util.cc; -class CommandLineException extends RuntimeException -{ - CommandLineException( String message ) - { - super( message ); +class CommandLineException extends RuntimeException { + CommandLineException(String message) { + super(message); } - CommandLineException( String message, Throwable cause ) - { - super( message, cause ); + CommandLineException(String message, Throwable cause) { + super(message, cause); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/CommandLineUtil.java b/driver/src/test/java/org/neo4j/driver/util/cc/CommandLineUtil.java index e6dcd14183..b6027238ad 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/CommandLineUtil.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/CommandLineUtil.java @@ -18,6 +18,10 @@ */ package org.neo4j.driver.util.cc; +import static java.lang.System.lineSeparator; +import static java.util.Arrays.asList; +import static java.util.concurrent.TimeUnit.MINUTES; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -27,111 +31,79 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; - import org.neo4j.driver.util.DaemonThreadFactory; import org.neo4j.driver.util.ProcessEnvConfigurator; -import static java.lang.System.lineSeparator; -import static java.util.Arrays.asList; -import static java.util.concurrent.TimeUnit.MINUTES; - -public class CommandLineUtil -{ - private static final ExecutorService executor = Executors.newCachedThreadPool( - new DaemonThreadFactory( "command-line-thread-" ) ); +public class CommandLineUtil { + private static final ExecutorService executor = + Executors.newCachedThreadPool(new DaemonThreadFactory("command-line-thread-")); - public static boolean boltKitAvailable() - { - try - { - executeCommand( "neoctrl-cluster", "--help" ); + public static boolean boltKitAvailable() { + try { + executeCommand("neoctrl-cluster", "--help"); return true; - } - catch ( CommandLineException e ) - { + } catch (CommandLineException e) { return false; } } - public static String executeCommand( List commands ) - { - try - { - ProcessBuilder processBuilder = new ProcessBuilder().command( commands ); - ProcessEnvConfigurator.configure( processBuilder ); - return executeAndGetStdOut( processBuilder ); - } - catch ( IOException | CommandLineException e ) - { - throw new CommandLineException( "Error running command " + commands, e ); - } - catch ( InterruptedException e ) - { + public static String executeCommand(List commands) { + try { + ProcessBuilder processBuilder = new ProcessBuilder().command(commands); + ProcessEnvConfigurator.configure(processBuilder); + return executeAndGetStdOut(processBuilder); + } catch (IOException | CommandLineException e) { + throw new CommandLineException("Error running command " + commands, e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new CommandLineException( "Interrupted while waiting for command " + commands, e ); + throw new CommandLineException("Interrupted while waiting for command " + commands, e); } } - public static String executeCommand( String... command ) - { - return executeCommand( asList( command ) ); + public static String executeCommand(String... command) { + return executeCommand(asList(command)); } - private static String executeAndGetStdOut( ProcessBuilder processBuilder ) - throws IOException, InterruptedException - { + private static String executeAndGetStdOut(ProcessBuilder processBuilder) throws IOException, InterruptedException { Process process = processBuilder.start(); - Future stdOutFuture = read( process.getInputStream() ); - Future stdErrFuture = read( process.getErrorStream() ); + Future stdOutFuture = read(process.getInputStream()); + Future stdErrFuture = read(process.getErrorStream()); int exitCode = process.waitFor(); - String stdOut = get( stdOutFuture ); - String stdErr = get( stdErrFuture ); - if ( exitCode != 0 ) - { - throw new CommandLineException( "Non-zero exit code\nSTDOUT:\n" + stdOut + "\nSTDERR:\n" + stdErr ); + String stdOut = get(stdOutFuture); + String stdErr = get(stdErrFuture); + if (exitCode != 0) { + throw new CommandLineException("Non-zero exit code\nSTDOUT:\n" + stdOut + "\nSTDERR:\n" + stdErr); } return stdOut; } - private static Future read( final InputStream input ) - { - return executor.submit( new Callable() - { + private static Future read(final InputStream input) { + return executor.submit(new Callable() { @Override - public String call() throws Exception - { - return readToString( input ); + public String call() throws Exception { + return readToString(input); } - } ); + }); } - private static String readToString( InputStream input ) - { + private static String readToString(InputStream input) { StringBuilder result = new StringBuilder(); - try ( BufferedReader reader = new BufferedReader( new InputStreamReader( input ) ) ) - { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(input))) { String line; - while ( (line = reader.readLine()) != null ) - { - result.append( line ).append( lineSeparator() ); + while ((line = reader.readLine()) != null) { + result.append(line).append(lineSeparator()); } - } - catch ( IOException e ) - { - throw new CommandLineException( "Unable to read from stream", e ); + } catch (IOException e) { + throw new CommandLineException("Unable to read from stream", e); } return result.toString(); } - private static T get( Future future ) - { - try - { - return future.get( 10, MINUTES ); - } - catch ( Exception e ) - { - throw new RuntimeException( e ); + private static T get(Future future) { + try { + return future.get(10, MINUTES); + } catch (Exception e) { + throw new RuntimeException(e); } } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/LocalOrRemoteClusterExtension.java b/driver/src/test/java/org/neo4j/driver/util/cc/LocalOrRemoteClusterExtension.java index 0de95e7318..6c5825c24b 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/LocalOrRemoteClusterExtension.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/LocalOrRemoteClusterExtension.java @@ -18,13 +18,11 @@ */ package org.neo4j.driver.util.cc; +import java.net.URI; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExtensionContext; - -import java.net.URI; - import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; @@ -32,115 +30,91 @@ import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.util.TestUtil; -public class LocalOrRemoteClusterExtension implements BeforeAllCallback, AfterEachCallback, AfterAllCallback -{ +public class LocalOrRemoteClusterExtension implements BeforeAllCallback, AfterEachCallback, AfterAllCallback { private static final String CLUSTER_URI_SYSTEM_PROPERTY_NAME = "externalClusterUri"; private static final String NEO4J_USER_PASSWORD_PROPERTY_NAME = "neo4jUserPassword"; private ClusterExtension localClusterExtension; private URI clusterUri; - public LocalOrRemoteClusterExtension() - { + public LocalOrRemoteClusterExtension() { assertValidSystemPropertiesDefined(); } - public URI getClusterUri() - { + public URI getClusterUri() { return clusterUri; } - public AuthToken getAuthToken() - { - if ( remoteClusterExists() ) - { - return AuthTokens.basic( "neo4j", neo4jUserPasswordFromSystemProperty() ); + public AuthToken getAuthToken() { + if (remoteClusterExists()) { + return AuthTokens.basic("neo4j", neo4jUserPasswordFromSystemProperty()); } return localClusterExtension.getDefaultAuthToken(); } @Override - public void beforeAll( ExtensionContext context ) throws Exception - { - if ( remoteClusterExists() ) - { + public void beforeAll(ExtensionContext context) throws Exception { + if (remoteClusterExists()) { clusterUri = remoteClusterUriFromSystemProperty(); deleteDataInRemoteCluster(); - } - else - { + } else { localClusterExtension = new ClusterExtension(); - localClusterExtension.beforeAll( context ); + localClusterExtension.beforeAll(context); clusterUri = localClusterExtension.getCluster().getRoutingUri(); } } @Override - public void afterEach( ExtensionContext context ) - { - if ( remoteClusterExists() ) - { + public void afterEach(ExtensionContext context) { + if (remoteClusterExists()) { deleteDataInRemoteCluster(); - } - else - { - localClusterExtension.afterEach( context ); + } else { + localClusterExtension.afterEach(context); } } @Override - public void afterAll( ExtensionContext context ) - { - if ( !remoteClusterExists() ) - { - localClusterExtension.afterAll( context ); + public void afterAll(ExtensionContext context) { + if (!remoteClusterExists()) { + localClusterExtension.afterAll(context); } } - public void dumpClusterLogs() - { - if ( localClusterExtension != null ) - { + public void dumpClusterLogs() { + if (localClusterExtension != null) { localClusterExtension.getCluster().dumpClusterDebugLog(); } } - private void deleteDataInRemoteCluster() - { + private void deleteDataInRemoteCluster() { Config.ConfigBuilder builder = Config.builder(); - builder.withEventLoopThreads( 1 ); + builder.withEventLoopThreads(1); - try ( Driver driver = GraphDatabase.driver( getClusterUri(), getAuthToken(), builder.build() ) ) - { - TestUtil.cleanDb( driver ); + try (Driver driver = GraphDatabase.driver(getClusterUri(), getAuthToken(), builder.build())) { + TestUtil.cleanDb(driver); } } - private static void assertValidSystemPropertiesDefined() - { + private static void assertValidSystemPropertiesDefined() { URI uri = remoteClusterUriFromSystemProperty(); String password = neo4jUserPasswordFromSystemProperty(); - if ( (uri != null && password == null) || (uri == null && password != null) ) - { + if ((uri != null && password == null) || (uri == null && password != null)) { throw new IllegalStateException( - "Both cluster uri and 'neo4j' user password system properties should be set. " + - "Uri: '" + uri + "', Password: '" + password + "'" ); + "Both cluster uri and 'neo4j' user password system properties should be set. " + "Uri: '" + uri + + "', Password: '" + password + "'"); } } - private static boolean remoteClusterExists() - { + private static boolean remoteClusterExists() { return remoteClusterUriFromSystemProperty() != null; } - private static URI remoteClusterUriFromSystemProperty() - { - String uri = System.getProperty( CLUSTER_URI_SYSTEM_PROPERTY_NAME ); - return uri == null ? null : URI.create( uri ); + private static URI remoteClusterUriFromSystemProperty() { + String uri = System.getProperty(CLUSTER_URI_SYSTEM_PROPERTY_NAME); + return uri == null ? null : URI.create(uri); } - private static String neo4jUserPasswordFromSystemProperty() - { - return System.getProperty( NEO4J_USER_PASSWORD_PROPERTY_NAME ); + private static String neo4jUserPasswordFromSystemProperty() { + return System.getProperty(NEO4J_USER_PASSWORD_PROPERTY_NAME); } } diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/SharedCluster.java b/driver/src/test/java/org/neo4j/driver/util/cc/SharedCluster.java index c032dbde1f..b0cbeda022 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/SharedCluster.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/SharedCluster.java @@ -18,6 +18,9 @@ */ package org.neo4j.driver.util.cc; +import static java.lang.System.lineSeparator; +import static org.neo4j.driver.util.Neo4jRunner.debug; + import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; @@ -25,138 +28,110 @@ import java.util.HashSet; import java.util.Set; -import static java.lang.System.lineSeparator; -import static org.neo4j.driver.util.Neo4jRunner.debug; - -final class SharedCluster -{ +final class SharedCluster { private static Cluster clusterInstance; - private SharedCluster() - { - } + private SharedCluster() {} - static Cluster get() - { + static Cluster get() { assertClusterExists(); return clusterInstance; } - static void remove() - { + static void remove() { assertClusterExists(); clusterInstance.close(); clusterInstance = null; } - static boolean exists() - { + static boolean exists() { return clusterInstance != null; } - static void install( String neo4jVersion, int cores, int readReplicas, String password, int port, Path path ) - { + static void install(String neo4jVersion, int cores, int readReplicas, String password, int port, Path path) { assertClusterDoesNotExist(); - if ( Files.isDirectory( path ) ) - { - debug( "Found and using cluster installed at `%s`.", path ); + if (Files.isDirectory(path)) { + debug("Found and using cluster installed at `%s`.", path); + } else { + ClusterControl.installCluster(neo4jVersion, cores, readReplicas, password, port, path); + debug("Downloaded cluster at `%s`.", path); } - else - { - ClusterControl.installCluster( neo4jVersion, cores, readReplicas, password, port, path ); - debug( "Downloaded cluster at `%s`.", path ); - } - clusterInstance = new Cluster( path, password ); + clusterInstance = new Cluster(path, password); } - static void start() throws ClusterUnavailableException - { + static void start() throws ClusterUnavailableException { assertClusterExists(); - String output = ClusterControl.startCluster( clusterInstance.getPath() ); - Set members = parseStartCommandOutput( output ); + String output = ClusterControl.startCluster(clusterInstance.getPath()); + Set members = parseStartCommandOutput(output); - try - { - clusterInstance = clusterInstance.withMembers( members ); - debug( "Cluster started: %s.", members ); - } - catch ( ClusterUnavailableException e ) - { + try { + clusterInstance = clusterInstance.withMembers(members); + debug("Cluster started: %s.", members); + } catch (ClusterUnavailableException e) { kill(); throw e; } } - static void start( ClusterMember member ) - { + static void start(ClusterMember member) { assertClusterExists(); - ClusterControl.startClusterMember( member.getPath() ); - debug( "Cluster member at `%s` started.", member ); + ClusterControl.startClusterMember(member.getPath()); + debug("Cluster member at `%s` started.", member); } - static void stop() - { + static void stop() { assertClusterExists(); - ClusterControl.stopCluster( clusterInstance.getPath() ); - debug( "Cluster at `%s` stopped.", clusterInstance.getPath() ); + ClusterControl.stopCluster(clusterInstance.getPath()); + debug("Cluster at `%s` stopped.", clusterInstance.getPath()); } - static void kill() - { + static void kill() { assertClusterExists(); - ClusterControl.killCluster( clusterInstance.getPath() ); - debug( "Cluster at `%s` killed.", clusterInstance.getPath() ); + ClusterControl.killCluster(clusterInstance.getPath()); + debug("Cluster at `%s` killed.", clusterInstance.getPath()); } - private static Set parseStartCommandOutput( String output ) - { + private static Set parseStartCommandOutput(String output) { Set result = new HashSet<>(); - String[] lines = output.split( lineSeparator() ); - for ( int i = 0; i < lines.length; i++ ) - { + String[] lines = output.split(lineSeparator()); + for (int i = 0; i < lines.length; i++) { String line = lines[i].trim(); - if( line.isEmpty() ) - { + if (line.isEmpty()) { // skip any empty lines continue; } - String[] clusterMemberSplit = line.split( " " ); - if ( clusterMemberSplit.length != 3 ) - { - throw new IllegalArgumentException( String.format( - "Wrong start command output found at line [%s]. " + - "Expected to have 'http_uri bolt_uri path' on each nonempty line. " + - "Command output:%n`%s`", i + 1, output ) ); + String[] clusterMemberSplit = line.split(" "); + if (clusterMemberSplit.length != 3) { + throw new IllegalArgumentException(String.format( + "Wrong start command output found at line [%s]. " + + "Expected to have 'http_uri bolt_uri path' on each nonempty line. " + + "Command output:%n`%s`", + i + 1, output)); } - URI boltUri = URI.create( clusterMemberSplit[1] ); - Path path = Paths.get( clusterMemberSplit[2] ); + URI boltUri = URI.create(clusterMemberSplit[1]); + Path path = Paths.get(clusterMemberSplit[2]); - result.add( new ClusterMember( boltUri, path ) ); + result.add(new ClusterMember(boltUri, path)); } - if ( result.isEmpty() ) - { - throw new IllegalStateException( "No cluster members" ); + if (result.isEmpty()) { + throw new IllegalStateException("No cluster members"); } return result; } - private static void assertClusterExists() - { - if ( clusterInstance == null ) - { - throw new IllegalStateException( "Shared cluster does not exist" ); + private static void assertClusterExists() { + if (clusterInstance == null) { + throw new IllegalStateException("Shared cluster does not exist"); } } - private static void assertClusterDoesNotExist() - { - if ( clusterInstance != null ) - { - throw new IllegalStateException( "Shared cluster already exists" ); + private static void assertClusterDoesNotExist() { + if (clusterInstance != null) { + throw new IllegalStateException("Shared cluster already exists"); } } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/AsyncAutocommitTransactionExample.java b/examples/src/main/java/org/neo4j/docs/driver/AsyncAutocommitTransactionExample.java index 14f7aa1e5a..fefeb64521 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/AsyncAutocommitTransactionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/AsyncAutocommitTransactionExample.java @@ -22,33 +22,29 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.async.AsyncSession; // end::async-autocommit-transaction-import[] -public class AsyncAutocommitTransactionExample extends BaseApplication -{ - public AsyncAutocommitTransactionExample( String uri, String user, String password ) - { - super( uri, user, password ); + +public class AsyncAutocommitTransactionExample extends BaseApplication { + public AsyncAutocommitTransactionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::async-autocommit-transaction[] - public CompletionStage> readProductTitles() - { + public CompletionStage> readProductTitles() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); AsyncSession session = driver.asyncSession(); - return session.runAsync( query, parameters ) - .thenCompose( cursor -> cursor.listAsync( record -> record.get( 0 ).asString() ) ) - .exceptionally( error -> - { + return session.runAsync(query, parameters) + .thenCompose(cursor -> cursor.listAsync(record -> record.get(0).asString())) + .exceptionally(error -> { // query execution failed, print error and fallback to empty list of titles error.printStackTrace(); return Collections.emptyList(); - } ) - .thenCompose( titles -> session.closeAsync().thenApply( ignore -> titles ) ); + }) + .thenCompose(titles -> session.closeAsync().thenApply(ignore -> titles)); } // end::async-autocommit-transaction[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/AsyncResultConsumeExample.java b/examples/src/main/java/org/neo4j/docs/driver/AsyncResultConsumeExample.java index 7675e3f5fe..c8661c174b 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/AsyncResultConsumeExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/AsyncResultConsumeExample.java @@ -22,28 +22,21 @@ import java.util.List; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.async.AsyncSession; // end::async-result-consume-import[] -public class AsyncResultConsumeExample extends BaseApplication -{ - public AsyncResultConsumeExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class AsyncResultConsumeExample extends BaseApplication { + public AsyncResultConsumeExample(String uri, String user, String password) { + super(uri, user, password); } // tag::async-result-consume[] - public CompletionStage> getPeople() - { + public CompletionStage> getPeople() { String query = "MATCH (a:Person) RETURN a.name ORDER BY a.name"; AsyncSession session = driver.asyncSession(); - return session.readTransactionAsync( tx -> - tx.runAsync( query ) - .thenCompose( cursor -> cursor.listAsync( record -> - record.get( 0 ).asString() ) ) - ); + return session.readTransactionAsync(tx -> tx.runAsync(query) + .thenCompose(cursor -> cursor.listAsync(record -> record.get(0).asString()))); } // end::async-result-consume[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/AsyncRunMultipleTransactionExample.java b/examples/src/main/java/org/neo4j/docs/driver/AsyncRunMultipleTransactionExample.java index 033877d303..a241e1c287 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/AsyncRunMultipleTransactionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/AsyncRunMultipleTransactionExample.java @@ -20,69 +20,57 @@ // tag::async-result-consume-import[] +import static org.neo4j.driver.Values.parameters; +// end::async-result-consume-import[] + import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.AsyncTransaction; import org.neo4j.driver.async.ResultCursor; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.summary.SummaryCounters; -import static org.neo4j.driver.Values.parameters; -// end::async-result-consume-import[] - -public class AsyncRunMultipleTransactionExample extends BaseApplication -{ - public AsyncRunMultipleTransactionExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class AsyncRunMultipleTransactionExample extends BaseApplication { + public AsyncRunMultipleTransactionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::async-multiple-tx[] - public CompletionStage addEmployees( final String companyName ) - { + public CompletionStage addEmployees(final String companyName) { AsyncSession session = driver.asyncSession(); - return session.readTransactionAsync( AsyncRunMultipleTransactionExample::matchPersonNodes ) - .thenCompose( personNames -> session.writeTransactionAsync( tx -> createNodes( tx, companyName, personNames ) ) ); + return session.readTransactionAsync(AsyncRunMultipleTransactionExample::matchPersonNodes) + .thenCompose( + personNames -> session.writeTransactionAsync(tx -> createNodes(tx, companyName, personNames))); } - private static CompletionStage> matchPersonNodes( AsyncTransaction tx ) - { - return tx.runAsync( "MATCH (a:Person) RETURN a.name AS name" ) - .thenCompose( cursor -> cursor.listAsync( record -> record.get( "name" ).asString() ) ); + private static CompletionStage> matchPersonNodes(AsyncTransaction tx) { + return tx.runAsync("MATCH (a:Person) RETURN a.name AS name") + .thenCompose( + cursor -> cursor.listAsync(record -> record.get("name").asString())); } - private static CompletableFuture createNodes( AsyncTransaction tx, String companyName, List personNames ) - { + private static CompletableFuture createNodes( + AsyncTransaction tx, String companyName, List personNames) { CompletableFuture[] nodeCreatedCounts = personNames.stream() - .map( personName -> createNode( - tx, - companyName, - personName ) ) - .toArray( - size -> new CompletableFuture[size] ); - return CompletableFuture.allOf( nodeCreatedCounts ) - .thenApply( ignored -> - Arrays.stream( - nodeCreatedCounts ) - .map( CompletableFuture::join ) - .reduce( 0, - Integer::sum ) ); + .map(personName -> createNode(tx, companyName, personName)) + .toArray(size -> new CompletableFuture[size]); + return CompletableFuture.allOf(nodeCreatedCounts).thenApply(ignored -> Arrays.stream(nodeCreatedCounts) + .map(CompletableFuture::join) + .reduce(0, Integer::sum)); } - private static CompletionStage createNode( AsyncTransaction tx, String companyName, String personName ) - { - return tx.runAsync( "MATCH (emp:Person {name: $person_name}) " + - "MERGE (com:Company {name: $company_name}) " + - "MERGE (emp)-[:WORKS_FOR]->(com)", - parameters( "person_name", personName, "company_name", companyName ) ) - .thenCompose( ResultCursor::consumeAsync ) - .thenApply( ResultSummary::counters ) - .thenApply( SummaryCounters::nodesCreated ); + private static CompletionStage createNode(AsyncTransaction tx, String companyName, String personName) { + return tx.runAsync( + "MATCH (emp:Person {name: $person_name}) " + "MERGE (com:Company {name: $company_name}) " + + "MERGE (emp)-[:WORKS_FOR]->(com)", + parameters("person_name", personName, "company_name", companyName)) + .thenCompose(ResultCursor::consumeAsync) + .thenApply(ResultSummary::counters) + .thenApply(SummaryCounters::nodesCreated); } // end::async-multiple-tx[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/AsyncTransactionFunctionExample.java b/examples/src/main/java/org/neo4j/docs/driver/AsyncTransactionFunctionExample.java index f878a24018..16cdfb9da6 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/AsyncTransactionFunctionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/AsyncTransactionFunctionExample.java @@ -21,31 +21,26 @@ import java.util.Collections; import java.util.Map; import java.util.concurrent.CompletionStage; - import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.summary.ResultSummary; // end::async-transaction-function-import[] -public class AsyncTransactionFunctionExample extends BaseApplication -{ - public AsyncTransactionFunctionExample( String uri, String user, String password ) - { - super( uri, user, password ); + +public class AsyncTransactionFunctionExample extends BaseApplication { + public AsyncTransactionFunctionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::async-transaction-function[] - public CompletionStage printAllProducts() - { + public CompletionStage printAllProducts() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); AsyncSession session = driver.asyncSession(); - return session.readTransactionAsync( tx -> - tx.runAsync( query, parameters ) - .thenCompose( cursor -> cursor.forEachAsync( record -> - // asynchronously print every record - System.out.println( record.get( 0 ).asString() ) ) ) - ); + return session.readTransactionAsync(tx -> tx.runAsync(query, parameters) + .thenCompose(cursor -> cursor.forEachAsync(record -> + // asynchronously print every record + System.out.println(record.get(0).asString())))); } // end::async-transaction-function[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/AsyncUnmanagedTransactionExample.java b/examples/src/main/java/org/neo4j/docs/driver/AsyncUnmanagedTransactionExample.java index 5e3eaf3950..f606add637 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/AsyncUnmanagedTransactionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/AsyncUnmanagedTransactionExample.java @@ -22,54 +22,46 @@ import java.util.Map; import java.util.concurrent.CompletionStage; import java.util.function.Function; - import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.AsyncTransaction; import org.neo4j.driver.async.ResultCursor; // end::async-unmanaged-transaction-import[] -public class AsyncUnmanagedTransactionExample extends BaseApplication -{ - public AsyncUnmanagedTransactionExample(String uri, String user, String password ) - { - super( uri, user, password ); +public class AsyncUnmanagedTransactionExample extends BaseApplication { + public AsyncUnmanagedTransactionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::async-unmanaged-transaction[] - public CompletionStage printSingleProduct() - { + public CompletionStage printSingleProduct() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); AsyncSession session = driver.asyncSession(); - Function> printSingleTitle = tx -> - tx.runAsync( query, parameters ) - .thenCompose( ResultCursor::singleAsync ) - .thenApply( record -> record.get( 0 ).asString() ) - .thenApply( title -> - { - // single title fetched successfully - System.out.println( title ); - return true; // signal to commit the transaction - } ) - .exceptionally( error -> - { - // query execution failed - error.printStackTrace(); - return false; // signal to rollback the transaction - } ) - .thenCompose( commit -> commit ? tx.commitAsync() : tx.rollbackAsync() ); + Function> printSingleTitle = tx -> tx.runAsync(query, parameters) + .thenCompose(ResultCursor::singleAsync) + .thenApply(record -> record.get(0).asString()) + .thenApply(title -> { + // single title fetched successfully + System.out.println(title); + return true; // signal to commit the transaction + }) + .exceptionally(error -> { + // query execution failed + error.printStackTrace(); + return false; // signal to rollback the transaction + }) + .thenCompose(commit -> commit ? tx.commitAsync() : tx.rollbackAsync()); return session.beginTransactionAsync() - .thenCompose( printSingleTitle ) - .exceptionally( error -> - { + .thenCompose(printSingleTitle) + .exceptionally(error -> { // either commit or rollback failed error.printStackTrace(); return null; - } ) - .thenCompose( ignore -> session.closeAsync() ); + }) + .thenCompose(ignore -> session.closeAsync()); } // end::async-unmanaged-transaction[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/AutocommitTransactionExample.java b/examples/src/main/java/org/neo4j/docs/driver/AutocommitTransactionExample.java index 64c27eb807..4ec6693357 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/AutocommitTransactionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/AutocommitTransactionExample.java @@ -20,24 +20,20 @@ // tag::autocommit-transaction-import[] -import org.neo4j.driver.Session; - import static org.neo4j.driver.Values.parameters; // end::autocommit-transaction-import[] -public class AutocommitTransactionExample extends BaseApplication -{ - public AutocommitTransactionExample( String uri, String user, String password ) - { - super( uri, user, password ); +import org.neo4j.driver.Session; + +public class AutocommitTransactionExample extends BaseApplication { + public AutocommitTransactionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::autocommit-transaction[] - public void addPerson( String name ) - { - try ( Session session = driver.session() ) - { - session.run( "CREATE (a:Person {name: $name})", parameters( "name", name ) ); + public void addPerson(String name) { + try (Session session = driver.session()) { + session.run("CREATE (a:Person {name: $name})", parameters("name", name)); } } // end::autocommit-transaction[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/BaseApplication.java b/examples/src/main/java/org/neo4j/docs/driver/BaseApplication.java index 5a4474451e..992fffb291 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/BaseApplication.java +++ b/examples/src/main/java/org/neo4j/docs/driver/BaseApplication.java @@ -22,18 +22,15 @@ import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; -public abstract class BaseApplication implements AutoCloseable -{ +public abstract class BaseApplication implements AutoCloseable { protected final Driver driver; - public BaseApplication( String uri, String user, String password ) - { - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ) ); + public BaseApplication(String uri, String user, String password) { + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password)); } @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/BasicAuthExample.java b/examples/src/main/java/org/neo4j/docs/driver/BasicAuthExample.java index eda9ad3b82..5c3162418a 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/BasicAuthExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/BasicAuthExample.java @@ -26,26 +26,22 @@ import org.neo4j.driver.Result; // end::basic-auth-import[] -public class BasicAuthExample implements AutoCloseable -{ +public class BasicAuthExample implements AutoCloseable { private final Driver driver; // tag::basic-auth[] - public BasicAuthExample( String uri, String user, String password ) - { - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ) ); + public BasicAuthExample(String uri, String user, String password) { + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password)); } // end::basic-auth[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } - public boolean canConnect() - { - Result result = driver.session().run( "RETURN 1" ); - return result.single().get( 0 ).asInt() == 1; + public boolean canConnect() { + Result result = driver.session().run("RETURN 1"); + return result.single().get(0).asInt() == 1; } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/BearerAuthExample.java b/examples/src/main/java/org/neo4j/docs/driver/BearerAuthExample.java index 9e24af17c3..48f9062eef 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/BearerAuthExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/BearerAuthExample.java @@ -25,20 +25,17 @@ import org.neo4j.driver.GraphDatabase; // end::bearer-auth-import[] -public class BearerAuthExample implements AutoCloseable -{ +public class BearerAuthExample implements AutoCloseable { private final Driver driver; // tag::bearer-auth[] - public BearerAuthExample( String uri, String bearerToken ) - { - driver = GraphDatabase.driver( uri, AuthTokens.bearer( bearerToken ) ); + public BearerAuthExample(String uri, String bearerToken) { + driver = GraphDatabase.driver(uri, AuthTokens.bearer(bearerToken)); } // end::bearer-auth[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/ConfigConnectionPoolExample.java b/examples/src/main/java/org/neo4j/docs/driver/ConfigConnectionPoolExample.java index 02a0b48f28..926aeea0b2 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ConfigConnectionPoolExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ConfigConnectionPoolExample.java @@ -19,39 +19,35 @@ package org.neo4j.docs.driver; // tag::config-connection-pool-import[] import java.util.concurrent.TimeUnit; - import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.Result; // end::config-connection-pool-import[] -public class ConfigConnectionPoolExample implements AutoCloseable -{ + +public class ConfigConnectionPoolExample implements AutoCloseable { private final Driver driver; // tag::config-connection-pool[] - public ConfigConnectionPoolExample( String uri, String user, String password ) - { + public ConfigConnectionPoolExample(String uri, String user, String password) { Config config = Config.builder() - .withMaxConnectionLifetime( 30, TimeUnit.MINUTES ) - .withMaxConnectionPoolSize( 50 ) - .withConnectionAcquisitionTimeout( 2, TimeUnit.MINUTES ) + .withMaxConnectionLifetime(30, TimeUnit.MINUTES) + .withMaxConnectionPoolSize(50) + .withConnectionAcquisitionTimeout(2, TimeUnit.MINUTES) .build(); - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ), config ); + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config); } // end::config-connection-pool[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } - public boolean canConnect() - { - Result result = driver.session().run( "RETURN 1" ); - return result.single().get( 0 ).asInt() == 1; + public boolean canConnect() { + Result result = driver.session().run("RETURN 1"); + return result.single().get(0).asInt() == 1; } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/ConfigConnectionTimeoutExample.java b/examples/src/main/java/org/neo4j/docs/driver/ConfigConnectionTimeoutExample.java index 0b8a0688af..7758828834 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ConfigConnectionTimeoutExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ConfigConnectionTimeoutExample.java @@ -20,32 +20,27 @@ // tag::config-connection-timeout-import[] +import static java.util.concurrent.TimeUnit.SECONDS; +// end::config-connection-timeout-import[] + import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; -import static java.util.concurrent.TimeUnit.SECONDS; -// end::config-connection-timeout-import[] - -public class ConfigConnectionTimeoutExample implements AutoCloseable -{ +public class ConfigConnectionTimeoutExample implements AutoCloseable { private final Driver driver; // tag::config-connection-timeout[] - public ConfigConnectionTimeoutExample( String uri, String user, String password ) - { - Config config = Config.builder() - .withConnectionTimeout( 15, SECONDS ) - .build(); + public ConfigConnectionTimeoutExample(String uri, String user, String password) { + Config config = Config.builder().withConnectionTimeout(15, SECONDS).build(); - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ), config ); + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config); } // end::config-connection-timeout[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/ConfigCustomResolverExample.java b/examples/src/main/java/org/neo4j/docs/driver/ConfigCustomResolverExample.java index 394b7f09f1..37f0950dab 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ConfigCustomResolverExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ConfigCustomResolverExample.java @@ -19,9 +19,11 @@ package org.neo4j.docs.driver; // tag::config-custom-resolver-import[] +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.Values.parameters; + import java.util.Arrays; import java.util.HashSet; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; @@ -32,58 +34,55 @@ import org.neo4j.driver.Session; import org.neo4j.driver.net.ServerAddress; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.Values.parameters; - // end::config-custom-resolver-import[] -public class ConfigCustomResolverExample implements AutoCloseable -{ +public class ConfigCustomResolverExample implements AutoCloseable { private final Driver driver; - public ConfigCustomResolverExample( String virtualUri, AuthToken authToken, ServerAddress... addresses ) - { + public ConfigCustomResolverExample(String virtualUri, AuthToken authToken, ServerAddress... addresses) { Config config = Config.builder() - .withResolver( address -> new HashSet<>( Arrays.asList( addresses ) ) ) - .build(); + .withResolver(address -> new HashSet<>(Arrays.asList(addresses))) + .build(); - driver = GraphDatabase.driver( virtualUri, authToken, config ); + driver = GraphDatabase.driver(virtualUri, authToken, config); } // tag::config-custom-resolver[] - private Driver createDriver( String virtualUri, String user, String password, ServerAddress... addresses ) - { + private Driver createDriver(String virtualUri, String user, String password, ServerAddress... addresses) { Config config = Config.builder() - .withResolver( address -> new HashSet<>( Arrays.asList( addresses ) ) ) + .withResolver(address -> new HashSet<>(Arrays.asList(addresses))) .build(); - return GraphDatabase.driver( virtualUri, AuthTokens.basic( user, password ), config ); + return GraphDatabase.driver(virtualUri, AuthTokens.basic(user, password), config); } - private void addPerson( String name ) - { + private void addPerson(String name) { String username = "neo4j"; String password = "some password"; - try ( Driver driver = createDriver( "neo4j://x.example.com", username, password, ServerAddress.of( "a.example.com", 7676 ), - ServerAddress.of( "b.example.com", 8787 ), ServerAddress.of( "c.example.com", 9898 ) ) ) - { - try ( Session session = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ) ) - { - session.run( "CREATE (a:Person {name: $name})", parameters( "name", name ) ); + try (Driver driver = createDriver( + "neo4j://x.example.com", + username, + password, + ServerAddress.of("a.example.com", 7676), + ServerAddress.of("b.example.com", 8787), + ServerAddress.of("c.example.com", 9898))) { + try (Session session = driver.session( + builder().withDefaultAccessMode(AccessMode.WRITE).build())) { + session.run("CREATE (a:Person {name: $name})", parameters("name", name)); } } } // end::config-custom-resolver[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } - public boolean canConnect() - { - Result result = driver.session( builder().withDefaultAccessMode( AccessMode.READ ).build() ).run( "RETURN 1" ); - return result.single().get( 0 ).asInt() == 1; + public boolean canConnect() { + Result result = driver.session( + builder().withDefaultAccessMode(AccessMode.READ).build()) + .run("RETURN 1"); + return result.single().get(0).asInt() == 1; } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/ConfigMaxRetryTimeExample.java b/examples/src/main/java/org/neo4j/docs/driver/ConfigMaxRetryTimeExample.java index 27e83dd72f..77e8a26cda 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ConfigMaxRetryTimeExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ConfigMaxRetryTimeExample.java @@ -20,32 +20,28 @@ // tag::config-max-retry-time-import[] +import static java.util.concurrent.TimeUnit.SECONDS; +// end::config-max-retry-time-import[] + import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; -import static java.util.concurrent.TimeUnit.SECONDS; -// end::config-max-retry-time-import[] - -public class ConfigMaxRetryTimeExample implements AutoCloseable -{ +public class ConfigMaxRetryTimeExample implements AutoCloseable { private final Driver driver; // tag::config-max-retry-time[] - public ConfigMaxRetryTimeExample( String uri, String user, String password ) - { - Config config = Config.builder() - .withMaxTransactionRetryTime( 15, SECONDS ) - .build(); + public ConfigMaxRetryTimeExample(String uri, String user, String password) { + Config config = + Config.builder().withMaxTransactionRetryTime(15, SECONDS).build(); - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ), config ); + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config); } // end::config-max-retry-time[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/ConfigTrustExample.java b/examples/src/main/java/org/neo4j/docs/driver/ConfigTrustExample.java index e1a621d87b..a2ac8acda8 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ConfigTrustExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ConfigTrustExample.java @@ -26,24 +26,21 @@ import org.neo4j.driver.GraphDatabase; // end::config-trust-import[] -public class ConfigTrustExample implements AutoCloseable -{ +public class ConfigTrustExample implements AutoCloseable { private final Driver driver; // tag::config-trust[] - public ConfigTrustExample( String uri, String user, String password ) - { + public ConfigTrustExample(String uri, String user, String password) { Config config = Config.builder() - .withTrustStrategy( Config.TrustStrategy.trustSystemCertificates() ) + .withTrustStrategy(Config.TrustStrategy.trustSystemCertificates()) .build(); - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ), config ); + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config); } // end::config-trust[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/ConfigUnencryptedExample.java b/examples/src/main/java/org/neo4j/docs/driver/ConfigUnencryptedExample.java index 5b36823cc9..f118f9d45e 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ConfigUnencryptedExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ConfigUnencryptedExample.java @@ -26,24 +26,19 @@ import org.neo4j.driver.GraphDatabase; // end::config-unencrypted-import[] -public class ConfigUnencryptedExample implements AutoCloseable -{ +public class ConfigUnencryptedExample implements AutoCloseable { private final Driver driver; // tag::config-unencrypted[] - public ConfigUnencryptedExample( String uri, String user, String password ) - { - Config config = Config.builder() - .withoutEncryption() - .build(); + public ConfigUnencryptedExample(String uri, String user, String password) { + Config config = Config.builder().withoutEncryption().build(); - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ), config ); + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config); } // end::config-unencrypted[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/CustomAuthExample.java b/examples/src/main/java/org/neo4j/docs/driver/CustomAuthExample.java index d31a9830f4..f4c2061113 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/CustomAuthExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/CustomAuthExample.java @@ -21,27 +21,28 @@ // tag::custom-auth-import[] import java.util.Map; - import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; // end::custom-auth-import[] -public class CustomAuthExample implements AutoCloseable -{ +public class CustomAuthExample implements AutoCloseable { private final Driver driver; // tag::custom-auth[] - public CustomAuthExample( String uri, String principal, String credentials, String realm, String scheme, - Map parameters ) - { - driver = GraphDatabase.driver( uri, AuthTokens.custom( principal, credentials, realm, scheme, parameters ) ); + public CustomAuthExample( + String uri, + String principal, + String credentials, + String realm, + String scheme, + Map parameters) { + driver = GraphDatabase.driver(uri, AuthTokens.custom(principal, credentials, realm, scheme, parameters)); } // end::custom-auth[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/CypherErrorExample.java b/examples/src/main/java/org/neo4j/docs/driver/CypherErrorExample.java index 43c1850fb2..a359ae864c 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/CypherErrorExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/CypherErrorExample.java @@ -20,49 +20,39 @@ // tag::cypher-error-import[] -import org.neo4j.driver.Session; +import static org.neo4j.driver.Values.parameters; +// end::cypher-error-import[] + import org.neo4j.driver.Result; +import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; import org.neo4j.driver.TransactionWork; import org.neo4j.driver.exceptions.ClientException; -import static org.neo4j.driver.Values.parameters; -// end::cypher-error-import[] - -public class CypherErrorExample extends BaseApplication -{ - public CypherErrorExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class CypherErrorExample extends BaseApplication { + public CypherErrorExample(String uri, String user, String password) { + super(uri, user, password); } // tag::cypher-error[] - public int getEmployeeNumber( final String name ) - { - try ( Session session = driver.session() ) - { - return session.readTransaction( new TransactionWork() - { + public int getEmployeeNumber(final String name) { + try (Session session = driver.session()) { + return session.readTransaction(new TransactionWork() { @Override - public Integer execute( Transaction tx ) - { - return selectEmployee( tx, name ); + public Integer execute(Transaction tx) { + return selectEmployee(tx, name); } - } ); + }); } } - private static int selectEmployee( Transaction tx, String name ) - { - try - { - Result result = tx.run( "SELECT * FROM Employees WHERE name = $name", parameters( "name", name ) ); - return result.single().get( "employee_number" ).asInt(); - } - catch ( ClientException ex ) - { + private static int selectEmployee(Transaction tx, String name) { + try { + Result result = tx.run("SELECT * FROM Employees WHERE name = $name", parameters("name", name)); + return result.single().get("employee_number").asInt(); + } catch (ClientException ex) { tx.rollback(); - System.err.println( ex.getMessage() ); + System.err.println(ex.getMessage()); return -1; } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/DatabaseSelectionExample.java b/examples/src/main/java/org/neo4j/docs/driver/DatabaseSelectionExample.java index e66236d091..5fc05f4ee1 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/DatabaseSelectionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/DatabaseSelectionExample.java @@ -24,28 +24,27 @@ import org.neo4j.driver.SessionConfig; // end::database-selection-import[] -public class DatabaseSelectionExample extends BaseApplication -{ - public DatabaseSelectionExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class DatabaseSelectionExample extends BaseApplication { + public DatabaseSelectionExample(String uri, String user, String password) { + super(uri, user, password); } - public void useAnotherDatabaseExample() - { + public void useAnotherDatabaseExample() { // tag::database-selection[] - try ( Session session = driver.session( SessionConfig.forDatabase( "examples" ) ) ) - { - session.run( "CREATE (a:Greeting {message: 'Hello, Example-Database'}) RETURN a" ).consume(); + try (Session session = driver.session(SessionConfig.forDatabase("examples"))) { + session.run("CREATE (a:Greeting {message: 'Hello, Example-Database'}) RETURN a") + .consume(); } SessionConfig sessionConfig = SessionConfig.builder() - .withDatabase( "examples" ) - .withDefaultAccessMode( AccessMode.READ ) + .withDatabase("examples") + .withDefaultAccessMode(AccessMode.READ) .build(); - try ( Session session = driver.session( sessionConfig ) ) - { - String msg = session.run( "MATCH (a:Greeting) RETURN a.message as msg" ).single().get( "msg" ).asString(); + try (Session session = driver.session(sessionConfig)) { + String msg = session.run("MATCH (a:Greeting) RETURN a.message as msg") + .single() + .get("msg") + .asString(); System.out.println(msg); } // end::database-selection[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/DriverIntroductionExample.java b/examples/src/main/java/org/neo4j/docs/driver/DriverIntroductionExample.java index 0197e1fbda..26f58443eb 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/DriverIntroductionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/DriverIntroductionExample.java @@ -25,7 +25,6 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; - import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @@ -56,28 +55,27 @@ public void close() throws Exception { public void createFriendship(final String person1Name, final String person2Name, final String knowsFrom) { // To learn more about the Cypher syntax, see https://neo4j.com/docs/cypher-manual/current/ // The Reference Card is also a good resource for keywords https://neo4j.com/docs/cypher-refcard/current/ - String createFriendshipQuery = "CREATE (p1:Person { name: $person1_name })\n" + - "CREATE (p2:Person { name: $person2_name })\n" + - "CREATE (p1)-[k:KNOWS { from: $knows_from }]->(p2)\n" + - "RETURN p1, p2, k"; + String createFriendshipQuery = + "CREATE (p1:Person { name: $person1_name })\n" + "CREATE (p2:Person { name: $person2_name })\n" + + "CREATE (p1)-[k:KNOWS { from: $knows_from }]->(p2)\n" + + "RETURN p1, p2, k"; Map params = new HashMap<>(); params.put("person1_name", person1Name); params.put("person2_name", person2Name); - params.put("knows_from", knowsFrom ); + params.put("knows_from", knowsFrom); - try (Session session = driver.session()) - { + try (Session session = driver.session()) { // Write transactions allow the driver to handle retries and transient errors - Record record = session.writeTransaction( tx -> - { - Result result = tx.run( createFriendshipQuery, params ); - return result.single(); - } ); - System.out.println( String.format( "Created friendship between: %s, %s from %s", - record.get( "p1" ).get( "name" ).asString(), - record.get( "p2" ).get( "name" ).asString(), - record.get( "k" ).get( "from" ).asString() ) ); + Record record = session.writeTransaction(tx -> { + Result result = tx.run(createFriendshipQuery, params); + return result.single(); + }); + System.out.println(String.format( + "Created friendship between: %s, %s from %s", + record.get("p1").get("name").asString(), + record.get("p2").get("name").asString(), + record.get("k").get("from").asString())); // You should capture any errors along with the query and data for traceability } catch (Neo4jException ex) { LOGGER.log(Level.SEVERE, createFriendshipQuery + " raised an exception", ex); @@ -86,9 +84,7 @@ public void createFriendship(final String person1Name, final String person2Name, } public void findPerson(final String personName) { - String readPersonByNameQuery = "MATCH (p:Person)\n" + - "WHERE p.name = $person_name\n" + - "RETURN p.name AS name"; + String readPersonByNameQuery = "MATCH (p:Person)\n" + "WHERE p.name = $person_name\n" + "RETURN p.name AS name"; Map params = Collections.singletonMap("person_name", personName); @@ -97,8 +93,9 @@ public void findPerson(final String personName) { Result result = tx.run(readPersonByNameQuery, params); return result.single(); }); - System.out.println(String.format("Found person: %s", record.get("name").asString())); - // You should capture any errors along with the query and data for traceability + System.out.println( + String.format("Found person: %s", record.get("name").asString())); + // You should capture any errors along with the query and data for traceability } catch (Neo4jException ex) { LOGGER.log(Level.SEVERE, readPersonByNameQuery + " raised an exception", ex); throw ex; @@ -112,9 +109,9 @@ public static void main(String... args) throws Exception { String user = ""; String password = ""; Config config = Config.builder() - // Configuring slf4j logging - .withLogging( Logging.slf4j() ) - .build(); + // Configuring slf4j logging + .withLogging(Logging.slf4j()) + .build(); try (DriverIntroductionExample app = new DriverIntroductionExample(boltUrl, user, password, config)) { app.createFriendship("Alice", "David", "School"); app.findPerson("Alice"); diff --git a/examples/src/main/java/org/neo4j/docs/driver/DriverLifecycleExample.java b/examples/src/main/java/org/neo4j/docs/driver/DriverLifecycleExample.java index 3f917faad7..e764eea5b7 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/DriverLifecycleExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/DriverLifecycleExample.java @@ -26,18 +26,15 @@ // end::driver-lifecycle-import[] // tag::driver-lifecycle[] -public class DriverLifecycleExample implements AutoCloseable -{ +public class DriverLifecycleExample implements AutoCloseable { private final Driver driver; - public DriverLifecycleExample( String uri, String user, String password ) - { - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ) ); + public DriverLifecycleExample(String uri, String user, String password) { + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password)); } @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/HelloWorldExample.java b/examples/src/main/java/org/neo4j/docs/driver/HelloWorldExample.java index cb64fd1a53..556cf1f543 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/HelloWorldExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/HelloWorldExample.java @@ -20,52 +20,44 @@ // tag::hello-world-import[] +import static org.neo4j.driver.Values.parameters; +// end::hello-world-import[] + import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.Result; import org.neo4j.driver.Session; -import static org.neo4j.driver.Values.parameters; -// end::hello-world-import[] - // tag::hello-world[] -public class HelloWorldExample implements AutoCloseable -{ +public class HelloWorldExample implements AutoCloseable { private final Driver driver; - public HelloWorldExample( String uri, String user, String password ) - { - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ) ); + public HelloWorldExample(String uri, String user, String password) { + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password)); } @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } - public void printGreeting( final String message ) - { - try ( Session session = driver.session() ) - { - String greeting = session.writeTransaction( tx -> - { - Result result = tx.run( "CREATE (a:Greeting) " + - "SET a.message = $message " + - "RETURN a.message + ', from node ' + id(a)", - parameters( "message", message ) ); - return result.single().get( 0 ).asString(); - } ); - System.out.println( greeting ); + public void printGreeting(final String message) { + try (Session session = driver.session()) { + String greeting = session.writeTransaction(tx -> { + Result result = tx.run( + "CREATE (a:Greeting) " + "SET a.message = $message " + + "RETURN a.message + ', from node ' + id(a)", + parameters("message", message)); + return result.single().get(0).asString(); + }); + System.out.println(greeting); } } - public static void main( String... args ) throws Exception - { - try ( HelloWorldExample greeter = new HelloWorldExample( "bolt://localhost:7687", "neo4j", "password" ) ) - { - greeter.printGreeting( "hello, world" ); + public static void main(String... args) throws Exception { + try (HelloWorldExample greeter = new HelloWorldExample("bolt://localhost:7687", "neo4j", "password")) { + greeter.printGreeting("hello, world"); } } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/HostnameVerificationExample.java b/examples/src/main/java/org/neo4j/docs/driver/HostnameVerificationExample.java index 596421fcad..01bbf5e8c9 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/HostnameVerificationExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/HostnameVerificationExample.java @@ -18,41 +18,35 @@ */ package org.neo4j.docs.driver; -import java.io.File; +import static org.neo4j.driver.Config.TrustStrategy.trustCustomCertificateSignedBy; +import java.io.File; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.Session; -import static org.neo4j.driver.Config.TrustStrategy.trustCustomCertificateSignedBy; - -public class HostnameVerificationExample implements AutoCloseable -{ +public class HostnameVerificationExample implements AutoCloseable { private final Driver driver; - HostnameVerificationExample( String uri, String user, String password, File certFile ) - { + HostnameVerificationExample(String uri, String user, String password, File certFile) { Config config = Config.builder() .withEncryption() - .withTrustStrategy( trustCustomCertificateSignedBy( certFile ).withHostnameVerification() ) + .withTrustStrategy(trustCustomCertificateSignedBy(certFile).withHostnameVerification()) .build(); - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ), config ); + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config); } - public boolean canConnect() - { - try ( Session session = driver.session() ) - { - return session.run( "RETURN 42" ).single().get( 0 ).asInt() == 42; + public boolean canConnect() { + try (Session session = driver.session()) { + return session.run("RETURN 42").single().get(0).asInt() == 42; } } @Override - public void close() - { + public void close() { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/KerberosAuthExample.java b/examples/src/main/java/org/neo4j/docs/driver/KerberosAuthExample.java index 1e3f240e6a..51c71d180b 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/KerberosAuthExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/KerberosAuthExample.java @@ -25,20 +25,17 @@ import org.neo4j.driver.GraphDatabase; // end::kerberos-auth-import[] -public class KerberosAuthExample implements AutoCloseable -{ +public class KerberosAuthExample implements AutoCloseable { private final Driver driver; // tag::kerberos-auth[] - public KerberosAuthExample( String uri, String ticket ) - { - driver = GraphDatabase.driver( uri, AuthTokens.kerberos( ticket ) ); + public KerberosAuthExample(String uri, String ticket) { + driver = GraphDatabase.driver(uri, AuthTokens.kerberos(ticket)); } // end::kerberos-auth[] @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/PassBookmarkExample.java b/examples/src/main/java/org/neo4j/docs/driver/PassBookmarkExample.java index e046e37d73..c66ff09b58 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/PassBookmarkExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/PassBookmarkExample.java @@ -20,9 +20,12 @@ // tag::pass-bookmarks-import[] +import static org.neo4j.driver.SessionConfig.builder; +import static org.neo4j.driver.Values.parameters; +// end::pass-bookmarks-import[] + import java.util.ArrayList; import java.util.List; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.Bookmark; import org.neo4j.driver.Record; @@ -30,93 +33,85 @@ import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; -import static org.neo4j.driver.SessionConfig.builder; -import static org.neo4j.driver.Values.parameters; -// end::pass-bookmarks-import[] +public class PassBookmarkExample extends BaseApplication { -public class PassBookmarkExample extends BaseApplication -{ - - public PassBookmarkExample( String uri, String user, String password ) - { - super( uri, user, password ); + public PassBookmarkExample(String uri, String user, String password) { + super(uri, user, password); } // tag::pass-bookmarks[] // Create a company node - private Result addCompany(final Transaction tx, final String name ) - { - return tx.run( "CREATE (:Company {name: $name})", parameters( "name", name ) ); + private Result addCompany(final Transaction tx, final String name) { + return tx.run("CREATE (:Company {name: $name})", parameters("name", name)); } // Create a person node - private Result addPerson(final Transaction tx, final String name ) - { - return tx.run( "CREATE (:Person {name: $name})", parameters( "name", name ) ); + private Result addPerson(final Transaction tx, final String name) { + return tx.run("CREATE (:Person {name: $name})", parameters("name", name)); } // Create an employment relationship to a pre-existing company node. // This relies on the person first having been created. - private Result employ(final Transaction tx, final String person, final String company ) - { - return tx.run( "MATCH (person:Person {name: $person_name}) " + - "MATCH (company:Company {name: $company_name}) " + - "CREATE (person)-[:WORKS_FOR]->(company)", - parameters( "person_name", person, "company_name", company ) ); + private Result employ(final Transaction tx, final String person, final String company) { + return tx.run( + "MATCH (person:Person {name: $person_name}) " + "MATCH (company:Company {name: $company_name}) " + + "CREATE (person)-[:WORKS_FOR]->(company)", + parameters("person_name", person, "company_name", company)); } // Create a friendship between two people. - private Result makeFriends(final Transaction tx, final String person1, final String person2 ) - { - return tx.run( "MATCH (a:Person {name: $person_1}) " + - "MATCH (b:Person {name: $person_2}) " + - "MERGE (a)-[:KNOWS]->(b)", - parameters( "person_1", person1, "person_2", person2 ) ); + private Result makeFriends(final Transaction tx, final String person1, final String person2) { + return tx.run( + "MATCH (a:Person {name: $person_1}) " + "MATCH (b:Person {name: $person_2}) " + + "MERGE (a)-[:KNOWS]->(b)", + parameters("person_1", person1, "person_2", person2)); } // Match and display all friendships. - private Result printFriends(final Transaction tx ) - { - Result result = tx.run( "MATCH (a)-[:KNOWS]->(b) RETURN a.name, b.name" ); - while ( result.hasNext() ) - { + private Result printFriends(final Transaction tx) { + Result result = tx.run("MATCH (a)-[:KNOWS]->(b) RETURN a.name, b.name"); + while (result.hasNext()) { Record record = result.next(); - System.out.println( String.format( "%s knows %s", record.get( "a.name" ).asString(), record.get( "b.name" ).toString() ) ); + System.out.println(String.format( + "%s knows %s", + record.get("a.name").asString(), record.get("b.name").toString())); } return result; } - public void addEmployAndMakeFriends() - { + public void addEmployAndMakeFriends() { // To collect the session bookmarks List savedBookmarks = new ArrayList<>(); // Create the first person and employment relationship. - try ( Session session1 = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ) ) - { - session1.writeTransaction( tx -> addCompany( tx, "Wayne Enterprises" ).consume() ); - session1.writeTransaction( tx -> addPerson( tx, "Alice" ).consume() ); - session1.writeTransaction( tx -> employ( tx, "Alice", "Wayne Enterprises" ).consume() ); - - savedBookmarks.add( session1.lastBookmark() ); + try (Session session1 = + driver.session(builder().withDefaultAccessMode(AccessMode.WRITE).build())) { + session1.writeTransaction(tx -> addCompany(tx, "Wayne Enterprises").consume()); + session1.writeTransaction(tx -> addPerson(tx, "Alice").consume()); + session1.writeTransaction( + tx -> employ(tx, "Alice", "Wayne Enterprises").consume()); + + savedBookmarks.add(session1.lastBookmark()); } // Create the second person and employment relationship. - try ( Session session2 = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ) ) - { - session2.writeTransaction( tx -> addCompany( tx, "LexCorp" ).consume() ); - session2.writeTransaction( tx -> addPerson( tx, "Bob" ).consume() ); - session2.writeTransaction( tx -> employ( tx, "Bob", "LexCorp" ).consume() ); + try (Session session2 = + driver.session(builder().withDefaultAccessMode(AccessMode.WRITE).build())) { + session2.writeTransaction(tx -> addCompany(tx, "LexCorp").consume()); + session2.writeTransaction(tx -> addPerson(tx, "Bob").consume()); + session2.writeTransaction(tx -> employ(tx, "Bob", "LexCorp").consume()); - savedBookmarks.add( session2.lastBookmark() ); + savedBookmarks.add(session2.lastBookmark()); } // Create a friendship between the two people created above. - try ( Session session3 = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).withBookmarks( savedBookmarks ).build() ) ) - { - session3.writeTransaction( tx -> makeFriends( tx, "Alice", "Bob" ).consume() ); + try (Session session3 = driver.session(builder() + .withDefaultAccessMode(AccessMode.WRITE) + .withBookmarks(savedBookmarks) + .build())) { + session3.writeTransaction(tx -> makeFriends(tx, "Alice", "Bob").consume()); - session3.readTransaction( this::printFriends ); + session3.readTransaction(this::printFriends); } } // end::pass-bookmarks[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/ReadWriteTransactionExample.java b/examples/src/main/java/org/neo4j/docs/driver/ReadWriteTransactionExample.java index 0cc7e5b5b8..d4a3a3e329 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ReadWriteTransactionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ReadWriteTransactionExample.java @@ -20,40 +20,34 @@ // tag::read-write-transaction-import[] +import static org.neo4j.driver.Values.parameters; +// end::read-write-transaction-import[] + import org.neo4j.driver.Result; import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; -import static org.neo4j.driver.Values.parameters; -// end::read-write-transaction-import[] - -public class ReadWriteTransactionExample extends BaseApplication -{ - public ReadWriteTransactionExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class ReadWriteTransactionExample extends BaseApplication { + public ReadWriteTransactionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::read-write-transaction[] - public long addPerson( final String name ) - { - try ( Session session = driver.session() ) - { - session.writeTransaction( tx -> createPersonNode( tx, name ) ); - return session.readTransaction( tx -> matchPersonNode( tx, name ) ); + public long addPerson(final String name) { + try (Session session = driver.session()) { + session.writeTransaction(tx -> createPersonNode(tx, name)); + return session.readTransaction(tx -> matchPersonNode(tx, name)); } } - private static Void createPersonNode( Transaction tx, String name ) - { - tx.run( "CREATE (a:Person {name: $name})", parameters( "name", name ) ).consume(); + private static Void createPersonNode(Transaction tx, String name) { + tx.run("CREATE (a:Person {name: $name})", parameters("name", name)).consume(); return null; } - private static long matchPersonNode( Transaction tx, String name ) - { - Result result = tx.run( "MATCH (a:Person {name: $name}) RETURN id(a)", parameters( "name", name ) ); - return result.single().get( 0 ).asLong(); + private static long matchPersonNode(Transaction tx, String name) { + Result result = tx.run("MATCH (a:Person {name: $name}) RETURN id(a)", parameters("name", name)); + return result.single().get(0).asLong(); } // end::read-write-transaction[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/ReadingValuesExample.java b/examples/src/main/java/org/neo4j/docs/driver/ReadingValuesExample.java index f533bd164a..30fb0cab67 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ReadingValuesExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ReadingValuesExample.java @@ -18,114 +18,97 @@ */ package org.neo4j.docs.driver; -import java.util.function.Function; +import static org.neo4j.driver.Values.parameters; +import java.util.function.Function; import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.Session; import org.neo4j.driver.Value; -import static org.neo4j.driver.Values.parameters; - -public class ReadingValuesExample extends BaseApplication -{ +public class ReadingValuesExample extends BaseApplication { private static final String nullFieldName = "fieldName"; private static final String intFieldName = "fieldName"; - public ReadingValuesExample( String uri, String user, String password ) - { - super( uri, user, password ); + public ReadingValuesExample(String uri, String user, String password) { + super(uri, user, password); } - public Boolean nullIsNull() - { - return echo( null, record -> - { + public Boolean nullIsNull() { + return echo(null, record -> { // tag::java-driver-reading-values-null[] - Value possibleNullValue = record.get( nullFieldName ); + Value possibleNullValue = record.get(nullFieldName); // Checking if its null boolean wasNull = possibleNullValue.isNull(); // true // end::java-driver-reading-values-null[] return wasNull; - } ); + }); } - public String nullAsString() - { - return echo( null, record -> - { - Value possibleNullValue = record.get( nullFieldName ); + public String nullAsString() { + return echo(null, record -> { + Value possibleNullValue = record.get(nullFieldName); // tag::java-driver-reading-values-null[] // Getting the null value as string String stringWithNullContent = possibleNullValue.asString(); // "null" // end::java-driver-reading-values-null[] return stringWithNullContent; - } ); + }); } - public Object nullAsObject() - { - return echo( null, record -> - { - Value possibleNullValue = record.get( nullFieldName ); + public Object nullAsObject() { + return echo(null, record -> { + Value possibleNullValue = record.get(nullFieldName); // tag::java-driver-reading-values-null[] // Getting `null` as object Object nullObject = possibleNullValue.asObject(); // null // end::java-driver-reading-values-null[] return nullObject; - } ); + }); } - public float nullAsObjectFloatDefaultValue() - { - return echo( null, record -> - { - Value possibleNullValue = record.get( nullFieldName ); + public float nullAsObjectFloatDefaultValue() { + return echo(null, record -> { + Value possibleNullValue = record.get(nullFieldName); // tag::java-driver-reading-values-null[] // Coercing value with a default value set - float floatValue = possibleNullValue.asFloat( 1.0f ); // 1.0f + float floatValue = possibleNullValue.asFloat(1.0f); // 1.0f // end::java-driver-reading-values-null[] return floatValue; - } ); + }); } - public void nullAsObjectFloat() - { - echo( null, record -> - { - Value possibleNullValue = record.get( nullFieldName ); + public void nullAsObjectFloat() { + echo(null, record -> { + Value possibleNullValue = record.get(nullFieldName); // tag::java-driver-reading-values-null[] // Could not cast null to float float floatValue = possibleNullValue.asFloat(); // throws org.neo4j.driver.exceptions.value.Uncoercible // end::java-driver-reading-values-null[] return floatValue; - } ); + }); } - public Boolean integerFieldIsNull() - { - return echo( 4, record -> - { + public Boolean integerFieldIsNull() { + return echo(4, record -> { // tag::java-driver-reading-values-non-null[] - Value value = record.get( intFieldName ); + Value value = record.get(intFieldName); // Checking if the value is null Boolean falseBoolean = value.isNull(); // false // end::java-driver-reading-values-non-null[] return falseBoolean; - } ); + }); } - public int integerAsInteger() - { - return echo( 4, record -> - { - Value value = record.get( intFieldName ); + public int integerAsInteger() { + return echo(4, record -> { + Value value = record.get(intFieldName); // tag::java-driver-reading-values-non-null[] // Getting as int @@ -133,14 +116,12 @@ public int integerAsInteger() // end::java-driver-reading-values-non-null[] return intValue; - } ); + }); } - public long integerAsLong() - { - return echo( 4, record -> - { - Value value = record.get( intFieldName ); + public long integerAsLong() { + return echo(4, record -> { + Value value = record.get(intFieldName); // tag::java-driver-reading-values-non-null[] // Getting value asLong is also possible for int values @@ -148,33 +129,28 @@ public long integerAsLong() // end::java-driver-reading-values-non-null[] return longValue; - } ); + }); } - public void integerAsString() - { - echo( 4, record -> - { - Value value = record.get( intFieldName ); + public void integerAsString() { + echo(4, record -> { + Value value = record.get(intFieldName); // tag::java-driver-reading-values-non-null[] // But it's not possible to get the int value as string String stringValue = value.asString(); // throws org.neo4j.driver.exceptions.value.Uncoercible // end::java-driver-reading-values-non-null[] return stringValue; - } ); + }); } - private O echo( T value, Function transformation ) - { - try ( Session session = driver.session() ) - { - return session.readTransaction( tx -> - { - Result result = tx.run( "RETURN $in AS fieldName", parameters( "in", value ) ); - Record record = result.next(); - return transformation.apply( record ); - } ); + private O echo(T value, Function transformation) { + try (Session session = driver.session()) { + return session.readTransaction(tx -> { + Result result = tx.run("RETURN $in AS fieldName", parameters("in", value)); + Record record = result.next(); + return transformation.apply(record); + }); } } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/ResultConsumeExample.java b/examples/src/main/java/org/neo4j/docs/driver/ResultConsumeExample.java index c40f266f3c..f1d83739a9 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ResultConsumeExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ResultConsumeExample.java @@ -22,32 +22,26 @@ import java.util.ArrayList; import java.util.List; - import org.neo4j.driver.Result; import org.neo4j.driver.Session; // end::result-consume-import[] -public class ResultConsumeExample extends BaseApplication -{ - public ResultConsumeExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class ResultConsumeExample extends BaseApplication { + public ResultConsumeExample(String uri, String user, String password) { + super(uri, user, password); } // tag::result-consume[] - public List getPeople() - { - try ( Session session = driver.session() ) - { - return session.readTransaction( tx -> { + public List getPeople() { + try (Session session = driver.session()) { + return session.readTransaction(tx -> { List names = new ArrayList<>(); - Result result = tx.run( "MATCH (a:Person) RETURN a.name ORDER BY a.name" ); - while ( result.hasNext() ) - { - names.add( result.next().get( 0 ).asString() ); + Result result = tx.run("MATCH (a:Person) RETURN a.name ORDER BY a.name"); + while (result.hasNext()) { + names.add(result.next().get(0).asString()); } return names; - } ); + }); } } // end::result-consume[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/ResultRetainExample.java b/examples/src/main/java/org/neo4j/docs/driver/ResultRetainExample.java index 63e954f530..fe5fe0db27 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ResultRetainExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ResultRetainExample.java @@ -20,58 +20,47 @@ // tag::result-retain-import[] -import java.util.List; +import static org.neo4j.driver.Values.parameters; +// end::result-retain-import[] +import java.util.List; import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.Session; import org.neo4j.driver.Transaction; import org.neo4j.driver.TransactionWork; -import static org.neo4j.driver.Values.parameters; -// end::result-retain-import[] - -public class ResultRetainExample extends BaseApplication -{ - public ResultRetainExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class ResultRetainExample extends BaseApplication { + public ResultRetainExample(String uri, String user, String password) { + super(uri, user, password); } // tag::result-retain[] - public int addEmployees( final String companyName ) - { - try ( Session session = driver.session() ) - { + public int addEmployees(final String companyName) { + try (Session session = driver.session()) { int employees = 0; - List persons = session.readTransaction( new TransactionWork>() - { + List persons = session.readTransaction(new TransactionWork>() { @Override - public List execute( Transaction tx ) - { - return matchPersonNodes( tx ); + public List execute(Transaction tx) { + return matchPersonNodes(tx); } - } ); - for ( final Record person : persons ) - { - employees += session.writeTransaction( tx -> - { - Result result = tx.run( "MATCH (emp:Person {name: $person_name}) " + - "MERGE (com:Company {name: $company_name}) " + - "MERGE (emp)-[:WORKS_FOR]->(com)", - parameters( "person_name", person.get( "name" ).asString(), "company_name", - companyName ) ); - result.consume(); - return 1; - } ); + }); + for (final Record person : persons) { + employees += session.writeTransaction(tx -> { + Result result = tx.run( + "MATCH (emp:Person {name: $person_name}) " + "MERGE (com:Company {name: $company_name}) " + + "MERGE (emp)-[:WORKS_FOR]->(com)", + parameters("person_name", person.get("name").asString(), "company_name", companyName)); + result.consume(); + return 1; + }); } return employees; } } - private static List matchPersonNodes( Transaction tx ) - { - return tx.run( "MATCH (a:Person) RETURN a.name AS name" ).list(); + private static List matchPersonNodes(Transaction tx) { + return tx.run("MATCH (a:Person) RETURN a.name AS name").list(); } // end::result-retain[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/RxAutocommitTransactionExample.java b/examples/src/main/java/org/neo4j/docs/driver/RxAutocommitTransactionExample.java index f8172178fa..fd52be77de 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/RxAutocommitTransactionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/RxAutocommitTransactionExample.java @@ -21,45 +21,41 @@ import io.reactivex.Flowable; // tag::rx-autocommit-transaction-import[] import io.reactivex.Observable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import java.util.Collections; import java.util.Map; - import org.neo4j.driver.reactive.RxSession; // end::rx-autocommit-transaction-import[] +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -public class RxAutocommitTransactionExample extends BaseApplication -{ - public RxAutocommitTransactionExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class RxAutocommitTransactionExample extends BaseApplication { + public RxAutocommitTransactionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::rx-autocommit-transaction[] - public Flux readProductTitles() - { + public Flux readProductTitles() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); - return Flux.usingWhen( Mono.fromSupplier( driver::rxSession ), - session -> Flux.from( session.run( query, parameters ).records() ).map( record -> record.get( 0 ).asString() ), - RxSession::close ); + return Flux.usingWhen( + Mono.fromSupplier(driver::rxSession), + session -> Flux.from(session.run(query, parameters).records()) + .map(record -> record.get(0).asString()), + RxSession::close); } // end::rx-autocommit-transaction[] // tag::RxJava-autocommit-transaction[] - public Flowable readProductTitlesRxJava() - { + public Flowable readProductTitlesRxJava() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); return Flowable.using( driver::rxSession, - session -> Flowable.fromPublisher( session.run( query, parameters ).records() ).map( record -> record.get( 0 ).asString() ), - session -> Observable.fromPublisher(session.close()).subscribe() - ); + session -> Flowable.fromPublisher(session.run(query, parameters).records()) + .map(record -> record.get(0).asString()), + session -> Observable.fromPublisher(session.close()).subscribe()); } // end::RxJava-autocommit-transaction[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/RxResultConsumeExample.java b/examples/src/main/java/org/neo4j/docs/driver/RxResultConsumeExample.java index 385e66b798..48fe16992b 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/RxResultConsumeExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/RxResultConsumeExample.java @@ -21,53 +21,47 @@ import io.reactivex.Flowable; // tag::rx-result-consume-import[] import io.reactivex.Observable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import java.util.Collections; import java.util.Map; - import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxSession; // end::rx-result-consume-import[] +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -public class RxResultConsumeExample extends BaseApplication -{ - public RxResultConsumeExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class RxResultConsumeExample extends BaseApplication { + public RxResultConsumeExample(String uri, String user, String password) { + super(uri, user, password); } // tag::rx-result-consume[] - public Flux getPeople() - { + public Flux getPeople() { String query = "MATCH (a:Person) RETURN a.name ORDER BY a.name"; - return Flux.usingWhen( Mono.fromSupplier( driver::rxSession ), - session -> session.readTransaction( tx -> { - RxResult result = tx.run( query ); - return Flux.from( result.records() ) - .map( record -> record.get( 0 ).asString() ); - } - ), RxSession::close ); + return Flux.usingWhen( + Mono.fromSupplier(driver::rxSession), + session -> session.readTransaction(tx -> { + RxResult result = tx.run(query); + return Flux.from(result.records()) + .map(record -> record.get(0).asString()); + }), + RxSession::close); } // end::rx-result-consume[] // tag::RxJava-result-consume[] - public Flowable getPeopleRxJava() - { + public Flowable getPeopleRxJava() { String query = "MATCH (a:Person) RETURN a.name ORDER BY a.name"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); return Flowable.using( driver::rxSession, - session -> session.readTransaction( tx -> { - RxResult result = tx.run( query, parameters ); - return Flowable.fromPublisher( result.records() ) - .map( record -> record.get( 0 ).asString() ); - } ) , - session -> Observable.fromPublisher(session.close()).subscribe() - ); + session -> session.readTransaction(tx -> { + RxResult result = tx.run(query, parameters); + return Flowable.fromPublisher(result.records()) + .map(record -> record.get(0).asString()); + }), + session -> Observable.fromPublisher(session.close()).subscribe()); } // end::RxJava-result-consume[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/RxTransactionFunctionExample.java b/examples/src/main/java/org/neo4j/docs/driver/RxTransactionFunctionExample.java index 06fb21e438..d2687780b1 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/RxTransactionFunctionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/RxTransactionFunctionExample.java @@ -21,55 +21,52 @@ import io.reactivex.Flowable; // tag::rx-transaction-function-import[] import io.reactivex.Observable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import java.util.Collections; import java.util.Map; - import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxSession; import org.neo4j.driver.summary.ResultSummary; // end::rx-transaction-function-import[] +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; -public class RxTransactionFunctionExample extends BaseApplication -{ - public RxTransactionFunctionExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class RxTransactionFunctionExample extends BaseApplication { + public RxTransactionFunctionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::rx-transaction-function[] - public Flux printAllProducts() - { + public Flux printAllProducts() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); - return Flux.usingWhen( Mono.fromSupplier( driver::rxSession ), - session -> session.readTransaction( tx -> { - RxResult result = tx.run( query, parameters ); - return Flux.from( result.records() ) - .doOnNext( record -> System.out.println( record.get( 0 ).asString() ) ).then( Mono.from( result.consume() ) ); - } - ), RxSession::close ); + return Flux.usingWhen( + Mono.fromSupplier(driver::rxSession), + session -> session.readTransaction(tx -> { + RxResult result = tx.run(query, parameters); + return Flux.from(result.records()) + .doOnNext(record -> System.out.println(record.get(0).asString())) + .then(Mono.from(result.consume())); + }), + RxSession::close); } // end::rx-transaction-function[] // tag::RxJava-transaction-function[] - public Flowable printAllProductsRxJava() - { + public Flowable printAllProductsRxJava() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); return Flowable.using( driver::rxSession, - session -> session.readTransaction( tx -> { - RxResult result = tx.run( query, parameters ); - return Flowable.fromPublisher( result.records() ) - .doOnNext( record -> System.out.println( record.get( 0 ).asString() ) ).ignoreElements().andThen( result.consume() ); - } ) , - session -> Observable.fromPublisher(session.close()).subscribe() - ); + session -> session.readTransaction(tx -> { + RxResult result = tx.run(query, parameters); + return Flowable.fromPublisher(result.records()) + .doOnNext(record -> System.out.println(record.get(0).asString())) + .ignoreElements() + .andThen(result.consume()); + }), + session -> Observable.fromPublisher(session.close()).subscribe()); } // end::RxJava-transaction-function[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/RxUnmanagedTransactionExample.java b/examples/src/main/java/org/neo4j/docs/driver/RxUnmanagedTransactionExample.java index 442e5e5418..7402204b6f 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/RxUnmanagedTransactionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/RxUnmanagedTransactionExample.java @@ -17,86 +17,82 @@ * limitations under the License. */ package org.neo4j.docs.driver; + import io.reactivex.Flowable; // tag::reactor-unmanaged-transaction-import[] import io.reactivex.Observable; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - import java.util.Collections; import java.util.Map; - import org.neo4j.driver.reactive.RxQueryRunner; import org.neo4j.driver.reactive.RxSession; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; // tag::reactor-unmanaged-transaction-import[] -public class RxUnmanagedTransactionExample extends BaseApplication -{ - public RxUnmanagedTransactionExample(String uri, String user, String password ) - { - super( uri, user, password ); +public class RxUnmanagedTransactionExample extends BaseApplication { + public RxUnmanagedTransactionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::reactor-unmanaged-transaction[] - static class QueryRunnerAndCallbacks - { + static class QueryRunnerAndCallbacks { final RxQueryRunner queryRunner; final Publisher commit; final Publisher rollback; - QueryRunnerAndCallbacks( RxQueryRunner queryRunner, Publisher commit, Publisher rollback ) - { + QueryRunnerAndCallbacks(RxQueryRunner queryRunner, Publisher commit, Publisher rollback) { this.queryRunner = queryRunner; this.commit = commit; this.rollback = rollback; } } - public Flux readSingleProduct() - { + public Flux readSingleProduct() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); // The additional holder is required to make both usingWhen constructs close // the resources in the correct order. Mono queryRunnerSupplier = Mono.using( driver::rxSession, - session -> Mono.from( session.beginTransaction() ).map(tx -> new QueryRunnerAndCallbacks( tx, tx.commit(), tx.rollback() ) ), - RxSession::close - ); + session -> Mono.from(session.beginTransaction()) + .map(tx -> new QueryRunnerAndCallbacks(tx, tx.commit(), tx.rollback())), + RxSession::close); return Flux.usingWhen( queryRunnerSupplier, - queryRunnerAndCallbacks -> Flux.from( queryRunnerAndCallbacks.queryRunner.run( query, parameters ).records() ).map( record -> record.get( 0 ).asString() ), + queryRunnerAndCallbacks -> Flux.from(queryRunnerAndCallbacks + .queryRunner + .run(query, parameters) + .records()) + .map(record -> record.get(0).asString()), queryRunnerAndCallbacks -> queryRunnerAndCallbacks.commit, (queryRunnerAndCallbacks, error) -> queryRunnerAndCallbacks.rollback, - queryRunnerAndCallbacks -> queryRunnerAndCallbacks.rollback - ); + queryRunnerAndCallbacks -> queryRunnerAndCallbacks.rollback); } // end::reactor-unmanaged-transaction[] // tag::RxJava-unmanaged-transaction[] - public Flowable readSingleProductRxJava() - { + public Flowable readSingleProductRxJava() { String query = "MATCH (p:Product) WHERE p.id = $id RETURN p.title"; - Map parameters = Collections.singletonMap( "id", 0 ); + Map parameters = Collections.singletonMap("id", 0); return Flowable.using( driver::rxSession, - session -> Flowable.fromPublisher( session.beginTransaction() ) - .flatMap( tx -> - Flowable.fromPublisher( tx.run( query, parameters ).records() ) - .map( record -> record.get( 0 ).asString() ) - .concatWith( tx.commit() ) - .onErrorResumeNext( error -> { - // We rollback and rethrow the error. For a real application, you may want to handle the error directly here - return Flowable.fromPublisher( tx.rollback() ).concatWith( Flowable.error( error ) ); - } ) - ), - session -> Observable.fromPublisher(session.close()).onErrorResumeNext( Observable.empty() ).subscribe() - ); + session -> Flowable.fromPublisher(session.beginTransaction()).flatMap(tx -> Flowable.fromPublisher( + tx.run(query, parameters).records()) + .map(record -> record.get(0).asString()) + .concatWith(tx.commit()) + .onErrorResumeNext(error -> { + // We rollback and rethrow the error. For a real application, you may want to handle the + // error directly here + return Flowable.fromPublisher(tx.rollback()).concatWith(Flowable.error(error)); + })), + session -> Observable.fromPublisher(session.close()) + .onErrorResumeNext(Observable.empty()) + .subscribe()); } // end::RxJava-unmanaged-transaction[] } diff --git a/examples/src/main/java/org/neo4j/docs/driver/ServiceUnavailableExample.java b/examples/src/main/java/org/neo4j/docs/driver/ServiceUnavailableExample.java index 5c4205f306..2bc9dd7c3b 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/ServiceUnavailableExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/ServiceUnavailableExample.java @@ -20,6 +20,9 @@ // tag::service-unavailable-import[] +import static java.util.concurrent.TimeUnit.SECONDS; +// end::service-unavailable-import[] + import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @@ -28,42 +31,31 @@ import org.neo4j.driver.Session; import org.neo4j.driver.exceptions.ServiceUnavailableException; -import static java.util.concurrent.TimeUnit.SECONDS; -// end::service-unavailable-import[] - -public class ServiceUnavailableExample implements AutoCloseable -{ +public class ServiceUnavailableExample implements AutoCloseable { protected final Driver driver; - public ServiceUnavailableExample( String uri, String user, String password ) - { + public ServiceUnavailableExample(String uri, String user, String password) { Config config = Config.builder() - .withMaxTransactionRetryTime( 3, SECONDS ) - .withLogging( Logging.none() ) + .withMaxTransactionRetryTime(3, SECONDS) + .withLogging(Logging.none()) .build(); - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ), config ); + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config); } @Override - public void close() throws Exception - { + public void close() throws Exception { driver.close(); } // tag::service-unavailable[] - public boolean addItem() - { - try ( Session session = driver.session() ) - { - return session.writeTransaction( tx -> - { - tx.run( "CREATE (a:Item)" ).consume(); - return true; - } ); - } - catch ( ServiceUnavailableException ex ) - { + public boolean addItem() { + try (Session session = driver.session()) { + return session.writeTransaction(tx -> { + tx.run("CREATE (a:Item)").consume(); + return true; + }); + } catch (ServiceUnavailableException ex) { return false; } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/SessionExample.java b/examples/src/main/java/org/neo4j/docs/driver/SessionExample.java index b9e9f254a6..a0b31a5a24 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/SessionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/SessionExample.java @@ -20,24 +20,20 @@ // tag::session-import[] -import org.neo4j.driver.Session; - import static org.neo4j.driver.Values.parameters; // end::session-import[] -public class SessionExample extends BaseApplication -{ - public SessionExample( String uri, String user, String password ) - { - super( uri, user, password ); +import org.neo4j.driver.Session; + +public class SessionExample extends BaseApplication { + public SessionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::session[] - public void addPerson(String name) - { - try ( Session session = driver.session() ) - { - session.run("CREATE (a:Person {name: $name})", parameters( "name", name ) ); + public void addPerson(String name) { + try (Session session = driver.session()) { + session.run("CREATE (a:Person {name: $name})", parameters("name", name)); } } // end::session[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/Slf4jLoggingExample.java b/examples/src/main/java/org/neo4j/docs/driver/Slf4jLoggingExample.java index d03823f6e7..01b8325fb8 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/Slf4jLoggingExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/Slf4jLoggingExample.java @@ -18,6 +18,8 @@ */ package org.neo4j.docs.driver; +import static java.util.Collections.singletonMap; + import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @@ -25,32 +27,26 @@ import org.neo4j.driver.Logging; import org.neo4j.driver.Session; -import static java.util.Collections.singletonMap; - -public class Slf4jLoggingExample implements AutoCloseable -{ +public class Slf4jLoggingExample implements AutoCloseable { private final Driver driver; - public Slf4jLoggingExample( String uri, String user, String password ) - { - Config config = Config.builder() - .withLogging( Logging.slf4j() ) - .build(); + public Slf4jLoggingExample(String uri, String user, String password) { + Config config = Config.builder().withLogging(Logging.slf4j()).build(); - driver = GraphDatabase.driver( uri, AuthTokens.basic( user, password ), config ); + driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password), config); } - public Object runReturnQuery( Object value ) - { - try ( Session session = driver.session() ) - { - return session.run( "RETURN $x", singletonMap( "x", value ) ).single().get( 0 ).asObject(); + public Object runReturnQuery(Object value) { + try (Session session = driver.session()) { + return session.run("RETURN $x", singletonMap("x", value)) + .single() + .get(0) + .asObject(); } } @Override - public void close() - { + public void close() { driver.close(); } } diff --git a/examples/src/main/java/org/neo4j/docs/driver/TransactionFunctionExample.java b/examples/src/main/java/org/neo4j/docs/driver/TransactionFunctionExample.java index 008fb4d0a1..d7e3c20f82 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/TransactionFunctionExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/TransactionFunctionExample.java @@ -20,27 +20,24 @@ // tag::transaction-function-import[] -import org.neo4j.driver.Session; - import static org.neo4j.driver.Values.parameters; // end::transaction-function-import[] -public class TransactionFunctionExample extends BaseApplication -{ - public TransactionFunctionExample( String uri, String user, String password ) - { - super( uri, user, password ); +import org.neo4j.driver.Session; + +public class TransactionFunctionExample extends BaseApplication { + public TransactionFunctionExample(String uri, String user, String password) { + super(uri, user, password); } // tag::transaction-function[] - public void addPerson( final String name ) - { - try ( Session session = driver.session() ) - { - session.writeTransaction( tx -> { - tx.run( "CREATE (a:Person {name: $name})", parameters( "name", name ) ).consume(); + public void addPerson(final String name) { + try (Session session = driver.session()) { + session.writeTransaction(tx -> { + tx.run("CREATE (a:Person {name: $name})", parameters("name", name)) + .consume(); return 1; - } ); + }); } } // end::transaction-function[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/TransactionMetadataConfigExample.java b/examples/src/main/java/org/neo4j/docs/driver/TransactionMetadataConfigExample.java index 08bc8c2e98..4bab5454ce 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/TransactionMetadataConfigExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/TransactionMetadataConfigExample.java @@ -18,37 +18,35 @@ */ package org.neo4j.docs.driver; +import static org.neo4j.driver.Values.parameters; +import static org.neo4j.driver.Values.value; + import java.util.HashMap; import java.util.Map; - import org.neo4j.driver.Session; import org.neo4j.driver.TransactionConfig; -import static org.neo4j.driver.Values.parameters; -import static org.neo4j.driver.Values.value; - -public class TransactionMetadataConfigExample extends BaseApplication -{ - public TransactionMetadataConfigExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class TransactionMetadataConfigExample extends BaseApplication { + public TransactionMetadataConfigExample(String uri, String user, String password) { + super(uri, user, password); } // tag::transaction-metadata-config[] - public void addPerson( final String name ) - { - try ( Session session = driver.session() ) - { - Map transactionMetadata = new HashMap<>(); - transactionMetadata.put( "applicationId", value( "123" ) ); + public void addPerson(final String name) { + try (Session session = driver.session()) { + Map transactionMetadata = new HashMap<>(); + transactionMetadata.put("applicationId", value("123")); TransactionConfig txConfig = TransactionConfig.builder() - .withMetadata( transactionMetadata ).build(); - session.writeTransaction( tx -> - { - tx.run( "CREATE (a:Person {name: $name})", parameters( "name", name ) ).consume(); - return 1; - }, txConfig ); + .withMetadata(transactionMetadata) + .build(); + session.writeTransaction( + tx -> { + tx.run("CREATE (a:Person {name: $name})", parameters("name", name)) + .consume(); + return 1; + }, + txConfig); } } // end::transaction-metadata-config[] diff --git a/examples/src/main/java/org/neo4j/docs/driver/TransactionTimeoutConfigExample.java b/examples/src/main/java/org/neo4j/docs/driver/TransactionTimeoutConfigExample.java index 9d7b4fa3e4..661b18f1ab 100644 --- a/examples/src/main/java/org/neo4j/docs/driver/TransactionTimeoutConfigExample.java +++ b/examples/src/main/java/org/neo4j/docs/driver/TransactionTimeoutConfigExample.java @@ -19,32 +19,29 @@ package org.neo4j.docs.driver; -import java.time.Duration; +import static org.neo4j.driver.Values.parameters; +import java.time.Duration; import org.neo4j.driver.Session; import org.neo4j.driver.TransactionConfig; -import static org.neo4j.driver.Values.parameters; - -public class TransactionTimeoutConfigExample extends BaseApplication -{ - public TransactionTimeoutConfigExample( String uri, String user, String password ) - { - super( uri, user, password ); +public class TransactionTimeoutConfigExample extends BaseApplication { + public TransactionTimeoutConfigExample(String uri, String user, String password) { + super(uri, user, password); } // tag::transaction-timeout-config[] - public void addPerson( final String name ) - { - try ( Session session = driver.session() ) - { + public void addPerson(final String name) { + try (Session session = driver.session()) { TransactionConfig txConfig = TransactionConfig.builder() - .withTimeout( Duration.ofSeconds( 5 ) ).build(); - session.writeTransaction( tx -> - { - tx.run( "CREATE (a:Person {name: $name})", parameters( "name", name ) ); - return 1; - }, txConfig ); + .withTimeout(Duration.ofSeconds(5)) + .build(); + session.writeTransaction( + tx -> { + tx.run("CREATE (a:Person {name: $name})", parameters("name", name)); + return 1; + }, + txConfig); } } // end::transaction-timeout-config[] diff --git a/examples/src/test/java/org/neo4j/docs/driver/ExamplesIT.java b/examples/src/test/java/org/neo4j/docs/driver/ExamplesIT.java index 76bedc62a3..b92fce2084 100644 --- a/examples/src/test/java/org/neo4j/docs/driver/ExamplesIT.java +++ b/examples/src/test/java/org/neo4j/docs/driver/ExamplesIT.java @@ -18,35 +18,6 @@ */ package org.neo4j.docs.driver; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; - -import org.neo4j.driver.Config; -import org.neo4j.driver.Driver; -import org.neo4j.driver.Session; -import org.neo4j.driver.SessionConfig; -import org.neo4j.driver.Value; -import org.neo4j.driver.Values; -import org.neo4j.driver.exceptions.value.Uncoercible; -import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; -import org.neo4j.driver.summary.QueryType; -import org.neo4j.driver.summary.ResultSummary; -import org.neo4j.driver.util.DatabaseExtension; -import org.neo4j.driver.util.ParallelizableIT; -import org.neo4j.driver.util.StdIOCapture; -import org.neo4j.driver.util.TestUtil; - import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.asList; import static org.hamcrest.Matchers.containsString; @@ -71,700 +42,622 @@ import static org.neo4j.driver.util.TestUtil.createDatabase; import static org.neo4j.driver.util.TestUtil.dropDatabase; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.neo4j.driver.Config; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Session; +import org.neo4j.driver.SessionConfig; +import org.neo4j.driver.Value; +import org.neo4j.driver.Values; +import org.neo4j.driver.exceptions.value.Uncoercible; +import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; +import org.neo4j.driver.summary.QueryType; +import org.neo4j.driver.summary.ResultSummary; +import org.neo4j.driver.util.DatabaseExtension; +import org.neo4j.driver.util.ParallelizableIT; +import org.neo4j.driver.util.StdIOCapture; +import org.neo4j.driver.util.TestUtil; + @ParallelizableIT -@Execution( ExecutionMode.CONCURRENT ) -class ExamplesIT -{ +@Execution(ExecutionMode.CONCURRENT) +class ExamplesIT { @RegisterExtension static final DatabaseExtension neo4j = new DatabaseExtension(); private String uri; - private int readInt( String database, final String query, final Value parameters ) - { + private int readInt(String database, final String query, final Value parameters) { SessionConfig sessionConfig; - if ( database == null ) - { + if (database == null) { sessionConfig = SessionConfig.defaultConfig(); + } else { + sessionConfig = SessionConfig.forDatabase(database); } - else - { - sessionConfig = SessionConfig.forDatabase( database ); - } - try ( Session session = neo4j.driver().session( sessionConfig ) ) - { - return session.readTransaction( tx -> tx.run( query, parameters ).single().get( 0 ).asInt() ); + try (Session session = neo4j.driver().session(sessionConfig)) { + return session.readTransaction( + tx -> tx.run(query, parameters).single().get(0).asInt()); } } - private int readInt( final String query, final Value parameters ) - { - return readInt( null, query, parameters ); + private int readInt(final String query, final Value parameters) { + return readInt(null, query, parameters); } - private int readInt( final String query ) - { - return readInt( query, parameters() ); + private int readInt(final String query) { + return readInt(query, parameters()); } - private void write( final String query, final Value parameters ) - { - try ( Session session = neo4j.driver().session() ) - { - session.writeTransaction( tx -> - { - tx.run( query, parameters ).consume(); + private void write(final String query, final Value parameters) { + try (Session session = neo4j.driver().session()) { + session.writeTransaction(tx -> { + tx.run(query, parameters).consume(); return null; - } ); + }); } } - private void write( String query ) - { - write( query, parameters() ); + private void write(String query) { + write(query, parameters()); } - private int personCount( String name ) - { - return readInt( "MATCH (a:Person {name: $name}) RETURN count(a)", parameters( "name", name ) ); + private int personCount(String name) { + return readInt("MATCH (a:Person {name: $name}) RETURN count(a)", parameters("name", name)); } - private int companyCount( String name ) - { - return readInt( "MATCH (a:Company {name: $name}) RETURN count(a)", parameters( "name", name ) ); + private int companyCount(String name) { + return readInt("MATCH (a:Company {name: $name}) RETURN count(a)", parameters("name", name)); } @BeforeEach - void setUp() - { + void setUp() { uri = neo4j.uri().toString(); - TestUtil.cleanDb( neo4j.driver() ); + TestUtil.cleanDb(neo4j.driver()); } @Test - void testShouldRunAutocommitTransactionExample() throws Exception - { + void testShouldRunAutocommitTransactionExample() throws Exception { // Given - try ( AutocommitTransactionExample example = new AutocommitTransactionExample( uri, USER, PASSWORD ) ) - { + try (AutocommitTransactionExample example = new AutocommitTransactionExample(uri, USER, PASSWORD)) { // When - example.addPerson( "Alice" ); + example.addPerson("Alice"); // Then - assertThat( personCount( "Alice" ), greaterThan( 0 ) ); + assertThat(personCount("Alice"), greaterThan(0)); } } @Test - void testShouldRunAsyncAutocommitTransactionExample() throws Exception - { - try ( AsyncAutocommitTransactionExample example = new AsyncAutocommitTransactionExample( uri, USER, PASSWORD ) ) - { + void testShouldRunAsyncAutocommitTransactionExample() throws Exception { + try (AsyncAutocommitTransactionExample example = new AsyncAutocommitTransactionExample(uri, USER, PASSWORD)) { // create some 'Product' nodes - try ( Session session = neo4j.driver().session() ) - { - session.run( - "UNWIND ['Tesseract', 'Orb', 'Eye of Agamotto'] AS item " + - "CREATE (:Product {id: 0, title: item})" ); + try (Session session = neo4j.driver().session()) { + session.run("UNWIND ['Tesseract', 'Orb', 'Eye of Agamotto'] AS item " + + "CREATE (:Product {id: 0, title: item})"); } // read all 'Product' nodes - List titles = await( example.readProductTitles() ); - assertEquals( new HashSet<>( asList( "Tesseract", "Orb", "Eye of Agamotto" ) ), new HashSet<>( titles ) ); + List titles = await(example.readProductTitles()); + assertEquals(new HashSet<>(asList("Tesseract", "Orb", "Eye of Agamotto")), new HashSet<>(titles)); } } @Test - void testShouldAsyncRunResultConsumeExample() throws Exception - { + void testShouldAsyncRunResultConsumeExample() throws Exception { // Given - write( "CREATE (a:Person {name: 'Alice'})" ); - write( "CREATE (a:Person {name: 'Bob'})" ); - try ( AsyncResultConsumeExample example = new AsyncResultConsumeExample( uri, USER, PASSWORD ) ) - { + write("CREATE (a:Person {name: 'Alice'})"); + write("CREATE (a:Person {name: 'Bob'})"); + try (AsyncResultConsumeExample example = new AsyncResultConsumeExample(uri, USER, PASSWORD)) { // When - List names = await( example.getPeople() ); + List names = await(example.getPeople()); // Then - assertThat( names, equalTo( asList( "Alice", "Bob" ) ) ); + assertThat(names, equalTo(asList("Alice", "Bob"))); } } @Test - void testShouldAsyncRunMultipleTransactionExample() throws Exception - { + void testShouldAsyncRunMultipleTransactionExample() throws Exception { // Given - write( "CREATE (a:Person {name: 'Alice'})" ); - write( "CREATE (a:Person {name: 'Bob'})" ); - try ( AsyncRunMultipleTransactionExample example = new AsyncRunMultipleTransactionExample( uri, USER, PASSWORD ) ) - { + write("CREATE (a:Person {name: 'Alice'})"); + write("CREATE (a:Person {name: 'Bob'})"); + try (AsyncRunMultipleTransactionExample example = new AsyncRunMultipleTransactionExample(uri, USER, PASSWORD)) { // When - Integer nodesCreated = await( example.addEmployees("Acme") ); + Integer nodesCreated = await(example.addEmployees("Acme")); // Then - int employeeCount = readInt( - "MATCH (emp:Person)-[WORKS_FOR]->(com:Company) WHERE com.name = 'Acme' RETURN count(emp)" ); - assertThat( employeeCount, equalTo( 2 ) ); - assertThat( nodesCreated, equalTo( 1 ) ); + int employeeCount = + readInt("MATCH (emp:Person)-[WORKS_FOR]->(com:Company) WHERE com.name = 'Acme' RETURN count(emp)"); + assertThat(employeeCount, equalTo(2)); + assertThat(nodesCreated, equalTo(1)); } } @Test - void testShouldRunConfigConnectionPoolExample() throws Exception - { + void testShouldRunConfigConnectionPoolExample() throws Exception { // Given - try ( ConfigConnectionPoolExample example = new ConfigConnectionPoolExample( uri, USER, PASSWORD ) ) - { + try (ConfigConnectionPoolExample example = new ConfigConnectionPoolExample(uri, USER, PASSWORD)) { // Then - assertTrue( example.canConnect() ); + assertTrue(example.canConnect()); } } @Test - void testShouldRunBasicAuthExample() throws Exception - { + void testShouldRunBasicAuthExample() throws Exception { // Given - try ( BasicAuthExample example = new BasicAuthExample( uri, USER, PASSWORD ) ) - { + try (BasicAuthExample example = new BasicAuthExample(uri, USER, PASSWORD)) { // Then - assertTrue( example.canConnect() ); + assertTrue(example.canConnect()); } } @Test - void testShouldRunConfigConnectionTimeoutExample() throws Exception - { + void testShouldRunConfigConnectionTimeoutExample() throws Exception { // Given - try ( ConfigConnectionTimeoutExample example = new ConfigConnectionTimeoutExample( uri, USER, PASSWORD ) ) - { + try (ConfigConnectionTimeoutExample example = new ConfigConnectionTimeoutExample(uri, USER, PASSWORD)) { // Then - assertThat( example, instanceOf( ConfigConnectionTimeoutExample.class ) ); + assertThat(example, instanceOf(ConfigConnectionTimeoutExample.class)); } } @Test - void testShouldRunConfigMaxRetryTimeExample() throws Exception - { + void testShouldRunConfigMaxRetryTimeExample() throws Exception { // Given - try ( ConfigMaxRetryTimeExample example = new ConfigMaxRetryTimeExample( uri, USER, PASSWORD ) ) - { + try (ConfigMaxRetryTimeExample example = new ConfigMaxRetryTimeExample(uri, USER, PASSWORD)) { // Then - assertThat( example, instanceOf( ConfigMaxRetryTimeExample.class ) ); + assertThat(example, instanceOf(ConfigMaxRetryTimeExample.class)); } } @Test - void testShouldRunConfigTrustExample() throws Exception - { + void testShouldRunConfigTrustExample() throws Exception { // Given - try ( ConfigTrustExample example = new ConfigTrustExample( uri, USER, PASSWORD ) ) - { + try (ConfigTrustExample example = new ConfigTrustExample(uri, USER, PASSWORD)) { // Then - assertThat( example, instanceOf( ConfigTrustExample.class ) ); + assertThat(example, instanceOf(ConfigTrustExample.class)); } } @Test - void testShouldRunConfigUnencryptedExample() throws Exception - { + void testShouldRunConfigUnencryptedExample() throws Exception { // Given - try ( ConfigUnencryptedExample example = new ConfigUnencryptedExample( uri, USER, PASSWORD ) ) - { + try (ConfigUnencryptedExample example = new ConfigUnencryptedExample(uri, USER, PASSWORD)) { // Then - assertThat( example, instanceOf( ConfigUnencryptedExample.class ) ); + assertThat(example, instanceOf(ConfigUnencryptedExample.class)); } } @Test - void testShouldRunCypherErrorExample() throws Exception - { + void testShouldRunCypherErrorExample() throws Exception { // Given - try ( CypherErrorExample example = new CypherErrorExample( uri, USER, PASSWORD ) ) - { + try (CypherErrorExample example = new CypherErrorExample(uri, USER, PASSWORD)) { // When & Then StdIOCapture stdIO = new StdIOCapture(); - try ( AutoCloseable ignored = stdIO.capture() ) - { - int employeeNumber = example.getEmployeeNumber( "Alice" ); + try (AutoCloseable ignored = stdIO.capture()) { + int employeeNumber = example.getEmployeeNumber("Alice"); - assertThat( employeeNumber, equalTo( -1 ) ); + assertThat(employeeNumber, equalTo(-1)); } - assertThat( stdIO.stderr().toString(), containsString( "Invalid input" ) ); + assertThat(stdIO.stderr().toString(), containsString("Invalid input")); } } @Test - void testShouldRunDriverLifecycleExample() throws Exception - { + void testShouldRunDriverLifecycleExample() throws Exception { // Given - try ( DriverLifecycleExample example = new DriverLifecycleExample( uri, USER, PASSWORD ) ) - { + try (DriverLifecycleExample example = new DriverLifecycleExample(uri, USER, PASSWORD)) { // Then - assertThat( example, instanceOf( DriverLifecycleExample.class ) ); + assertThat(example, instanceOf(DriverLifecycleExample.class)); } } @Test - void testShouldRunHelloWorld() throws Exception - { + void testShouldRunHelloWorld() throws Exception { // Given - try ( HelloWorldExample greeter = new HelloWorldExample( uri, USER, PASSWORD ) ) - { + try (HelloWorldExample greeter = new HelloWorldExample(uri, USER, PASSWORD)) { // When StdIOCapture stdIO = new StdIOCapture(); - try ( AutoCloseable ignored = stdIO.capture() ) - { - greeter.printGreeting( "hello, world" ); + try (AutoCloseable ignored = stdIO.capture()) { + greeter.printGreeting("hello, world"); } // Then - assertThat( stdIO.stdout().size(), equalTo( 1 ) ); - assertThat( stdIO.stdout().get( 0 ), containsString( "hello, world" ) ); + assertThat(stdIO.stdout().size(), equalTo(1)); + assertThat(stdIO.stdout().get(0), containsString("hello, world")); } } @Test - void testShouldRunDriverIntroduction() throws Exception - { + void testShouldRunDriverIntroduction() throws Exception { // Given - Config config = Config.builder().withEncryption().withTrustStrategy(trustAllCertificates()).build(); - try (DriverIntroductionExample intro = new DriverIntroductionExample( uri, USER, PASSWORD, config) ) - { + Config config = Config.builder() + .withEncryption() + .withTrustStrategy(trustAllCertificates()) + .build(); + try (DriverIntroductionExample intro = new DriverIntroductionExample(uri, USER, PASSWORD, config)) { // When StdIOCapture stdIO = new StdIOCapture(); - try ( AutoCloseable ignored = stdIO.capture() ) - { - intro.createFriendship( "Alice", "David", "School" ); - intro.findPerson( "Alice" ); + try (AutoCloseable ignored = stdIO.capture()) { + intro.createFriendship("Alice", "David", "School"); + intro.findPerson("Alice"); } // Then - assertThat( stdIO.stdout().size(), equalTo( 2 ) ); - assertThat( stdIO.stdout().get( 0 ), containsString( "Created friendship between: Alice, David from School" ) ); - assertThat( stdIO.stdout().get( 1 ), containsString( "Found person: Alice" ) ); + assertThat(stdIO.stdout().size(), equalTo(2)); + assertThat(stdIO.stdout().get(0), containsString("Created friendship between: Alice, David from School")); + assertThat(stdIO.stdout().get(1), containsString("Found person: Alice")); } } @Test - void testShouldRunReadWriteTransactionExample() throws Exception - { + void testShouldRunReadWriteTransactionExample() throws Exception { // Given - try ( ReadWriteTransactionExample example = new ReadWriteTransactionExample( uri, USER, PASSWORD ) ) - { + try (ReadWriteTransactionExample example = new ReadWriteTransactionExample(uri, USER, PASSWORD)) { // When - long nodeID = example.addPerson( "Alice" ); + long nodeID = example.addPerson("Alice"); // Then - assertThat( nodeID, greaterThanOrEqualTo( 0L ) ); + assertThat(nodeID, greaterThanOrEqualTo(0L)); } } @Test - void testShouldRunResultConsumeExample() throws Exception - { + void testShouldRunResultConsumeExample() throws Exception { // Given - write( "CREATE (a:Person {name: 'Alice'})" ); - write( "CREATE (a:Person {name: 'Bob'})" ); - try ( ResultConsumeExample example = new ResultConsumeExample( uri, USER, PASSWORD ) ) - { + write("CREATE (a:Person {name: 'Alice'})"); + write("CREATE (a:Person {name: 'Bob'})"); + try (ResultConsumeExample example = new ResultConsumeExample(uri, USER, PASSWORD)) { // When List names = example.getPeople(); // Then - assertThat( names, equalTo( asList( "Alice", "Bob" ) ) ); + assertThat(names, equalTo(asList("Alice", "Bob"))); } } @Test - void testShouldRunResultRetainExample() throws Exception - { + void testShouldRunResultRetainExample() throws Exception { // Given - write( "CREATE (a:Person {name: 'Alice'})" ); - write( "CREATE (a:Person {name: 'Bob'})" ); - try ( ResultRetainExample example = new ResultRetainExample( uri, USER, PASSWORD ) ) - { + write("CREATE (a:Person {name: 'Alice'})"); + write("CREATE (a:Person {name: 'Bob'})"); + try (ResultRetainExample example = new ResultRetainExample(uri, USER, PASSWORD)) { // When - example.addEmployees( "Acme" ); + example.addEmployees("Acme"); // Then - int employeeCount = readInt( - "MATCH (emp:Person)-[WORKS_FOR]->(com:Company) WHERE com.name = 'Acme' RETURN count(emp)" ); - assertThat( employeeCount, equalTo( 2 ) ); + int employeeCount = + readInt("MATCH (emp:Person)-[WORKS_FOR]->(com:Company) WHERE com.name = 'Acme' RETURN count(emp)"); + assertThat(employeeCount, equalTo(2)); } } @Test - void testShouldRunServiceUnavailableExample() throws Exception - { + void testShouldRunServiceUnavailableExample() throws Exception { // Given - try ( ServiceUnavailableExample example = new ServiceUnavailableExample( uri, USER, PASSWORD ) ) - { - try - { + try (ServiceUnavailableExample example = new ServiceUnavailableExample(uri, USER, PASSWORD)) { + try { // When neo4j.stopDb(); // Then - assertThat( example.addItem(), equalTo( false ) ); - } - finally - { + assertThat(example.addItem(), equalTo(false)); + } finally { neo4j.startDb(); } } } @Test - void testShouldRunSessionExample() throws Exception - { + void testShouldRunSessionExample() throws Exception { // Given - try ( SessionExample example = new SessionExample( uri, USER, PASSWORD ) ) - { + try (SessionExample example = new SessionExample(uri, USER, PASSWORD)) { // When - example.addPerson( "Alice" ); + example.addPerson("Alice"); // Then - assertThat( example, instanceOf( SessionExample.class ) ); - assertThat( personCount( "Alice" ), greaterThan( 0 ) ); + assertThat(example, instanceOf(SessionExample.class)); + assertThat(personCount("Alice"), greaterThan(0)); } } @Test - void testShouldRunTransactionFunctionExample() throws Exception - { + void testShouldRunTransactionFunctionExample() throws Exception { // Given - try ( TransactionFunctionExample example = new TransactionFunctionExample( uri, USER, PASSWORD ) ) - { + try (TransactionFunctionExample example = new TransactionFunctionExample(uri, USER, PASSWORD)) { // When - example.addPerson( "Alice" ); + example.addPerson("Alice"); // Then - assertThat( personCount( "Alice" ), greaterThan( 0 ) ); + assertThat(personCount("Alice"), greaterThan(0)); } } @Test - void testShouldConfigureTransactionTimeoutExample() throws Exception - { + void testShouldConfigureTransactionTimeoutExample() throws Exception { // Given - try ( TransactionTimeoutConfigExample example = new TransactionTimeoutConfigExample( uri, USER, PASSWORD ) ) - { + try (TransactionTimeoutConfigExample example = new TransactionTimeoutConfigExample(uri, USER, PASSWORD)) { // When - example.addPerson( "Alice" ); + example.addPerson("Alice"); // Then - assertThat( personCount( "Alice" ), greaterThan( 0 ) ); + assertThat(personCount("Alice"), greaterThan(0)); } } @Test - void testShouldConfigureTransactionMetadataExample() throws Exception - { + void testShouldConfigureTransactionMetadataExample() throws Exception { // Given - try ( TransactionMetadataConfigExample example = new TransactionMetadataConfigExample( uri, USER, PASSWORD ) ) - { + try (TransactionMetadataConfigExample example = new TransactionMetadataConfigExample(uri, USER, PASSWORD)) { // When - example.addPerson( "Alice" ); + example.addPerson("Alice"); // Then - assertThat( personCount( "Alice" ), greaterThan( 0 ) ); + assertThat(personCount("Alice"), greaterThan(0)); } } @Test - void testShouldRunAsyncTransactionFunctionExample() throws Exception - { - try ( AsyncTransactionFunctionExample example = new AsyncTransactionFunctionExample( uri, USER, PASSWORD ) ) - { + void testShouldRunAsyncTransactionFunctionExample() throws Exception { + try (AsyncTransactionFunctionExample example = new AsyncTransactionFunctionExample(uri, USER, PASSWORD)) { // create some 'Product' nodes - try ( Session session = neo4j.driver().session() ) - { + try (Session session = neo4j.driver().session()) { session.run( - "UNWIND ['Infinity Gauntlet', 'Mjölnir'] AS item " + - "CREATE (:Product {id: 0, title: item})" ); + "UNWIND ['Infinity Gauntlet', 'Mjölnir'] AS item " + "CREATE (:Product {id: 0, title: item})"); } StdIOCapture stdIOCapture = new StdIOCapture(); // print all 'Product' nodes to fake stdout - try ( AutoCloseable ignore = stdIOCapture.capture() ) - { - ResultSummary summary = await( example.printAllProducts() ); - assertEquals( QueryType.READ_ONLY, summary.queryType() ); + try (AutoCloseable ignore = stdIOCapture.capture()) { + ResultSummary summary = await(example.printAllProducts()); + assertEquals(QueryType.READ_ONLY, summary.queryType()); } - Set capturedOutput = new HashSet<>( stdIOCapture.stdout() ); - assertEquals( new HashSet<>( asList( "Infinity Gauntlet", "Mjölnir" ) ), capturedOutput ); + Set capturedOutput = new HashSet<>(stdIOCapture.stdout()); + assertEquals(new HashSet<>(asList("Infinity Gauntlet", "Mjölnir")), capturedOutput); } } @Test - void testPassBookmarksExample() throws Exception - { - try ( PassBookmarkExample example = new PassBookmarkExample( uri, USER, PASSWORD ) ) - { + void testPassBookmarksExample() throws Exception { + try (PassBookmarkExample example = new PassBookmarkExample(uri, USER, PASSWORD)) { // When example.addEmployAndMakeFriends(); // Then - assertThat( companyCount( "Wayne Enterprises" ), is( 1 ) ); - assertThat( companyCount( "LexCorp" ), is( 1 ) ); - assertThat( personCount( "Alice" ), is( 1 ) ); - assertThat( personCount( "Bob" ), is( 1 ) ); + assertThat(companyCount("Wayne Enterprises"), is(1)); + assertThat(companyCount("LexCorp"), is(1)); + assertThat(personCount("Alice"), is(1)); + assertThat(personCount("Bob"), is(1)); int employeeCountOfWayne = readInt( - "MATCH (emp:Person)-[WORKS_FOR]->(com:Company) WHERE com.name = 'Wayne Enterprises' RETURN count(emp)" ); - assertThat( employeeCountOfWayne, is( 1 ) ); + "MATCH (emp:Person)-[WORKS_FOR]->(com:Company) WHERE com.name = 'Wayne Enterprises' RETURN count(emp)"); + assertThat(employeeCountOfWayne, is(1)); int employeeCountOfLexCorp = readInt( - "MATCH (emp:Person)-[WORKS_FOR]->(com:Company) WHERE com.name = 'LexCorp' RETURN count(emp)" ); - assertThat( employeeCountOfLexCorp, is( 1 ) ); + "MATCH (emp:Person)-[WORKS_FOR]->(com:Company) WHERE com.name = 'LexCorp' RETURN count(emp)"); + assertThat(employeeCountOfLexCorp, is(1)); - int friendCount = readInt( - "MATCH (a:Person {name: 'Alice'})-[:KNOWS]->(b:Person {name: 'Bob'}) RETURN count(a)" ); - assertThat( friendCount, is( 1 ) ); + int friendCount = + readInt("MATCH (a:Person {name: 'Alice'})-[:KNOWS]->(b:Person {name: 'Bob'}) RETURN count(a)"); + assertThat(friendCount, is(1)); } } @Test - void testAsyncUnmanagedTransactionExample() throws Exception - { - try ( AsyncUnmanagedTransactionExample example = new AsyncUnmanagedTransactionExample( uri, USER, PASSWORD ) ) - { + void testAsyncUnmanagedTransactionExample() throws Exception { + try (AsyncUnmanagedTransactionExample example = new AsyncUnmanagedTransactionExample(uri, USER, PASSWORD)) { // create a 'Product' node - try ( Session session = neo4j.driver().session() ) - { - session.run( "CREATE (:Product {id: 0, title: 'Mind Gem'})" ); + try (Session session = neo4j.driver().session()) { + session.run("CREATE (:Product {id: 0, title: 'Mind Gem'})"); } StdIOCapture stdIOCapture = new StdIOCapture(); // print the single 'Product' node - try ( AutoCloseable ignore = stdIOCapture.capture() ) - { - await( example.printSingleProduct() ); + try (AutoCloseable ignore = stdIOCapture.capture()) { + await(example.printSingleProduct()); } - assertEquals( 1, stdIOCapture.stdout().size() ); - assertEquals( "Mind Gem", stdIOCapture.stdout().get( 0 ) ); + assertEquals(1, stdIOCapture.stdout().size()); + assertEquals("Mind Gem", stdIOCapture.stdout().get(0)); } } @Test - void testSlf4jLogging() throws Exception - { + void testSlf4jLogging() throws Exception { // log file is defined in logback-test.xml configuration file - Path logFile = Paths.get( "target", "test.log" ); - if ( Files.exists( logFile ) ) - { + Path logFile = Paths.get("target", "test.log"); + if (Files.exists(logFile)) { // delete file made this test flaky // erase content instead - Files.write( logFile, new byte[0] ); + Files.write(logFile, new byte[0]); } // verify erased - String logFileContent = new String( Files.readAllBytes( logFile ), UTF_8 ); - assertThat( logFileContent, is( emptyString() ) ); + String logFileContent = new String(Files.readAllBytes(logFile), UTF_8); + assertThat(logFileContent, is(emptyString())); String randomString = UUID.randomUUID().toString(); - try ( Slf4jLoggingExample example = new Slf4jLoggingExample( uri, USER, PASSWORD ) ) - { - Object result = example.runReturnQuery( randomString ); - assertEquals( randomString, result ); + try (Slf4jLoggingExample example = new Slf4jLoggingExample(uri, USER, PASSWORD)) { + Object result = example.runReturnQuery(randomString); + assertEquals(randomString, result); } - assertTrue( Files.exists( logFile ) ); - - logFileContent = new String( Files.readAllBytes( logFile ), UTF_8 ); - assertThat( logFileContent, containsString( "RETURN $x" ) ); - assertThat( logFileContent, containsString( randomString ) ); + assertTrue(Files.exists(logFile)); + logFileContent = new String(Files.readAllBytes(logFile), UTF_8); + assertThat(logFileContent, containsString("RETURN $x")); + assertThat(logFileContent, containsString(randomString)); } @Test - void testHostnameVerificationExample() - { - try ( HostnameVerificationExample example = new HostnameVerificationExample( uri, USER, PASSWORD, neo4j.tlsCertFile() ) ) - { - assertTrue( example.canConnect() ); + void testHostnameVerificationExample() { + try (HostnameVerificationExample example = + new HostnameVerificationExample(uri, USER, PASSWORD, neo4j.tlsCertFile())) { + assertTrue(example.canConnect()); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void testShouldRunRxAutocommitTransactionExample() throws Exception - { - try ( RxAutocommitTransactionExample example = new RxAutocommitTransactionExample( uri, USER, PASSWORD ) ) - { + @EnabledOnNeo4jWith(BOLT_V4) + void testShouldRunRxAutocommitTransactionExample() throws Exception { + try (RxAutocommitTransactionExample example = new RxAutocommitTransactionExample(uri, USER, PASSWORD)) { // create some 'Product' nodes - try ( Session session = neo4j.driver().session() ) - { - session.run( - "UNWIND ['Tesseract', 'Orb', 'Eye of Agamotto'] AS item " + - "CREATE (:Product {id: 0, title: item})" ); + try (Session session = neo4j.driver().session()) { + session.run("UNWIND ['Tesseract', 'Orb', 'Eye of Agamotto'] AS item " + + "CREATE (:Product {id: 0, title: item})"); } // read all 'Product' nodes - List titles = await( example.readProductTitles() ); - assertEquals( new HashSet<>( asList( "Tesseract", "Orb", "Eye of Agamotto" ) ), new HashSet<>( titles ) ); + List titles = await(example.readProductTitles()); + assertEquals(new HashSet<>(asList("Tesseract", "Orb", "Eye of Agamotto")), new HashSet<>(titles)); - titles = await( example.readProductTitlesRxJava() ); - assertEquals( new HashSet<>( asList( "Tesseract", "Orb", "Eye of Agamotto" ) ), new HashSet<>( titles ) ); + titles = await(example.readProductTitlesRxJava()); + assertEquals(new HashSet<>(asList("Tesseract", "Orb", "Eye of Agamotto")), new HashSet<>(titles)); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void testRxUnmanagedTransactionExample() throws Exception - { - try ( RxUnmanagedTransactionExample example = new RxUnmanagedTransactionExample( uri, USER, PASSWORD ) ) - { + @EnabledOnNeo4jWith(BOLT_V4) + void testRxUnmanagedTransactionExample() throws Exception { + try (RxUnmanagedTransactionExample example = new RxUnmanagedTransactionExample(uri, USER, PASSWORD)) { // create a 'Product' node - try ( Session session = neo4j.driver().session() ) - { - session.run( "CREATE (:Product {id: 0, title: 'Mind Gem'})" ); + try (Session session = neo4j.driver().session()) { + session.run("CREATE (:Product {id: 0, title: 'Mind Gem'})"); } - List products = await( example.readSingleProduct() ); - assertEquals( 1, products.size() ); - assertEquals( "Mind Gem", products.get( 0 ) ); - - products = await( example.readSingleProductRxJava() ); - assertEquals( 1, products.size() ); - assertEquals( "Mind Gem", products.get( 0 ) ); + List products = await(example.readSingleProduct()); + assertEquals(1, products.size()); + assertEquals("Mind Gem", products.get(0)); + products = await(example.readSingleProductRxJava()); + assertEquals(1, products.size()); + assertEquals("Mind Gem", products.get(0)); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void testShouldRunRxTransactionFunctionExampleReactor() throws Exception - { - try ( RxTransactionFunctionExample example = new RxTransactionFunctionExample( uri, USER, PASSWORD ) ) - { + @EnabledOnNeo4jWith(BOLT_V4) + void testShouldRunRxTransactionFunctionExampleReactor() throws Exception { + try (RxTransactionFunctionExample example = new RxTransactionFunctionExample(uri, USER, PASSWORD)) { // create some 'Product' nodes - try ( Session session = neo4j.driver().session() ) - { + try (Session session = neo4j.driver().session()) { session.run( - "UNWIND ['Infinity Gauntlet', 'Mjölnir'] AS item " + - "CREATE (:Product {id: 0, title: item})" ); + "UNWIND ['Infinity Gauntlet', 'Mjölnir'] AS item " + "CREATE (:Product {id: 0, title: item})"); } StdIOCapture stdIOCapture = new StdIOCapture(); // print all 'Product' nodes to fake stdout - try ( AutoCloseable ignore = stdIOCapture.capture() ) - { - final List summaryList = await( example.printAllProducts() ); - assertThat( summaryList.size(), equalTo( 1 ) ); - ResultSummary summary = summaryList.get( 0 ); - assertEquals( QueryType.READ_ONLY, summary.queryType() ); + try (AutoCloseable ignore = stdIOCapture.capture()) { + final List summaryList = await(example.printAllProducts()); + assertThat(summaryList.size(), equalTo(1)); + ResultSummary summary = summaryList.get(0); + assertEquals(QueryType.READ_ONLY, summary.queryType()); } - Set capturedOutput = new HashSet<>( stdIOCapture.stdout() ); - assertEquals( new HashSet<>( asList( "Infinity Gauntlet", "Mjölnir" ) ), capturedOutput ); + Set capturedOutput = new HashSet<>(stdIOCapture.stdout()); + assertEquals(new HashSet<>(asList("Infinity Gauntlet", "Mjölnir")), capturedOutput); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void testShouldRunRxTransactionFunctionExampleRxJava() throws Exception - { - try ( RxTransactionFunctionExample example = new RxTransactionFunctionExample( uri, USER, PASSWORD ) ) - { + @EnabledOnNeo4jWith(BOLT_V4) + void testShouldRunRxTransactionFunctionExampleRxJava() throws Exception { + try (RxTransactionFunctionExample example = new RxTransactionFunctionExample(uri, USER, PASSWORD)) { // create some 'Product' nodes - try ( Session session = neo4j.driver().session() ) - { + try (Session session = neo4j.driver().session()) { session.run( - "UNWIND ['Infinity Gauntlet', 'Mjölnir'] AS item " + - "CREATE (:Product {id: 0, title: item})" ); + "UNWIND ['Infinity Gauntlet', 'Mjölnir'] AS item " + "CREATE (:Product {id: 0, title: item})"); } StdIOCapture stdIOCapture = new StdIOCapture(); // print all 'Product' nodes to fake stdout - try ( AutoCloseable ignore = stdIOCapture.capture() ) - { - final List summaryList = await( example.printAllProductsRxJava() ); - assertThat( summaryList.size(), equalTo( 1 ) ); - ResultSummary summary = summaryList.get( 0 ); - assertEquals( QueryType.READ_ONLY, summary.queryType() ); + try (AutoCloseable ignore = stdIOCapture.capture()) { + final List summaryList = await(example.printAllProductsRxJava()); + assertThat(summaryList.size(), equalTo(1)); + ResultSummary summary = summaryList.get(0); + assertEquals(QueryType.READ_ONLY, summary.queryType()); } - Set capturedOutput = new HashSet<>( stdIOCapture.stdout() ); - assertEquals( new HashSet<>( asList( "Infinity Gauntlet", "Mjölnir" ) ), capturedOutput ); + Set capturedOutput = new HashSet<>(stdIOCapture.stdout()); + assertEquals(new HashSet<>(asList("Infinity Gauntlet", "Mjölnir")), capturedOutput); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void testShouldRunRxResultConsumeExampleReactor() throws Exception - { + @EnabledOnNeo4jWith(BOLT_V4) + void testShouldRunRxResultConsumeExampleReactor() throws Exception { // Given - write( "CREATE (a:Person {name: 'Alice'})" ); - write( "CREATE (a:Person {name: 'Bob'})" ); - try ( RxResultConsumeExample example = new RxResultConsumeExample( uri, USER, PASSWORD ) ) - { + write("CREATE (a:Person {name: 'Alice'})"); + write("CREATE (a:Person {name: 'Bob'})"); + try (RxResultConsumeExample example = new RxResultConsumeExample(uri, USER, PASSWORD)) { // When - List names = await( example.getPeople() ); + List names = await(example.getPeople()); // Then - assertThat( names, equalTo( asList( "Alice", "Bob" ) ) ); + assertThat(names, equalTo(asList("Alice", "Bob"))); } } @Test - @EnabledOnNeo4jWith( BOLT_V4 ) - void testShouldRunRxResultConsumeExampleRxJava() throws Exception - { + @EnabledOnNeo4jWith(BOLT_V4) + void testShouldRunRxResultConsumeExampleRxJava() throws Exception { // Given - write( "CREATE (a:Person {name: 'Alice'})" ); - write( "CREATE (a:Person {name: 'Bob'})" ); - try ( RxResultConsumeExample example = new RxResultConsumeExample( uri, USER, PASSWORD ) ) - { + write("CREATE (a:Person {name: 'Alice'})"); + write("CREATE (a:Person {name: 'Bob'})"); + try (RxResultConsumeExample example = new RxResultConsumeExample(uri, USER, PASSWORD)) { // When - List names = await( example.getPeopleRxJava() ); + List names = await(example.getPeopleRxJava()); // Then - assertThat( names, equalTo( asList( "Alice", "Bob" ) ) ); + assertThat(names, equalTo(asList("Alice", "Bob"))); } } @Test - @EnabledOnNeo4jWith( value = BOLT_V4, edition = ENTERPRISE) - void testUseAnotherDatabaseExample() throws Exception - { + @EnabledOnNeo4jWith(value = BOLT_V4, edition = ENTERPRISE) + void testUseAnotherDatabaseExample() throws Exception { Driver driver = neo4j.driver(); - dropDatabase( driver, "examples" ); - createDatabase( driver, "examples" ); + dropDatabase(driver, "examples"); + createDatabase(driver, "examples"); - try ( DatabaseSelectionExample example = new DatabaseSelectionExample( uri, USER, PASSWORD ) ) - { + try (DatabaseSelectionExample example = new DatabaseSelectionExample(uri, USER, PASSWORD)) { // When example.useAnotherDatabaseExample(); // Then - int greetingCount = readInt( "examples", "MATCH (a:Greeting) RETURN count(a)", Values.parameters() ); - assertThat( greetingCount, is( 1 ) ); + int greetingCount = readInt("examples", "MATCH (a:Greeting) RETURN count(a)", Values.parameters()); + assertThat(greetingCount, is(1)); } } @Test - void testReadingValuesExample() throws Exception - { - try (ReadingValuesExample example = new ReadingValuesExample( uri, USER, PASSWORD )) - { - assertThat( example.integerFieldIsNull(), is(false) ); - assertThat( example.integerAsInteger(), is( 4 ) ); - assertThat( example.integerAsLong(), is( 4L ) ); - assertThrows( Uncoercible.class, example::integerAsString ); + void testReadingValuesExample() throws Exception { + try (ReadingValuesExample example = new ReadingValuesExample(uri, USER, PASSWORD)) { + assertThat(example.integerFieldIsNull(), is(false)); + assertThat(example.integerAsInteger(), is(4)); + assertThat(example.integerAsLong(), is(4L)); + assertThrows(Uncoercible.class, example::integerAsString); - assertThat( example.nullIsNull(), is(true) ); - assertThat( example.nullAsString(), is( "null" ) ); - assertThat( example.nullAsObject(), nullValue()); - assertThat( example.nullAsObjectFloatDefaultValue(), is( 1.0f ) ); - assertThrows( Uncoercible.class, example::nullAsObjectFloat ); + assertThat(example.nullIsNull(), is(true)); + assertThat(example.nullAsString(), is("null")); + assertThat(example.nullAsObject(), nullValue()); + assertThat(example.nullAsObjectFloatDefaultValue(), is(1.0f)); + assertThrows(Uncoercible.class, example::nullAsObjectFloat); } } } diff --git a/examples/src/test/java/org/neo4j/docs/driver/RoutingExamplesIT.java b/examples/src/test/java/org/neo4j/docs/driver/RoutingExamplesIT.java index 200acc99a3..a02d216e4f 100644 --- a/examples/src/test/java/org/neo4j/docs/driver/RoutingExamplesIT.java +++ b/examples/src/test/java/org/neo4j/docs/driver/RoutingExamplesIT.java @@ -18,31 +18,26 @@ */ package org.neo4j.docs.driver; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.net.URI; - +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.driver.net.ServerAddress; import org.neo4j.driver.util.cc.ClusterExtension; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class RoutingExamplesIT -{ +class RoutingExamplesIT { @RegisterExtension static final ClusterExtension neo4j = new ClusterExtension(); @Test - void testShouldRunConfigCustomResolverExample() throws Exception - { + void testShouldRunConfigCustomResolverExample() throws Exception { // Given URI uri = neo4j.getCluster().getRoutingUri(); - try ( ConfigCustomResolverExample example = new ConfigCustomResolverExample( "neo4j://x.example.com", neo4j.getDefaultAuthToken(), - ServerAddress.of( uri.getHost(), uri.getPort() ) ) ) - { + try (ConfigCustomResolverExample example = new ConfigCustomResolverExample( + "neo4j://x.example.com", neo4j.getDefaultAuthToken(), ServerAddress.of(uri.getHost(), uri.getPort()))) { // Then - assertTrue( example.canConnect() ); + assertTrue(example.canConnect()); } } } diff --git a/pom.xml b/pom.xml index 66ccd2efa1..f0e4223fa7 100644 --- a/pom.xml +++ b/pom.xml @@ -345,6 +345,51 @@ maven-shade-plugin 3.2.0 + + com.diffplug.spotless + spotless-maven-plugin + 2.21.0 + + + + check + + + + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0 + + + de.skuzzle.enforcer + restrict-imports-enforcer-rule + 2.0.0 + + + + + + enforce + + + + + + + Star imports are not allowed, please configure your editor to substitute them with fully qualified imports. + **.'*' + + + true + + @@ -501,6 +546,14 @@ false + + com.diffplug.spotless + spotless-maven-plugin + + + org.apache.maven.plugins + maven-enforcer-plugin + diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java index b1f09baeea..e3d76fa4b9 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java @@ -30,49 +30,37 @@ import neo4j.org.testkit.backend.channel.handler.TestkitRequestProcessorHandler; import neo4j.org.testkit.backend.channel.handler.TestkitRequestResponseMapperHandler; -public class Runner -{ - public static void main( String[] args ) throws InterruptedException - { +public class Runner { + public static void main(String[] args) throws InterruptedException { TestkitRequestProcessorHandler.BackendMode backendMode; String modeArg = args.length > 0 ? args[0] : null; - if ( "async".equals( modeArg ) ) - { + if ("async".equals(modeArg)) { backendMode = TestkitRequestProcessorHandler.BackendMode.ASYNC; - } - else if ( "reactive".equals( modeArg ) ) - { + } else if ("reactive".equals(modeArg)) { backendMode = TestkitRequestProcessorHandler.BackendMode.REACTIVE; - } - else - { + } else { backendMode = TestkitRequestProcessorHandler.BackendMode.SYNC; } EventLoopGroup group = new NioEventLoopGroup(); - try - - { + try { ServerBootstrap bootstrap = new ServerBootstrap(); - bootstrap.group( group ) - .channel( NioServerSocketChannel.class ) - .localAddress( 9876 ) - .childHandler( new ChannelInitializer() - { - @Override - protected void initChannel( SocketChannel channel ) - { - channel.pipeline().addLast( new TestkitMessageInboundHandler() ); - channel.pipeline().addLast( new TestkitMessageOutboundHandler() ); - channel.pipeline().addLast( new TestkitRequestResponseMapperHandler() ); - channel.pipeline().addLast( new TestkitRequestProcessorHandler( backendMode ) ); - } - } ); + bootstrap + .group(group) + .channel(NioServerSocketChannel.class) + .localAddress(9876) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel channel) { + channel.pipeline().addLast(new TestkitMessageInboundHandler()); + channel.pipeline().addLast(new TestkitMessageOutboundHandler()); + channel.pipeline().addLast(new TestkitRequestResponseMapperHandler()); + channel.pipeline().addLast(new TestkitRequestProcessorHandler(backendMode)); + } + }); ChannelFuture server = bootstrap.bind().sync(); server.channel().closeFuture().sync(); - } - finally - { + } finally { group.shutdownGracefully().sync(); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/RxBufferedSubscriber.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/RxBufferedSubscriber.java index 2264c553ae..436016690d 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/RxBufferedSubscriber.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/RxBufferedSubscriber.java @@ -18,6 +18,11 @@ */ package neo4j.org.testkit.backend; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Supplier; import org.reactivestreams.Subscription; import reactor.core.publisher.BaseSubscriber; import reactor.core.publisher.Flux; @@ -25,12 +30,6 @@ import reactor.core.publisher.Mono; import reactor.core.publisher.MonoSink; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Supplier; - /** * Buffered subscriber for testing purposes. *

@@ -42,8 +41,7 @@ * * @param */ -public class RxBufferedSubscriber extends BaseSubscriber -{ +public class RxBufferedSubscriber extends BaseSubscriber { private final Lock lock = new ReentrantLock(); private final long fetchSize; private final CompletableFuture subscriptionFuture = new CompletableFuture<>(); @@ -52,16 +50,15 @@ public class RxBufferedSubscriber extends BaseSubscriber private long pendingItems; private boolean nextInProgress; - public RxBufferedSubscriber( long fetchSize ) - { + public RxBufferedSubscriber(long fetchSize) { this.fetchSize = fetchSize; AtomicReference> sinkRef = new AtomicReference<>(); itemsSubscriber = new OneSignalSubscriber<>(); - Flux.create( fluxSink -> - { - sinkRef.set( fluxSink ); - fluxSink.onRequest( ignored -> requestFromUpstream() ); - } ).subscribe( itemsSubscriber ); + Flux.create(fluxSink -> { + sinkRef.set(fluxSink); + fluxSink.onRequest(ignored -> requestFromUpstream()); + }) + .subscribe(itemsSubscriber); itemsSink = sinkRef.get(); } @@ -76,166 +73,128 @@ public RxBufferedSubscriber( long fetchSize ) * * @return the {@link Mono} of next signal. */ - public Mono next() - { - executeWithLock( lock, () -> - { - if ( nextInProgress ) - { - throw new IllegalStateException( "Only one in progress next is allowed at a time" ); + public Mono next() { + executeWithLock(lock, () -> { + if (nextInProgress) { + throw new IllegalStateException("Only one in progress next is allowed at a time"); } return nextInProgress = true; - } ); - return Mono.fromCompletionStage( subscriptionFuture ) - .then( Mono.create( itemsSubscriber::requestNext ) ) - .doOnSuccess( ignored -> executeWithLock( lock, () -> nextInProgress = false ) ) - .doOnError( ignored -> executeWithLock( lock, () -> nextInProgress = false ) ); + }); + return Mono.fromCompletionStage(subscriptionFuture) + .then(Mono.create(itemsSubscriber::requestNext)) + .doOnSuccess(ignored -> executeWithLock(lock, () -> nextInProgress = false)) + .doOnError(ignored -> executeWithLock(lock, () -> nextInProgress = false)); } @Override - protected void hookOnSubscribe( Subscription subscription ) - { - subscriptionFuture.complete( subscription ); + protected void hookOnSubscribe(Subscription subscription) { + subscriptionFuture.complete(subscription); } @Override - protected void hookOnNext( T value ) - { - executeWithLock( lock, () -> pendingItems-- ); - itemsSink.next( value ); + protected void hookOnNext(T value) { + executeWithLock(lock, () -> pendingItems--); + itemsSink.next(value); } @Override - protected void hookOnComplete() - { + protected void hookOnComplete() { itemsSink.complete(); } @Override - protected void hookOnError( Throwable throwable ) - { - itemsSink.error( throwable ); + protected void hookOnError(Throwable throwable) { + itemsSink.error(throwable); } - private void requestFromUpstream() - { - boolean moreItemsPending = executeWithLock( lock, () -> - { + private void requestFromUpstream() { + boolean moreItemsPending = executeWithLock(lock, () -> { boolean morePending; - if ( pendingItems > 0 ) - { + if (pendingItems > 0) { morePending = true; - } - else - { + } else { pendingItems = fetchSize; morePending = false; } return morePending; - } ); - if ( moreItemsPending ) - { + }); + if (moreItemsPending) { return; } - Subscription subscription = subscriptionFuture.getNow( null ); - if ( subscription == null ) - { - throw new IllegalStateException( "Upstream subscription must not be null at this stage" ); + Subscription subscription = subscriptionFuture.getNow(null); + if (subscription == null) { + throw new IllegalStateException("Upstream subscription must not be null at this stage"); } - subscription.request( fetchSize ); + subscription.request(fetchSize); } - public static T executeWithLock( Lock lock, Supplier supplier ) - { + public static T executeWithLock(Lock lock, Supplier supplier) { lock.lock(); - try - { + try { return supplier.get(); - } - finally - { + } finally { lock.unlock(); } } - private static class OneSignalSubscriber extends BaseSubscriber - { + private static class OneSignalSubscriber extends BaseSubscriber { private final Lock lock = new ReentrantLock(); private final CompletableFuture completionFuture = new CompletableFuture<>(); private MonoSink sink; private boolean emitted; - public void requestNext( MonoSink sink ) - { - executeWithLock( lock, () -> - { + public void requestNext(MonoSink sink) { + executeWithLock(lock, () -> { this.sink = sink; return emitted = false; - } ); - - if ( completionFuture.isDone() ) - { - completionFuture.whenComplete( - ( ignored, throwable ) -> - { - if ( throwable != null ) - { - this.sink.error( throwable ); - } - else - { - this.sink.success(); - } - } ); - } - else - { - upstream().request( 1 ); + }); + + if (completionFuture.isDone()) { + completionFuture.whenComplete((ignored, throwable) -> { + if (throwable != null) { + this.sink.error(throwable); + } else { + this.sink.success(); + } + }); + } else { + upstream().request(1); } } @Override - protected void hookOnSubscribe( Subscription subscription ) - { + protected void hookOnSubscribe(Subscription subscription) { // left empty to prevent requesting signals immediately } @Override - protected void hookOnNext( T value ) - { - MonoSink sink = executeWithLock( lock, () -> - { + protected void hookOnNext(T value) { + MonoSink sink = executeWithLock(lock, () -> { emitted = true; return this.sink; - } ); - sink.success( value ); + }); + sink.success(value); } @Override - protected void hookOnComplete() - { - MonoSink sink = executeWithLock( lock, () -> - { - completionFuture.complete( null ); + protected void hookOnComplete() { + MonoSink sink = executeWithLock(lock, () -> { + completionFuture.complete(null); return !emitted ? this.sink : null; - } ); - if ( sink != null ) - { + }); + if (sink != null) { sink.success(); } } @Override - protected void hookOnError( Throwable throwable ) - { - MonoSink sink = executeWithLock( lock, () -> - { - completionFuture.completeExceptionally( throwable ); + protected void hookOnError(Throwable throwable) { + MonoSink sink = executeWithLock(lock, () -> { + completionFuture.completeExceptionally(throwable); return !emitted ? this.sink : null; - } ); - if ( sink != null ) - { - sink.error( throwable ); + }); + if (sink != null) { + sink.error(throwable); } } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/TestkitState.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/TestkitState.java index ed10e9a02f..3545e0b0c9 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/TestkitState.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/TestkitState.java @@ -18,6 +18,12 @@ */ package neo4j.org.testkit.backend; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; import lombok.Getter; import neo4j.org.testkit.backend.holder.AsyncSessionHolder; import neo4j.org.testkit.backend.holder.AsyncTransactionHolder; @@ -31,189 +37,156 @@ import neo4j.org.testkit.backend.holder.TransactionHolder; import neo4j.org.testkit.backend.messages.requests.TestkitCallbackResult; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; - import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.internal.cluster.RoutingTableRegistry; +import reactor.core.publisher.Mono; -public class TestkitState -{ +public class TestkitState { private static final String DRIVER_NOT_FOUND_MESSAGE = "Could not find driver"; private static final String SESSION_NOT_FOUND_MESSAGE = "Could not find session"; private static final String TRANSACTION_NOT_FOUND_MESSAGE = "Could not find transaction"; private static final String RESULT_NOT_FOUND_MESSAGE = "Could not find result"; - private final Map driverIdToDriverHolder = new HashMap<>(); + private final Map driverIdToDriverHolder = new HashMap<>(); + @Getter - private final Map routingTableRegistry = new HashMap<>(); - private final Map sessionIdToSessionHolder = new HashMap<>(); - private final Map sessionIdToAsyncSessionHolder = new HashMap<>(); - private final Map sessionIdToRxSessionHolder = new HashMap<>(); - private final Map resultIdToResultHolder = new HashMap<>(); - private final Map resultIdToResultCursorHolder = new HashMap<>(); - private final Map resultIdToRxResultHolder = new HashMap<>(); - private final Map transactionIdToTransactionHolder = new HashMap<>(); - private final Map transactionIdToAsyncTransactionHolder = new HashMap<>(); - private final Map transactionIdToRxTransactionHolder = new HashMap<>(); + private final Map routingTableRegistry = new HashMap<>(); + + private final Map sessionIdToSessionHolder = new HashMap<>(); + private final Map sessionIdToAsyncSessionHolder = new HashMap<>(); + private final Map sessionIdToRxSessionHolder = new HashMap<>(); + private final Map resultIdToResultHolder = new HashMap<>(); + private final Map resultIdToResultCursorHolder = new HashMap<>(); + private final Map resultIdToRxResultHolder = new HashMap<>(); + private final Map transactionIdToTransactionHolder = new HashMap<>(); + private final Map transactionIdToAsyncTransactionHolder = new HashMap<>(); + private final Map transactionIdToRxTransactionHolder = new HashMap<>(); + @Getter - private final Map errors = new HashMap<>(); - private final AtomicInteger idGenerator = new AtomicInteger( 0 ); + private final Map errors = new HashMap<>(); + + private final AtomicInteger idGenerator = new AtomicInteger(0); + @Getter private final Consumer responseWriter; + @Getter - private final Map> callbackIdToFuture = new HashMap<>(); + private final Map> callbackIdToFuture = new HashMap<>(); - public TestkitState( Consumer responseWriter ) - { + public TestkitState(Consumer responseWriter) { this.responseWriter = responseWriter; } - public String newId() - { - return String.valueOf( idGenerator.getAndIncrement() ); + public String newId() { + return String.valueOf(idGenerator.getAndIncrement()); } - public void addDriverHolder( String id, DriverHolder driverHolder ) - { - driverIdToDriverHolder.put( id, driverHolder ); + public void addDriverHolder(String id, DriverHolder driverHolder) { + driverIdToDriverHolder.put(id, driverHolder); } - public DriverHolder getDriverHolder( String id ) - { - return get( id, driverIdToDriverHolder, DRIVER_NOT_FOUND_MESSAGE ); + public DriverHolder getDriverHolder(String id) { + return get(id, driverIdToDriverHolder, DRIVER_NOT_FOUND_MESSAGE); } - public String addSessionHolder( SessionHolder sessionHolder ) - { - return add( sessionHolder, sessionIdToSessionHolder ); + public String addSessionHolder(SessionHolder sessionHolder) { + return add(sessionHolder, sessionIdToSessionHolder); } - public SessionHolder getSessionHolder( String id ) - { - return get( id, sessionIdToSessionHolder, SESSION_NOT_FOUND_MESSAGE ); + public SessionHolder getSessionHolder(String id) { + return get(id, sessionIdToSessionHolder, SESSION_NOT_FOUND_MESSAGE); } - public String addAsyncSessionHolder( AsyncSessionHolder sessionHolder ) - { - return add( sessionHolder, sessionIdToAsyncSessionHolder ); + public String addAsyncSessionHolder(AsyncSessionHolder sessionHolder) { + return add(sessionHolder, sessionIdToAsyncSessionHolder); } - public CompletionStage getAsyncSessionHolder( String id ) - { - return getAsync( id, sessionIdToAsyncSessionHolder, SESSION_NOT_FOUND_MESSAGE ); + public CompletionStage getAsyncSessionHolder(String id) { + return getAsync(id, sessionIdToAsyncSessionHolder, SESSION_NOT_FOUND_MESSAGE); } - public String addRxSessionHolder( RxSessionHolder sessionHolder ) - { - return add( sessionHolder, sessionIdToRxSessionHolder ); + public String addRxSessionHolder(RxSessionHolder sessionHolder) { + return add(sessionHolder, sessionIdToRxSessionHolder); } - public Mono getRxSessionHolder( String id ) - { - return getRx( id, sessionIdToRxSessionHolder, SESSION_NOT_FOUND_MESSAGE ); + public Mono getRxSessionHolder(String id) { + return getRx(id, sessionIdToRxSessionHolder, SESSION_NOT_FOUND_MESSAGE); } - public String addTransactionHolder( TransactionHolder transactionHolder ) - { - return add( transactionHolder, transactionIdToTransactionHolder ); + public String addTransactionHolder(TransactionHolder transactionHolder) { + return add(transactionHolder, transactionIdToTransactionHolder); } - public TransactionHolder getTransactionHolder( String id ) - { - return get( id, transactionIdToTransactionHolder, TRANSACTION_NOT_FOUND_MESSAGE ); + public TransactionHolder getTransactionHolder(String id) { + return get(id, transactionIdToTransactionHolder, TRANSACTION_NOT_FOUND_MESSAGE); } - public String addAsyncTransactionHolder( AsyncTransactionHolder transactionHolder ) - { - return add( transactionHolder, transactionIdToAsyncTransactionHolder ); + public String addAsyncTransactionHolder(AsyncTransactionHolder transactionHolder) { + return add(transactionHolder, transactionIdToAsyncTransactionHolder); } - public CompletionStage getAsyncTransactionHolder( String id ) - { - return getAsync( id, transactionIdToAsyncTransactionHolder, TRANSACTION_NOT_FOUND_MESSAGE ); + public CompletionStage getAsyncTransactionHolder(String id) { + return getAsync(id, transactionIdToAsyncTransactionHolder, TRANSACTION_NOT_FOUND_MESSAGE); } - public String addRxTransactionHolder( RxTransactionHolder transactionHolder ) - { - return add( transactionHolder, transactionIdToRxTransactionHolder ); + public String addRxTransactionHolder(RxTransactionHolder transactionHolder) { + return add(transactionHolder, transactionIdToRxTransactionHolder); } - public Mono getRxTransactionHolder( String id ) - { - return getRx( id, transactionIdToRxTransactionHolder, TRANSACTION_NOT_FOUND_MESSAGE ); + public Mono getRxTransactionHolder(String id) { + return getRx(id, transactionIdToRxTransactionHolder, TRANSACTION_NOT_FOUND_MESSAGE); } - public String addResultHolder( ResultHolder resultHolder ) - { - return add( resultHolder, resultIdToResultHolder ); + public String addResultHolder(ResultHolder resultHolder) { + return add(resultHolder, resultIdToResultHolder); } - public ResultHolder getResultHolder( String id ) - { - return get( id, resultIdToResultHolder, RESULT_NOT_FOUND_MESSAGE ); + public ResultHolder getResultHolder(String id) { + return get(id, resultIdToResultHolder, RESULT_NOT_FOUND_MESSAGE); } - public String addAsyncResultHolder( ResultCursorHolder resultHolder ) - { - return add( resultHolder, resultIdToResultCursorHolder ); + public String addAsyncResultHolder(ResultCursorHolder resultHolder) { + return add(resultHolder, resultIdToResultCursorHolder); } - public CompletionStage getAsyncResultHolder( String id ) - { - return getAsync( id, resultIdToResultCursorHolder, RESULT_NOT_FOUND_MESSAGE ); + public CompletionStage getAsyncResultHolder(String id) { + return getAsync(id, resultIdToResultCursorHolder, RESULT_NOT_FOUND_MESSAGE); } - public String addRxResultHolder( RxResultHolder resultHolder ) - { - return add( resultHolder, resultIdToRxResultHolder ); + public String addRxResultHolder(RxResultHolder resultHolder) { + return add(resultHolder, resultIdToRxResultHolder); } - public Mono getRxResultHolder( String id ) - { - return getRx( id, resultIdToRxResultHolder, RESULT_NOT_FOUND_MESSAGE ); + public Mono getRxResultHolder(String id) { + return getRx(id, resultIdToRxResultHolder, RESULT_NOT_FOUND_MESSAGE); } - private String add( T value, Map idToT ) - { + private String add(T value, Map idToT) { String id = newId(); - idToT.put( id, value ); + idToT.put(id, value); return id; } - private T get( String id, Map idToT, String notFoundMessage ) - { - T value = idToT.get( id ); - if ( value == null ) - { - throw new RuntimeException( notFoundMessage ); + private T get(String id, Map idToT, String notFoundMessage) { + T value = idToT.get(id); + if (value == null) { + throw new RuntimeException(notFoundMessage); } return value; } - private CompletableFuture getAsync( String id, Map idToT, String notFoundMessage ) - { + private CompletableFuture getAsync(String id, Map idToT, String notFoundMessage) { CompletableFuture result = new CompletableFuture<>(); - T value = idToT.get( id ); - if ( value == null ) - { - result.completeExceptionally( new RuntimeException( notFoundMessage ) ); - } - else - { - result.complete( value ); + T value = idToT.get(id); + if (value == null) { + result.completeExceptionally(new RuntimeException(notFoundMessage)); + } else { + result.complete(value); } return result; } - private Mono getRx( String id, Map idToT, String notFoundMessage ) - { - return Mono.fromCompletionStage( getAsync( id, idToT, notFoundMessage ) ); + private Mono getRx(String id, Map idToT, String notFoundMessage) { + return Mono.fromCompletionStage(getAsync(id, idToT, notFoundMessage)); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitMessageInboundHandler.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitMessageInboundHandler.java index f1c06a815c..52d5f937c0 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitMessageInboundHandler.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitMessageInboundHandler.java @@ -22,60 +22,51 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.CharsetUtil; - import java.util.ArrayList; import java.util.List; import java.util.Optional; -public class TestkitMessageInboundHandler extends SimpleChannelInboundHandler -{ +public class TestkitMessageInboundHandler extends SimpleChannelInboundHandler { private final StringBuilder requestBuffer = new StringBuilder(); @Override - public void channelRead0( ChannelHandlerContext ctx, ByteBuf byteBuf ) - { - String requestStr = byteBuf.toString( CharsetUtil.UTF_8 ); - requestBuffer.append( requestStr ); + public void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf) { + String requestStr = byteBuf.toString(CharsetUtil.UTF_8); + requestBuffer.append(requestStr); List testkitMessages = new ArrayList<>(); Optional testkitMessageOpt = extractTestkitMessage(); - while ( testkitMessageOpt.isPresent() ) - { - testkitMessages.add( testkitMessageOpt.get() ); + while (testkitMessageOpt.isPresent()) { + testkitMessages.add(testkitMessageOpt.get()); testkitMessageOpt = extractTestkitMessage(); } - testkitMessages.forEach( ctx::fireChannelRead ); + testkitMessages.forEach(ctx::fireChannelRead); } - private Optional extractTestkitMessage() - { + private Optional extractTestkitMessage() { String requestEndMarker = "#request end\n"; - int endMarkerIndex = requestBuffer.indexOf( requestEndMarker ); - if ( endMarkerIndex < 0 ) - { + int endMarkerIndex = requestBuffer.indexOf(requestEndMarker); + if (endMarkerIndex < 0) { return Optional.empty(); } String requestBeginMarker = "#request begin\n"; - int beginMarkerIndex = requestBuffer.indexOf( requestBeginMarker ); - if ( beginMarkerIndex != 0 ) - { - throw new RuntimeException( "Unexpected data in message buffer" ); + int beginMarkerIndex = requestBuffer.indexOf(requestBeginMarker); + if (beginMarkerIndex != 0) { + throw new RuntimeException("Unexpected data in message buffer"); } // extract Testkit message without markers - String testkitMessage = requestBuffer.substring( requestBeginMarker.length(), endMarkerIndex ); - if ( testkitMessage.contains( requestBeginMarker ) || testkitMessage.contains( requestEndMarker ) ) - { - throw new RuntimeException( "Testkit message contains request markers" ); + String testkitMessage = requestBuffer.substring(requestBeginMarker.length(), endMarkerIndex); + if (testkitMessage.contains(requestBeginMarker) || testkitMessage.contains(requestEndMarker)) { + throw new RuntimeException("Testkit message contains request markers"); } // remove Testkit message from buffer - requestBuffer.delete( 0, endMarkerIndex + requestEndMarker.length() + 1 ); - return Optional.of( testkitMessage ); + requestBuffer.delete(0, endMarkerIndex + requestEndMarker.length() + 1); + return Optional.of(testkitMessage); } @Override - public void exceptionCaught( ChannelHandlerContext ctx, Throwable cause ) - { + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { ctx.close(); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitMessageOutboundHandler.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitMessageOutboundHandler.java index 905b69f754..b5b7dfd4ab 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitMessageOutboundHandler.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitMessageOutboundHandler.java @@ -23,17 +23,14 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; - import java.nio.charset.StandardCharsets; -public class TestkitMessageOutboundHandler extends ChannelOutboundHandlerAdapter -{ +public class TestkitMessageOutboundHandler extends ChannelOutboundHandlerAdapter { @Override - public void write( ChannelHandlerContext ctx, Object msg, ChannelPromise promise ) - { + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { String testkitResponseStr = (String) msg; - String testkitMessage = String.format( "#response begin\n%s\n#response end\n", testkitResponseStr ); - ByteBuf byteBuf = Unpooled.copiedBuffer( testkitMessage, StandardCharsets.UTF_8 ); - ctx.writeAndFlush( byteBuf, promise ); + String testkitMessage = String.format("#response begin\n%s\n#response end\n", testkitResponseStr); + ByteBuf byteBuf = Unpooled.copiedBuffer(testkitMessage, StandardCharsets.UTF_8); + ctx.writeAndFlush(byteBuf, promise); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestProcessorHandler.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestProcessorHandler.java index 3d2ce940d0..0a80a8e3b2 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestProcessorHandler.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestProcessorHandler.java @@ -21,153 +21,128 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; -import neo4j.org.testkit.backend.TestkitState; -import neo4j.org.testkit.backend.messages.requests.TestkitRequest; -import neo4j.org.testkit.backend.messages.responses.BackendError; -import neo4j.org.testkit.backend.messages.responses.DriverError; -import neo4j.org.testkit.backend.messages.responses.TestkitResponse; - import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.function.BiFunction; - +import neo4j.org.testkit.backend.TestkitState; +import neo4j.org.testkit.backend.messages.requests.TestkitRequest; +import neo4j.org.testkit.backend.messages.responses.BackendError; +import neo4j.org.testkit.backend.messages.responses.DriverError; +import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.exceptions.UntrustedServerException; import org.neo4j.driver.internal.spi.ConnectionPool; -public class TestkitRequestProcessorHandler extends ChannelInboundHandlerAdapter -{ - private final TestkitState testkitState = new TestkitState( this::writeAndFlush ); - private final BiFunction> processorImpl; +public class TestkitRequestProcessorHandler extends ChannelInboundHandlerAdapter { + private final TestkitState testkitState = new TestkitState(this::writeAndFlush); + private final BiFunction> processorImpl; // Some requests require multiple threads - private final Executor requestExecutorService = Executors.newFixedThreadPool( 10 ); + private final Executor requestExecutorService = Executors.newFixedThreadPool(10); private Channel channel; - public TestkitRequestProcessorHandler( BackendMode backendMode ) - { - switch ( backendMode ) - { - case ASYNC: - processorImpl = TestkitRequest::processAsync; - break; - case REACTIVE: - processorImpl = ( request, state ) -> request.processRx( state ).toFuture(); - break; - default: - processorImpl = TestkitRequestProcessorHandler::wrapSyncRequest; - break; + public TestkitRequestProcessorHandler(BackendMode backendMode) { + switch (backendMode) { + case ASYNC: + processorImpl = TestkitRequest::processAsync; + break; + case REACTIVE: + processorImpl = (request, state) -> request.processRx(state).toFuture(); + break; + default: + processorImpl = TestkitRequestProcessorHandler::wrapSyncRequest; + break; } } @Override - public void channelRegistered( ChannelHandlerContext ctx ) throws Exception - { + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { channel = ctx.channel(); - super.channelRegistered( ctx ); + super.channelRegistered(ctx); } @Override - public void channelRead( ChannelHandlerContext ctx, Object msg ) - { - // Processing is done in a separate thread to avoid blocking EventLoop because some testing logic, like resolvers support, is blocking. - requestExecutorService.execute( () -> - { - try - { - TestkitRequest request = (TestkitRequest) msg; - CompletionStage responseStage = processorImpl.apply( request, testkitState ); - responseStage.whenComplete( ( response, throwable ) -> - { - if ( throwable != null ) - { - ctx.writeAndFlush( createErrorResponse( throwable ) ); - } - else if ( response != null ) - { - ctx.writeAndFlush( response ); - } - } ); - } - catch ( Throwable throwable ) - { - ctx.writeAndFlush( createErrorResponse( throwable ) ); - } - } ); + public void channelRead(ChannelHandlerContext ctx, Object msg) { + // Processing is done in a separate thread to avoid blocking EventLoop because some testing logic, like + // resolvers support, is blocking. + requestExecutorService.execute(() -> { + try { + TestkitRequest request = (TestkitRequest) msg; + CompletionStage responseStage = processorImpl.apply(request, testkitState); + responseStage.whenComplete((response, throwable) -> { + if (throwable != null) { + ctx.writeAndFlush(createErrorResponse(throwable)); + } else if (response != null) { + ctx.writeAndFlush(response); + } + }); + } catch (Throwable throwable) { + ctx.writeAndFlush(createErrorResponse(throwable)); + } + }); } - private static CompletionStage wrapSyncRequest( TestkitRequest testkitRequest, TestkitState testkitState ) - { + private static CompletionStage wrapSyncRequest( + TestkitRequest testkitRequest, TestkitState testkitState) { CompletableFuture result = new CompletableFuture<>(); - try - { - result.complete( testkitRequest.process( testkitState ) ); - } - catch ( Throwable t ) - { - result.completeExceptionally( t ); + try { + result.complete(testkitRequest.process(testkitState)); + } catch (Throwable t) { + result.completeExceptionally(t); } return result; } - private TestkitResponse createErrorResponse( Throwable throwable ) - { - if ( throwable instanceof CompletionException ) - { + private TestkitResponse createErrorResponse(Throwable throwable) { + if (throwable instanceof CompletionException) { throwable = throwable.getCause(); } - if ( throwable instanceof Neo4jException ) - { + if (throwable instanceof Neo4jException) { String id = testkitState.newId(); Neo4jException e = (Neo4jException) throwable; - testkitState.getErrors().put( id, e ); + testkitState.getErrors().put(id, e); return DriverError.builder() - .data( DriverError.DriverErrorBody.builder() - .id( id ) - .errorType( e.getClass().getName() ) - .code( e.code() ) - .msg( e.getMessage() ) - .build() ) - .build(); - } - else if ( isConnectionPoolClosedException( throwable ) || throwable instanceof UntrustedServerException ) - { + .data(DriverError.DriverErrorBody.builder() + .id(id) + .errorType(e.getClass().getName()) + .code(e.code()) + .msg(e.getMessage()) + .build()) + .build(); + } else if (isConnectionPoolClosedException(throwable) || throwable instanceof UntrustedServerException) { String id = testkitState.newId(); return DriverError.builder() - .data( - DriverError.DriverErrorBody.builder() - .id( id ) - .errorType( throwable.getClass().getName() ) - .msg( throwable.getMessage() ) - .build() - ) - .build(); - } - else - { - return BackendError.builder().data( BackendError.BackendErrorBody.builder().msg( throwable.toString() ).build() ).build(); + .data(DriverError.DriverErrorBody.builder() + .id(id) + .errorType(throwable.getClass().getName()) + .msg(throwable.getMessage()) + .build()) + .build(); + } else { + return BackendError.builder() + .data(BackendError.BackendErrorBody.builder() + .msg(throwable.toString()) + .build()) + .build(); } } - private boolean isConnectionPoolClosedException( Throwable throwable ) - { - return throwable instanceof IllegalStateException && throwable.getMessage() != null && - throwable.getMessage().equals( ConnectionPool.CONNECTION_POOL_CLOSED_ERROR_MESSAGE ); + private boolean isConnectionPoolClosedException(Throwable throwable) { + return throwable instanceof IllegalStateException + && throwable.getMessage() != null + && throwable.getMessage().equals(ConnectionPool.CONNECTION_POOL_CLOSED_ERROR_MESSAGE); } - private void writeAndFlush( TestkitResponse response ) - { - if ( channel == null ) - { - throw new IllegalStateException( "Called before channel is initialized" ); + private void writeAndFlush(TestkitResponse response) { + if (channel == null) { + throw new IllegalStateException("Called before channel is initialized"); } - channel.writeAndFlush( response ); + channel.writeAndFlush(response); } - public enum BackendMode - { + public enum BackendMode { SYNC, ASYNC, REACTIVE diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestResponseMapperHandler.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestResponseMapperHandler.java index d599257a76..9afc93e308 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestResponseMapperHandler.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/channel/handler/TestkitRequestResponseMapperHandler.java @@ -28,40 +28,33 @@ import neo4j.org.testkit.backend.messages.requests.TestkitRequest; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -public class TestkitRequestResponseMapperHandler extends ChannelDuplexHandler -{ +public class TestkitRequestResponseMapperHandler extends ChannelDuplexHandler { private final ObjectMapper objectMapper = newObjectMapper(); @Override - public void channelRead( ChannelHandlerContext ctx, Object msg ) - { + public void channelRead(ChannelHandlerContext ctx, Object msg) { String testkitMessage = (String) msg; TestkitRequest testkitRequest; - try - { - testkitRequest = objectMapper.readValue( testkitMessage, TestkitRequest.class ); + try { + testkitRequest = objectMapper.readValue(testkitMessage, TestkitRequest.class); + } catch (JsonProcessingException e) { + throw new RuntimeException("Failed to deserialize Testkit message", e); } - catch ( JsonProcessingException e ) - { - throw new RuntimeException( "Failed to deserialize Testkit message", e ); - } - ctx.fireChannelRead( testkitRequest ); + ctx.fireChannelRead(testkitRequest); } @Override - public void write( ChannelHandlerContext ctx, Object msg, ChannelPromise promise ) throws Exception - { + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { TestkitResponse testkitResponse = (TestkitResponse) msg; - String responseStr = objectMapper.writeValueAsString( testkitResponse ); - ctx.writeAndFlush( responseStr, promise ); + String responseStr = objectMapper.writeValueAsString(testkitResponse); + ctx.writeAndFlush(responseStr, promise); } - public static ObjectMapper newObjectMapper() - { + public static ObjectMapper newObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); TestkitModule testkitModule = new TestkitModule(); - objectMapper.registerModule( testkitModule ); - objectMapper.disable( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES ); + objectMapper.registerModule(testkitModule); + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); return objectMapper; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractResultHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractResultHolder.java index d9bb3704c1..848d17752c 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractResultHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractResultHolder.java @@ -18,40 +18,35 @@ */ package neo4j.org.testkit.backend.holder; -import lombok.Getter; - import java.util.Optional; +import lombok.Getter; -public abstract class AbstractResultHolder, T3> -{ +public abstract class AbstractResultHolder, T3> { private final T1 sessionHolder; private final T2 transactionHolder; + @Getter private final T3 result; - public AbstractResultHolder( T1 sessionHolder, T3 result ) - { + public AbstractResultHolder(T1 sessionHolder, T3 result) { this.sessionHolder = sessionHolder; this.transactionHolder = null; this.result = result; } - public AbstractResultHolder( T2 transactionHolder, T3 result ) - { + public AbstractResultHolder(T2 transactionHolder, T3 result) { this.sessionHolder = null; this.transactionHolder = transactionHolder; this.result = result; } - public T1 getSessionHolder() - { - return transactionHolder != null ? getSessionHolder( transactionHolder ) : sessionHolder; + public T1 getSessionHolder() { + return transactionHolder != null ? getSessionHolder(transactionHolder) : sessionHolder; } - public Optional getTransactionHolder() - { - return Optional.ofNullable( transactionHolder ); + public Optional getTransactionHolder() { + return Optional.ofNullable(transactionHolder); } - protected abstract T1 getSessionHolder( T2 transactionHolder ); + protected abstract T1 getSessionHolder(T2 transactionHolder); } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractSessionHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractSessionHolder.java index f8e9381848..ce72739004 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractSessionHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractSessionHolder.java @@ -18,21 +18,19 @@ */ package neo4j.org.testkit.backend.holder; +import java.util.concurrent.CompletableFuture; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; - -import java.util.concurrent.CompletableFuture; - import org.neo4j.driver.SessionConfig; @RequiredArgsConstructor @Getter -public abstract class AbstractSessionHolder -{ +public abstract class AbstractSessionHolder { public final DriverHolder driverHolder; public final T session; public final SessionConfig config; + @Setter public CompletableFuture txWorkFuture; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractTransactionHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractTransactionHolder.java index 7bd0429b96..195e318086 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractTransactionHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AbstractTransactionHolder.java @@ -23,8 +23,7 @@ @RequiredArgsConstructor @Getter -public abstract class AbstractTransactionHolder -{ +public abstract class AbstractTransactionHolder { private final T1 sessionHolder; private final T2 transaction; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AsyncSessionHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AsyncSessionHolder.java index ddba2a3eaa..0a46ebe2fb 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AsyncSessionHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AsyncSessionHolder.java @@ -21,10 +21,8 @@ import org.neo4j.driver.SessionConfig; import org.neo4j.driver.async.AsyncSession; -public class AsyncSessionHolder extends AbstractSessionHolder -{ - public AsyncSessionHolder( DriverHolder driverHolder, AsyncSession session, SessionConfig config ) - { - super( driverHolder, session, config ); +public class AsyncSessionHolder extends AbstractSessionHolder { + public AsyncSessionHolder(DriverHolder driverHolder, AsyncSession session, SessionConfig config) { + super(driverHolder, session, config); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AsyncTransactionHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AsyncTransactionHolder.java index afca81a67d..8d81c714f4 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AsyncTransactionHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/AsyncTransactionHolder.java @@ -20,10 +20,8 @@ import org.neo4j.driver.async.AsyncTransaction; -public class AsyncTransactionHolder extends AbstractTransactionHolder -{ - public AsyncTransactionHolder( AsyncSessionHolder sessionHolder, AsyncTransaction transaction ) - { - super( sessionHolder, transaction ); +public class AsyncTransactionHolder extends AbstractTransactionHolder { + public AsyncTransactionHolder(AsyncSessionHolder sessionHolder, AsyncTransaction transaction) { + super(sessionHolder, transaction); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/DriverHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/DriverHolder.java index b765fa20e7..be99c9e211 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/DriverHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/DriverHolder.java @@ -20,14 +20,12 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; - import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @RequiredArgsConstructor @Getter -public class DriverHolder -{ +public class DriverHolder { private final Driver driver; private final Config config; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/ResultCursorHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/ResultCursorHolder.java index 02f4bedd13..347a01e86e 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/ResultCursorHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/ResultCursorHolder.java @@ -20,21 +20,17 @@ import org.neo4j.driver.async.ResultCursor; -public class ResultCursorHolder extends AbstractResultHolder -{ - public ResultCursorHolder( AsyncSessionHolder sessionHolder, ResultCursor result ) - { - super( sessionHolder, result ); +public class ResultCursorHolder extends AbstractResultHolder { + public ResultCursorHolder(AsyncSessionHolder sessionHolder, ResultCursor result) { + super(sessionHolder, result); } - public ResultCursorHolder( AsyncTransactionHolder transactionHolder, ResultCursor result ) - { - super( transactionHolder, result ); + public ResultCursorHolder(AsyncTransactionHolder transactionHolder, ResultCursor result) { + super(transactionHolder, result); } @Override - protected AsyncSessionHolder getSessionHolder( AsyncTransactionHolder transactionHolder ) - { + protected AsyncSessionHolder getSessionHolder(AsyncTransactionHolder transactionHolder) { return transactionHolder.getSessionHolder(); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/ResultHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/ResultHolder.java index 07d6fc6ff8..5c2e375dbb 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/ResultHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/ResultHolder.java @@ -20,21 +20,17 @@ import org.neo4j.driver.Result; -public class ResultHolder extends AbstractResultHolder -{ - public ResultHolder( SessionHolder sessionHolder, Result result ) - { - super( sessionHolder, result ); +public class ResultHolder extends AbstractResultHolder { + public ResultHolder(SessionHolder sessionHolder, Result result) { + super(sessionHolder, result); } - public ResultHolder( TransactionHolder transactionHolder, Result result ) - { - super( transactionHolder, result ); + public ResultHolder(TransactionHolder transactionHolder, Result result) { + super(transactionHolder, result); } @Override - protected SessionHolder getSessionHolder( TransactionHolder transactionHolder ) - { + protected SessionHolder getSessionHolder(TransactionHolder transactionHolder) { return transactionHolder.getSessionHolder(); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxResultHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxResultHolder.java index fd1c290c4b..1fe61d249e 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxResultHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxResultHolder.java @@ -18,41 +18,35 @@ */ package neo4j.org.testkit.backend.holder; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicLong; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.RxBufferedSubscriber; - -import java.util.Optional; -import java.util.concurrent.atomic.AtomicLong; - import org.neo4j.driver.Record; import org.neo4j.driver.reactive.RxResult; -public class RxResultHolder extends AbstractResultHolder -{ +public class RxResultHolder extends AbstractResultHolder { @Setter private RxBufferedSubscriber subscriber; + @Getter private final AtomicLong requestedRecordsCounter = new AtomicLong(); - public RxResultHolder( RxSessionHolder sessionHolder, RxResult result ) - { - super( sessionHolder, result ); + public RxResultHolder(RxSessionHolder sessionHolder, RxResult result) { + super(sessionHolder, result); } - public RxResultHolder( RxTransactionHolder transactionHolder, RxResult result ) - { - super( transactionHolder, result ); + public RxResultHolder(RxTransactionHolder transactionHolder, RxResult result) { + super(transactionHolder, result); } - public Optional> getSubscriber() - { - return Optional.ofNullable( subscriber ); + public Optional> getSubscriber() { + return Optional.ofNullable(subscriber); } @Override - protected RxSessionHolder getSessionHolder( RxTransactionHolder transactionHolder ) - { + protected RxSessionHolder getSessionHolder(RxTransactionHolder transactionHolder) { return transactionHolder.getSessionHolder(); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxSessionHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxSessionHolder.java index 73e66b2920..2156a153dc 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxSessionHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxSessionHolder.java @@ -21,10 +21,8 @@ import org.neo4j.driver.SessionConfig; import org.neo4j.driver.reactive.RxSession; -public class RxSessionHolder extends AbstractSessionHolder -{ - public RxSessionHolder( DriverHolder driverHolder, RxSession session, SessionConfig config ) - { - super( driverHolder, session, config ); +public class RxSessionHolder extends AbstractSessionHolder { + public RxSessionHolder(DriverHolder driverHolder, RxSession session, SessionConfig config) { + super(driverHolder, session, config); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxTransactionHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxTransactionHolder.java index cbb3001a63..fe36e926d4 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxTransactionHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/RxTransactionHolder.java @@ -20,10 +20,8 @@ import org.neo4j.driver.reactive.RxTransaction; -public class RxTransactionHolder extends AbstractTransactionHolder -{ - public RxTransactionHolder( RxSessionHolder sessionHolder, RxTransaction transaction ) - { - super( sessionHolder, transaction ); +public class RxTransactionHolder extends AbstractTransactionHolder { + public RxTransactionHolder(RxSessionHolder sessionHolder, RxTransaction transaction) { + super(sessionHolder, transaction); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/SessionHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/SessionHolder.java index 14bb3f3b96..df79c17f01 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/SessionHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/SessionHolder.java @@ -21,10 +21,8 @@ import org.neo4j.driver.Session; import org.neo4j.driver.SessionConfig; -public class SessionHolder extends AbstractSessionHolder -{ - public SessionHolder( DriverHolder driverHolder, Session session, SessionConfig config ) - { - super( driverHolder, session, config ); +public class SessionHolder extends AbstractSessionHolder { + public SessionHolder(DriverHolder driverHolder, Session session, SessionConfig config) { + super(driverHolder, session, config); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/TransactionHolder.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/TransactionHolder.java index 4919750f5c..b2c8964784 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/TransactionHolder.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/holder/TransactionHolder.java @@ -20,10 +20,8 @@ import org.neo4j.driver.Transaction; -public class TransactionHolder extends AbstractTransactionHolder -{ - public TransactionHolder( SessionHolder sessionHolder, Transaction transaction ) - { - super( sessionHolder, transaction ); +public class TransactionHolder extends AbstractTransactionHolder { + public TransactionHolder(SessionHolder sessionHolder, Transaction transaction) { + super(sessionHolder, transaction); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/TestkitModule.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/TestkitModule.java index 47f9a7fb44..cf71a03af6 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/TestkitModule.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/TestkitModule.java @@ -19,6 +19,7 @@ package neo4j.org.testkit.backend.messages; import com.fasterxml.jackson.databind.module.SimpleModule; +import java.util.List; import neo4j.org.testkit.backend.messages.requests.deserializer.TestkitListDeserializer; import neo4j.org.testkit.backend.messages.responses.serializer.TestkitBookmarkSerializer; import neo4j.org.testkit.backend.messages.responses.serializer.TestkitListValueSerializer; @@ -28,9 +29,6 @@ import neo4j.org.testkit.backend.messages.responses.serializer.TestkitRecordSerializer; import neo4j.org.testkit.backend.messages.responses.serializer.TestkitRelationshipValueSerializer; import neo4j.org.testkit.backend.messages.responses.serializer.TestkitValueSerializer; - -import java.util.List; - import org.neo4j.driver.Bookmark; import org.neo4j.driver.Record; import org.neo4j.driver.Value; @@ -40,19 +38,17 @@ import org.neo4j.driver.internal.value.PathValue; import org.neo4j.driver.internal.value.RelationshipValue; -public class TestkitModule extends SimpleModule -{ - public TestkitModule() - { - this.addDeserializer( List.class, new TestkitListDeserializer() ); +public class TestkitModule extends SimpleModule { + public TestkitModule() { + this.addDeserializer(List.class, new TestkitListDeserializer()); - this.addSerializer( Value.class, new TestkitValueSerializer() ); - this.addSerializer( NodeValue.class, new TestkitNodeValueSerializer() ); - this.addSerializer( ListValue.class, new TestkitListValueSerializer() ); - this.addSerializer( Record.class, new TestkitRecordSerializer() ); - this.addSerializer( MapValue.class, new TestkitMapValueSerializer() ); - this.addSerializer( Bookmark.class, new TestkitBookmarkSerializer() ); - this.addSerializer( PathValue.class, new TestkitPathValueSerializer() ); - this.addSerializer( RelationshipValue.class, new TestkitRelationshipValueSerializer() ); + this.addSerializer(Value.class, new TestkitValueSerializer()); + this.addSerializer(NodeValue.class, new TestkitNodeValueSerializer()); + this.addSerializer(ListValue.class, new TestkitListValueSerializer()); + this.addSerializer(Record.class, new TestkitRecordSerializer()); + this.addSerializer(MapValue.class, new TestkitMapValueSerializer()); + this.addSerializer(Bookmark.class, new TestkitBookmarkSerializer()); + this.addSerializer(PathValue.class, new TestkitPathValueSerializer()); + this.addSerializer(RelationshipValue.class, new TestkitRelationshipValueSerializer()); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/AuthorizationToken.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/AuthorizationToken.java index 0e70420cdc..fd0870a129 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/AuthorizationToken.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/AuthorizationToken.java @@ -20,27 +20,24 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import java.util.Map; import lombok.Getter; import lombok.Setter; -import java.util.Map; - @Setter @Getter -@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "name" ) -public class AuthorizationToken -{ - @JsonProperty( "data" ) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "name") +public class AuthorizationToken { + @JsonProperty("data") private Tokens tokens; @Getter @Setter - public static class Tokens - { + public static class Tokens { private String scheme; private String principal; private String credentials; private String realm; - private Map parameters; + private Map parameters; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/CheckDriverIsEncrypted.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/CheckDriverIsEncrypted.java index 1204900651..cd8ce346d5 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/CheckDriverIsEncrypted.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/CheckDriverIsEncrypted.java @@ -18,6 +18,8 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -26,45 +28,38 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class CheckDriverIsEncrypted implements TestkitRequest -{ +public class CheckDriverIsEncrypted implements TestkitRequest { private CheckDriverIsEncryptedBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - return createResponse( testkitState ); + public TestkitResponse process(TestkitState testkitState) { + return createResponse(testkitState); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return CompletableFuture.completedFuture( createResponse( testkitState ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return CompletableFuture.completedFuture(createResponse(testkitState)); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.just( createResponse( testkitState ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.just(createResponse(testkitState)); } - private DriverIsEncrypted createResponse( TestkitState testkitState ) - { - DriverHolder driverHolder = testkitState.getDriverHolder( data.getDriverId() ); + private DriverIsEncrypted createResponse(TestkitState testkitState) { + DriverHolder driverHolder = testkitState.getDriverHolder(data.getDriverId()); return DriverIsEncrypted.builder() - .data( DriverIsEncrypted.DriverIsEncryptedBody.builder().encrypted( driverHolder.getDriver().isEncrypted() ).build() ) - .build(); + .data(DriverIsEncrypted.DriverIsEncryptedBody.builder() + .encrypted(driverHolder.getDriver().isEncrypted()) + .build()) + .build(); } @Setter @Getter - public static class CheckDriverIsEncryptedBody - { + public static class CheckDriverIsEncryptedBody { private String driverId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/CheckMultiDBSupport.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/CheckMultiDBSupport.java index 03cb95016d..47b5f064e6 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/CheckMultiDBSupport.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/CheckMultiDBSupport.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,50 +26,43 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class CheckMultiDBSupport implements TestkitRequest -{ +public class CheckMultiDBSupport implements TestkitRequest { private CheckMultiDBSupportBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { + public TestkitResponse process(TestkitState testkitState) { String driverId = data.getDriverId(); - boolean available = testkitState.getDriverHolder( driverId ).getDriver().supportsMultiDb(); - return createResponse( available ); + boolean available = testkitState.getDriverHolder(driverId).getDriver().supportsMultiDb(); + return createResponse(available); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getDriverHolder( data.getDriverId() ) - .getDriver() - .supportsMultiDbAsync() - .thenApply( this::createResponse ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getDriverHolder(data.getDriverId()) + .getDriver() + .supportsMultiDbAsync() + .thenApply(this::createResponse); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.fromCompletionStage( processAsync( testkitState ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.fromCompletionStage(processAsync(testkitState)); } - private MultiDBSupport createResponse( boolean available ) - { + private MultiDBSupport createResponse(boolean available) { return MultiDBSupport.builder() - .data( MultiDBSupport.MultiDBSupportBody.builder() - .available( available ) - .build() ) - .build(); + .data(MultiDBSupport.MultiDBSupportBody.builder() + .available(available) + .build()) + .build(); } @Setter @Getter - public static class CheckMultiDBSupportBody - { + public static class CheckMultiDBSupportBody { private String driverId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/DomainNameResolutionCompleted.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/DomainNameResolutionCompleted.java index 537456155f..28a35f5414 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/DomainNameResolutionCompleted.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/DomainNameResolutionCompleted.java @@ -18,27 +18,23 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.List; import lombok.Getter; import lombok.Setter; -import java.util.List; - @Setter @Getter -public class DomainNameResolutionCompleted implements TestkitCallbackResult -{ +public class DomainNameResolutionCompleted implements TestkitCallbackResult { private DomainNameResolutionCompletedBody data; @Override - public String getCallbackId() - { + public String getCallbackId() { return data.getRequestId(); } @Setter @Getter - public static class DomainNameResolutionCompletedBody - { + public static class DomainNameResolutionCompletedBody { private String requestId; private List addresses; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/DriverClose.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/DriverClose.java index d7fd879fb5..c8b23bc59f 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/DriverClose.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/DriverClose.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,45 +26,40 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class DriverClose implements TestkitRequest -{ +public class DriverClose implements TestkitRequest { private DriverCloseBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - testkitState.getDriverHolder( data.getDriverId() ).getDriver().close(); + public TestkitResponse process(TestkitState testkitState) { + testkitState.getDriverHolder(data.getDriverId()).getDriver().close(); return createResponse(); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getDriverHolder( data.getDriverId() ) - .getDriver() - .closeAsync() - .thenApply( ignored -> createResponse() ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getDriverHolder(data.getDriverId()) + .getDriver() + .closeAsync() + .thenApply(ignored -> createResponse()); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.fromCompletionStage( processAsync( testkitState ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.fromCompletionStage(processAsync(testkitState)); } - private Driver createResponse() - { - return Driver.builder().data( Driver.DriverBody.builder().id( data.getDriverId() ).build() ).build(); + private Driver createResponse() { + return Driver.builder() + .data(Driver.DriverBody.builder().id(data.getDriverId()).build()) + .build(); } @Setter @Getter - private static class DriverCloseBody - { + private static class DriverCloseBody { private String driverId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetConnectionPoolMetrics.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetConnectionPoolMetrics.java index 63cc06e252..00e32d113b 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetConnectionPoolMetrics.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetConnectionPoolMetrics.java @@ -18,89 +18,77 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; import neo4j.org.testkit.backend.holder.DriverHolder; import neo4j.org.testkit.backend.messages.responses.ConnectionPoolMetrics; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Metrics; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.net.ServerAddress; +import reactor.core.publisher.Mono; @Getter @Setter -public class GetConnectionPoolMetrics implements TestkitRequest -{ +public class GetConnectionPoolMetrics implements TestkitRequest { private GetConnectionPoolMetricsBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - return getConnectionPoolMetrics( testkitState ); + public TestkitResponse process(TestkitState testkitState) { + return getConnectionPoolMetrics(testkitState); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return CompletableFuture.completedFuture( getConnectionPoolMetrics( testkitState ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return CompletableFuture.completedFuture(getConnectionPoolMetrics(testkitState)); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.just( getConnectionPoolMetrics( testkitState ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.just(getConnectionPoolMetrics(testkitState)); } - private ConnectionPoolMetrics getConnectionPoolMetrics( TestkitState testkitState ) - { - DriverHolder driverHolder = testkitState.getDriverHolder( data.getDriverId() ); + private ConnectionPoolMetrics getConnectionPoolMetrics(TestkitState testkitState) { + DriverHolder driverHolder = testkitState.getDriverHolder(data.getDriverId()); Metrics metrics = driverHolder.getDriver().metrics(); - org.neo4j.driver.ConnectionPoolMetrics poolMetrics = - metrics.connectionPoolMetrics().stream() - .filter( pm -> - { - // Brute forcing the access via reflections avoid having the InternalConnectionPoolMetrics a public class - ServerAddress poolAddress; - try - { - Method m = pm.getClass().getDeclaredMethod("getAddress"); - m.setAccessible( true ); - poolAddress = (ServerAddress) m.invoke( pm ); - } - catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException e ) - { - return false; - } - ServerAddress address = new BoltServerAddress( data.getAddress() ); - return address.host().equals( poolAddress.host() ) && address.port() == poolAddress.port(); - } ) - .findFirst() - .orElseThrow( () -> new IllegalArgumentException( String.format( "Pool metrics for %s are not available", data.getAddress() ) ) ); - return createResponse( poolMetrics ); + org.neo4j.driver.ConnectionPoolMetrics poolMetrics = metrics.connectionPoolMetrics().stream() + .filter(pm -> { + // Brute forcing the access via reflections avoid having the InternalConnectionPoolMetrics a public + // class + ServerAddress poolAddress; + try { + Method m = pm.getClass().getDeclaredMethod("getAddress"); + m.setAccessible(true); + poolAddress = (ServerAddress) m.invoke(pm); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + return false; + } + ServerAddress address = new BoltServerAddress(data.getAddress()); + return address.host().equals(poolAddress.host()) && address.port() == poolAddress.port(); + }) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException( + String.format("Pool metrics for %s are not available", data.getAddress()))); + return createResponse(poolMetrics); } - private ConnectionPoolMetrics createResponse( org.neo4j.driver.ConnectionPoolMetrics poolMetrics ) - { + private ConnectionPoolMetrics createResponse(org.neo4j.driver.ConnectionPoolMetrics poolMetrics) { return ConnectionPoolMetrics.builder() - .data( ConnectionPoolMetrics.ConnectionPoolMetricsBody.builder() - .inUse( poolMetrics.inUse() ) - .idle( poolMetrics.idle() ) - .build() ) - .build(); + .data(ConnectionPoolMetrics.ConnectionPoolMetricsBody.builder() + .inUse(poolMetrics.inUse()) + .idle(poolMetrics.idle()) + .build()) + .build(); } @Setter @Getter - public static class GetConnectionPoolMetricsBody - { + public static class GetConnectionPoolMetricsBody { private String driverId; private String address; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetFeatures.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetFeatures.java index 9c7730ee1f..0e601e114e 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetFeatures.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetFeatures.java @@ -18,6 +18,11 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,17 +30,10 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class GetFeatures implements TestkitRequest -{ - private static final Set COMMON_FEATURES = new HashSet<>( Arrays.asList( +public class GetFeatures implements TestkitRequest { + private static final Set COMMON_FEATURES = new HashSet<>(Arrays.asList( "Feature:Bolt:4.0", "Feature:Bolt:4.1", "Feature:Bolt:4.2", @@ -56,49 +54,44 @@ public class GetFeatures implements TestkitRequest "Feature:API:Driver.IsEncrypted", "Feature:API:SSLConfig", "Detail:DefaultSecurityConfigValueEquality", - "Optimization:ImplicitDefaultArguments" - ) ); + "Optimization:ImplicitDefaultArguments")); - private static final Set SYNC_FEATURES = new HashSet<>( Arrays.asList( + private static final Set SYNC_FEATURES = new HashSet<>(Arrays.asList( "Feature:Bolt:3.0", "Optimization:PullPipelining", "Feature:API:Result.List", "Feature:API:Result.Peek", - "Optimization:ResultListFetchAll" - ) ); + "Optimization:ResultListFetchAll")); - private static final Set ASYNC_FEATURES = new HashSet<>( Arrays.asList( + private static final Set ASYNC_FEATURES = new HashSet<>(Arrays.asList( "Feature:Bolt:3.0", "Optimization:PullPipelining", "Feature:API:Result.List", "Feature:API:Result.Peek", - "Optimization:ResultListFetchAll" - ) ); + "Optimization:ResultListFetchAll")); @Override - public TestkitResponse process( TestkitState testkitState ) - { - Set features = new HashSet<>( COMMON_FEATURES ); - features.addAll( SYNC_FEATURES ); - return createResponse( features ); + public TestkitResponse process(TestkitState testkitState) { + Set features = new HashSet<>(COMMON_FEATURES); + features.addAll(SYNC_FEATURES); + return createResponse(features); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - Set features = new HashSet<>( COMMON_FEATURES ); - features.addAll( ASYNC_FEATURES ); - return CompletableFuture.completedFuture( createResponse( features ) ); + public CompletionStage processAsync(TestkitState testkitState) { + Set features = new HashSet<>(COMMON_FEATURES); + features.addAll(ASYNC_FEATURES); + return CompletableFuture.completedFuture(createResponse(features)); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.just( createResponse( COMMON_FEATURES ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.just(createResponse(COMMON_FEATURES)); } - private FeatureList createResponse( Set features ) - { - return FeatureList.builder().data( FeatureList.FeatureListBody.builder().features( features ).build() ).build(); + private FeatureList createResponse(Set features) { + return FeatureList.builder() + .data(FeatureList.FeatureListBody.builder().features(features).build()) + .build(); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java index 0be682d5e3..4789a1a08e 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java @@ -18,81 +18,75 @@ */ package neo4j.org.testkit.backend.messages.requests; -import lombok.Getter; -import lombok.Setter; -import neo4j.org.testkit.backend.TestkitState; -import neo4j.org.testkit.backend.messages.responses.RoutingTable; -import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.function.Function; import java.util.stream.Collectors; - +import lombok.Getter; +import lombok.Setter; +import neo4j.org.testkit.backend.TestkitState; +import neo4j.org.testkit.backend.messages.responses.RoutingTable; +import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DatabaseName; import org.neo4j.driver.internal.DatabaseNameUtil; import org.neo4j.driver.internal.cluster.RoutingTableHandler; import org.neo4j.driver.internal.cluster.RoutingTableRegistry; +import reactor.core.publisher.Mono; @Setter @Getter -public class GetRoutingTable implements TestkitRequest -{ - private static final Function,List> ADDRESSES_TO_STRINGS = - ( addresses ) -> addresses.stream() - .map( address -> String.format( "%s:%d", address.host(), address.port() ) ) - .collect( Collectors.toList() ); +public class GetRoutingTable implements TestkitRequest { + private static final Function, List> ADDRESSES_TO_STRINGS = + (addresses) -> addresses.stream() + .map(address -> String.format("%s:%d", address.host(), address.port())) + .collect(Collectors.toList()); private GetRoutingTableBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - RoutingTableRegistry routingTableRegistry = testkitState.getRoutingTableRegistry().get( data.getDriverId() ); - if ( routingTableRegistry == null ) - { - throw new IllegalStateException( - String.format( "There is no routing table registry for '%s' driver. (It might be a direct driver)", data.getDriverId() ) ); + public TestkitResponse process(TestkitState testkitState) { + RoutingTableRegistry routingTableRegistry = + testkitState.getRoutingTableRegistry().get(data.getDriverId()); + if (routingTableRegistry == null) { + throw new IllegalStateException(String.format( + "There is no routing table registry for '%s' driver. (It might be a direct driver)", + data.getDriverId())); } - DatabaseName databaseName = DatabaseNameUtil.database( data.getDatabase() ); - RoutingTableHandler routingTableHandler = routingTableRegistry.getRoutingTableHandler( databaseName ).orElseThrow( - () -> new IllegalStateException( - String.format( "There is no routing table handler for the '%s' database.", databaseName.databaseName().orElse( "null" ) ) ) ); + DatabaseName databaseName = DatabaseNameUtil.database(data.getDatabase()); + RoutingTableHandler routingTableHandler = routingTableRegistry + .getRoutingTableHandler(databaseName) + .orElseThrow(() -> new IllegalStateException(String.format( + "There is no routing table handler for the '%s' database.", + databaseName.databaseName().orElse("null")))); org.neo4j.driver.internal.cluster.RoutingTable routingTable = routingTableHandler.routingTable(); - return RoutingTable - .builder() - .data( RoutingTable.RoutingTableBody - .builder() - .database( databaseName.databaseName().orElse( null ) ) - .routers( ADDRESSES_TO_STRINGS.apply( routingTable.routers() ) ) - .readers( ADDRESSES_TO_STRINGS.apply( routingTable.readers() ) ) - .writers( ADDRESSES_TO_STRINGS.apply( routingTable.writers() ) ) - .build() - ).build(); + return RoutingTable.builder() + .data(RoutingTable.RoutingTableBody.builder() + .database(databaseName.databaseName().orElse(null)) + .routers(ADDRESSES_TO_STRINGS.apply(routingTable.routers())) + .readers(ADDRESSES_TO_STRINGS.apply(routingTable.readers())) + .writers(ADDRESSES_TO_STRINGS.apply(routingTable.writers())) + .build()) + .build(); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return CompletableFuture.completedFuture( process( testkitState ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return CompletableFuture.completedFuture(process(testkitState)); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.just( process( testkitState ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.just(process(testkitState)); } @Setter @Getter - public static class GetRoutingTableBody - { + public static class GetRoutingTableBody { private String driverId; private String database; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewDriver.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewDriver.java index 3257c04709..eadbf7e36c 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewDriver.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewDriver.java @@ -18,19 +18,6 @@ */ package neo4j.org.testkit.backend.messages.requests; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -import neo4j.org.testkit.backend.TestkitState; -import neo4j.org.testkit.backend.holder.DriverHolder; -import neo4j.org.testkit.backend.messages.responses.DomainNameResolutionRequired; -import neo4j.org.testkit.backend.messages.responses.Driver; -import neo4j.org.testkit.backend.messages.responses.DriverError; -import neo4j.org.testkit.backend.messages.responses.ResolverResolutionRequired; -import neo4j.org.testkit.backend.messages.responses.TestkitCallback; -import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - import java.io.File; import java.net.InetAddress; import java.net.URI; @@ -44,7 +31,17 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; - +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import neo4j.org.testkit.backend.TestkitState; +import neo4j.org.testkit.backend.holder.DriverHolder; +import neo4j.org.testkit.backend.messages.responses.DomainNameResolutionRequired; +import neo4j.org.testkit.backend.messages.responses.Driver; +import neo4j.org.testkit.backend.messages.responses.DriverError; +import neo4j.org.testkit.backend.messages.responses.ResolverResolutionRequired; +import neo4j.org.testkit.backend.messages.responses.TestkitCallback; +import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import org.neo4j.driver.AuthToken; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; @@ -58,238 +55,219 @@ import org.neo4j.driver.internal.retry.RetrySettings; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.net.ServerAddressResolver; +import reactor.core.publisher.Mono; @Setter @Getter -public class NewDriver implements TestkitRequest -{ +public class NewDriver implements TestkitRequest { private NewDriverBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { + public TestkitResponse process(TestkitState testkitState) { String id = testkitState.newId(); AuthToken authToken; - switch ( data.getAuthorizationToken().getTokens().getScheme() ) - { - case "basic": - authToken = AuthTokens.basic( data.authorizationToken.getTokens().getPrincipal(), - data.authorizationToken.getTokens().getCredentials(), - data.authorizationToken.getTokens().getRealm() ); - break; - case "bearer": - authToken = AuthTokens.bearer( data.authorizationToken.getTokens().getCredentials() ); - break; - case "kerberos": - authToken = AuthTokens.kerberos( data.authorizationToken.getTokens().getCredentials() ); - break; - default: - authToken = AuthTokens.custom( - data.authorizationToken.getTokens().getPrincipal(), - data.authorizationToken.getTokens().getCredentials(), - data.authorizationToken.getTokens().getRealm(), - data.authorizationToken.getTokens().getScheme(), - data.authorizationToken.getTokens().getParameters() - ); - break; + switch (data.getAuthorizationToken().getTokens().getScheme()) { + case "basic": + authToken = AuthTokens.basic( + data.authorizationToken.getTokens().getPrincipal(), + data.authorizationToken.getTokens().getCredentials(), + data.authorizationToken.getTokens().getRealm()); + break; + case "bearer": + authToken = + AuthTokens.bearer(data.authorizationToken.getTokens().getCredentials()); + break; + case "kerberos": + authToken = + AuthTokens.kerberos(data.authorizationToken.getTokens().getCredentials()); + break; + default: + authToken = AuthTokens.custom( + data.authorizationToken.getTokens().getPrincipal(), + data.authorizationToken.getTokens().getCredentials(), + data.authorizationToken.getTokens().getRealm(), + data.authorizationToken.getTokens().getScheme(), + data.authorizationToken.getTokens().getParameters()); + break; } Config.ConfigBuilder configBuilder = Config.builder(); - if ( data.isResolverRegistered() ) - { - configBuilder.withResolver( callbackResolver( testkitState ) ); + if (data.isResolverRegistered()) { + configBuilder.withResolver(callbackResolver(testkitState)); } DomainNameResolver domainNameResolver = DefaultDomainNameResolver.getInstance(); - if ( data.isDomainNameResolverRegistered() ) - { - domainNameResolver = callbackDomainNameResolver( testkitState ); + if (data.isDomainNameResolverRegistered()) { + domainNameResolver = callbackDomainNameResolver(testkitState); } - Optional.ofNullable( data.userAgent ).ifPresent( configBuilder::withUserAgent ); - Optional.ofNullable( data.connectionTimeoutMs ).ifPresent( timeout -> configBuilder.withConnectionTimeout( timeout, TimeUnit.MILLISECONDS ) ); - Optional.ofNullable( data.fetchSize ).ifPresent( configBuilder::withFetchSize ); - RetrySettings retrySettings = Optional.ofNullable( data.maxTxRetryTimeMs ) - .map( RetrySettings::new ) - .orElse( RetrySettings.DEFAULT ); - Optional.ofNullable( data.livenessCheckTimeoutMs ) - .ifPresent( timeout -> configBuilder.withConnectionLivenessCheckTimeout( timeout, TimeUnit.MILLISECONDS ) ); - Optional.ofNullable( data.maxConnectionPoolSize ).ifPresent( configBuilder::withMaxConnectionPoolSize ); - Optional.ofNullable( data.connectionAcquisitionTimeoutMs ) - .ifPresent( timeout -> configBuilder.withConnectionAcquisitionTimeout( timeout, TimeUnit.MILLISECONDS ) ); + Optional.ofNullable(data.userAgent).ifPresent(configBuilder::withUserAgent); + Optional.ofNullable(data.connectionTimeoutMs) + .ifPresent(timeout -> configBuilder.withConnectionTimeout(timeout, TimeUnit.MILLISECONDS)); + Optional.ofNullable(data.fetchSize).ifPresent(configBuilder::withFetchSize); + RetrySettings retrySettings = Optional.ofNullable(data.maxTxRetryTimeMs) + .map(RetrySettings::new) + .orElse(RetrySettings.DEFAULT); + Optional.ofNullable(data.livenessCheckTimeoutMs) + .ifPresent(timeout -> configBuilder.withConnectionLivenessCheckTimeout(timeout, TimeUnit.MILLISECONDS)); + Optional.ofNullable(data.maxConnectionPoolSize).ifPresent(configBuilder::withMaxConnectionPoolSize); + Optional.ofNullable(data.connectionAcquisitionTimeoutMs) + .ifPresent(timeout -> configBuilder.withConnectionAcquisitionTimeout(timeout, TimeUnit.MILLISECONDS)); configBuilder.withDriverMetrics(); org.neo4j.driver.Driver driver; Config config = configBuilder.build(); - try - { - driver = driver( URI.create( data.uri ), authToken, config, retrySettings, domainNameResolver, configureSecuritySettingsBuilder(), testkitState, - id ); + try { + driver = driver( + URI.create(data.uri), + authToken, + config, + retrySettings, + domainNameResolver, + configureSecuritySettingsBuilder(), + testkitState, + id); + } catch (RuntimeException e) { + return handleExceptionAsErrorResponse(testkitState, e).orElseThrow(() -> e); } - catch ( RuntimeException e ) - { - return handleExceptionAsErrorResponse( testkitState, e ).orElseThrow( () -> e ); - } - testkitState.addDriverHolder( id, new DriverHolder( driver, config ) ); - return Driver.builder().data( Driver.DriverBody.builder().id( id ).build() ).build(); + testkitState.addDriverHolder(id, new DriverHolder(driver, config)); + return Driver.builder().data(Driver.DriverBody.builder().id(id).build()).build(); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return CompletableFuture.completedFuture( process( testkitState ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return CompletableFuture.completedFuture(process(testkitState)); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.fromCompletionStage( processAsync( testkitState ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.fromCompletionStage(processAsync(testkitState)); } - private ServerAddressResolver callbackResolver( TestkitState testkitState ) - { - return address -> - { + private ServerAddressResolver callbackResolver(TestkitState testkitState) { + return address -> { String callbackId = testkitState.newId(); ResolverResolutionRequired.ResolverResolutionRequiredBody body = ResolverResolutionRequired.ResolverResolutionRequiredBody.builder() - .id( callbackId ) - .address( String.format( "%s:%d", address.host(), address.port() ) ) - .build(); + .id(callbackId) + .address(String.format("%s:%d", address.host(), address.port())) + .build(); ResolverResolutionRequired response = - ResolverResolutionRequired.builder() - .data( body ) - .build(); - CompletionStage c = dispatchTestkitCallback( testkitState, response ); + ResolverResolutionRequired.builder().data(body).build(); + CompletionStage c = dispatchTestkitCallback(testkitState, response); ResolverResolutionCompleted resolutionCompleted; - try - { - resolutionCompleted = (ResolverResolutionCompleted) c.toCompletableFuture().get(); - } - catch ( Exception e ) - { - throw new RuntimeException( e ); + try { + resolutionCompleted = + (ResolverResolutionCompleted) c.toCompletableFuture().get(); + } catch (Exception e) { + throw new RuntimeException(e); } - return resolutionCompleted.getData().getAddresses() - .stream() - .map( BoltServerAddress::new ) - .collect( Collectors.toCollection( LinkedHashSet::new ) ); + return resolutionCompleted.getData().getAddresses().stream() + .map(BoltServerAddress::new) + .collect(Collectors.toCollection(LinkedHashSet::new)); }; } - private DomainNameResolver callbackDomainNameResolver( TestkitState testkitState ) - { - return address -> - { + private DomainNameResolver callbackDomainNameResolver(TestkitState testkitState) { + return address -> { String callbackId = testkitState.newId(); DomainNameResolutionRequired.DomainNameResolutionRequiredBody body = DomainNameResolutionRequired.DomainNameResolutionRequiredBody.builder() - .id( callbackId ) - .name( address ) - .build(); + .id(callbackId) + .name(address) + .build(); DomainNameResolutionRequired callback = - DomainNameResolutionRequired.builder() - .data( body ) - .build(); + DomainNameResolutionRequired.builder().data(body).build(); - CompletionStage callbackStage = dispatchTestkitCallback( testkitState, callback ); + CompletionStage callbackStage = dispatchTestkitCallback(testkitState, callback); DomainNameResolutionCompleted resolutionCompleted; - try - { - resolutionCompleted = (DomainNameResolutionCompleted) callbackStage.toCompletableFuture().get(); - } - catch ( Exception e ) - { - throw new RuntimeException( "Unexpected failure during Testkit callback", e ); + try { + resolutionCompleted = (DomainNameResolutionCompleted) + callbackStage.toCompletableFuture().get(); + } catch (Exception e) { + throw new RuntimeException("Unexpected failure during Testkit callback", e); } - return resolutionCompleted.getData().getAddresses() - .stream() - .map( - addr -> - { - try - { - return InetAddress.getByName( addr ); - } - catch ( UnknownHostException e ) - { - throw new RuntimeException( e ); - } - } ) - .toArray( InetAddress[]::new ); + return resolutionCompleted.getData().getAddresses().stream() + .map(addr -> { + try { + return InetAddress.getByName(addr); + } catch (UnknownHostException e) { + throw new RuntimeException(e); + } + }) + .toArray(InetAddress[]::new); }; } - private CompletionStage dispatchTestkitCallback( TestkitState testkitState, TestkitCallback response ) - { + private CompletionStage dispatchTestkitCallback( + TestkitState testkitState, TestkitCallback response) { CompletableFuture future = new CompletableFuture<>(); - testkitState.getCallbackIdToFuture().put( response.getCallbackId(), future ); - testkitState.getResponseWriter().accept( response ); + testkitState.getCallbackIdToFuture().put(response.getCallbackId(), future); + testkitState.getResponseWriter().accept(response); return future; } - private org.neo4j.driver.Driver driver( URI uri, AuthToken authToken, Config config, RetrySettings retrySettings, DomainNameResolver domainNameResolver, - SecuritySettings.SecuritySettingsBuilder securitySettingsBuilder, TestkitState testkitState, String driverId ) - { + private org.neo4j.driver.Driver driver( + URI uri, + AuthToken authToken, + Config config, + RetrySettings retrySettings, + DomainNameResolver domainNameResolver, + SecuritySettings.SecuritySettingsBuilder securitySettingsBuilder, + TestkitState testkitState, + String driverId) { RoutingSettings routingSettings = RoutingSettings.DEFAULT; SecuritySettings securitySettings = securitySettingsBuilder.build(); - SecurityPlan securityPlan = securitySettings.createSecurityPlan( uri.getScheme() ); - return new DriverFactoryWithDomainNameResolver( domainNameResolver, testkitState, driverId ) - .newInstance( uri, authToken, routingSettings, retrySettings, config, securityPlan ); + SecurityPlan securityPlan = securitySettings.createSecurityPlan(uri.getScheme()); + return new DriverFactoryWithDomainNameResolver(domainNameResolver, testkitState, driverId) + .newInstance(uri, authToken, routingSettings, retrySettings, config, securityPlan); } - private Optional handleExceptionAsErrorResponse( TestkitState testkitState, RuntimeException e ) - { + private Optional handleExceptionAsErrorResponse(TestkitState testkitState, RuntimeException e) { Optional response = Optional.empty(); - if ( e instanceof IllegalArgumentException && e.getMessage().startsWith( DriverFactory.NO_ROUTING_CONTEXT_ERROR_MESSAGE ) ) - { + if (e instanceof IllegalArgumentException + && e.getMessage().startsWith(DriverFactory.NO_ROUTING_CONTEXT_ERROR_MESSAGE)) { String id = testkitState.newId(); String errorType = e.getClass().getName(); - response = Optional.of( - DriverError.builder().data( DriverError.DriverErrorBody.builder().id( id ).errorType( errorType ).msg( e.getMessage() ).build() ).build() - ); + response = Optional.of(DriverError.builder() + .data(DriverError.DriverErrorBody.builder() + .id(id) + .errorType(errorType) + .msg(e.getMessage()) + .build()) + .build()); } return response; } - private SecuritySettings.SecuritySettingsBuilder configureSecuritySettingsBuilder() - { - SecuritySettings.SecuritySettingsBuilder securitySettingsBuilder = new SecuritySettings.SecuritySettingsBuilder(); - if ( data.encrypted ) - { + private SecuritySettings.SecuritySettingsBuilder configureSecuritySettingsBuilder() { + SecuritySettings.SecuritySettingsBuilder securitySettingsBuilder = + new SecuritySettings.SecuritySettingsBuilder(); + if (data.encrypted) { securitySettingsBuilder.withEncryption(); - } - else - { + } else { securitySettingsBuilder.withoutEncryption(); } - if ( data.trustedCertificates != null ) - { - if ( !data.trustedCertificates.isEmpty() ) - { + if (data.trustedCertificates != null) { + if (!data.trustedCertificates.isEmpty()) { File[] certs = data.trustedCertificates.stream() - .map( cert -> "/usr/local/share/custom-ca-certificates/" + cert ) - .map( Paths::get ) - .map( Path::toFile ) - .toArray( File[]::new ); - securitySettingsBuilder.withTrustStrategy( Config.TrustStrategy.trustCustomCertificateSignedBy( certs ) ); + .map(cert -> "/usr/local/share/custom-ca-certificates/" + cert) + .map(Paths::get) + .map(Path::toFile) + .toArray(File[]::new); + securitySettingsBuilder.withTrustStrategy(Config.TrustStrategy.trustCustomCertificateSignedBy(certs)); + } else { + securitySettingsBuilder.withTrustStrategy(Config.TrustStrategy.trustAllCertificates()); } - else - { - securitySettingsBuilder.withTrustStrategy( Config.TrustStrategy.trustAllCertificates() ); - } - } - else - { - securitySettingsBuilder.withTrustStrategy( Config.TrustStrategy.trustSystemCertificates() ); + } else { + securitySettingsBuilder.withTrustStrategy(Config.TrustStrategy.trustSystemCertificates()); } return securitySettingsBuilder; } @Setter @Getter - public static class NewDriverBody - { + public static class NewDriverBody { private String uri; private AuthorizationToken authorizationToken; private String userAgent; @@ -306,22 +284,19 @@ public static class NewDriverBody } @RequiredArgsConstructor - private static class DriverFactoryWithDomainNameResolver extends DriverFactory - { + private static class DriverFactoryWithDomainNameResolver extends DriverFactory { private final DomainNameResolver domainNameResolver; private final TestkitState testkitState; private final String driverId; @Override - protected DomainNameResolver getDomainNameResolver() - { + protected DomainNameResolver getDomainNameResolver() { return domainNameResolver; } @Override - protected void handleNewLoadBalancer( LoadBalancer loadBalancer ) - { - testkitState.getRoutingTableRegistry().put( driverId, loadBalancer.getRoutingTableRegistry() ); + protected void handleNewLoadBalancer(LoadBalancer loadBalancer) { + testkitState.getRoutingTableRegistry().put(driverId, loadBalancer.getRoutingTableRegistry()); } } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewSession.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewSession.java index 299e456d9a..331be83bb3 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewSession.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewSession.java @@ -18,6 +18,13 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -27,90 +34,77 @@ import neo4j.org.testkit.backend.holder.SessionHolder; import neo4j.org.testkit.backend.messages.responses.Session; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; - import org.neo4j.driver.AccessMode; import org.neo4j.driver.SessionConfig; import org.neo4j.driver.internal.InternalBookmark; +import reactor.core.publisher.Mono; @Setter @Getter -public class NewSession implements TestkitRequest -{ +public class NewSession implements TestkitRequest { private NewSessionBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - return createSessionStateAndResponse( testkitState, this::createSessionState, testkitState::addSessionHolder ); + public TestkitResponse process(TestkitState testkitState) { + return createSessionStateAndResponse(testkitState, this::createSessionState, testkitState::addSessionHolder); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return CompletableFuture.completedFuture( - createSessionStateAndResponse( testkitState, this::createAsyncSessionState, testkitState::addAsyncSessionHolder ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return CompletableFuture.completedFuture(createSessionStateAndResponse( + testkitState, this::createAsyncSessionState, testkitState::addAsyncSessionHolder)); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.just( createSessionStateAndResponse( testkitState, this::createRxSessionState, testkitState::addRxSessionHolder ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.just(createSessionStateAndResponse( + testkitState, this::createRxSessionState, testkitState::addRxSessionHolder)); } - protected TestkitResponse createSessionStateAndResponse( TestkitState testkitState, BiFunction sessionStateProducer, - Function addSessionHolder ) - { - DriverHolder driverHolder = testkitState.getDriverHolder( data.getDriverId() ); - AccessMode formattedAccessMode = data.getAccessMode().equals( "r" ) ? AccessMode.READ : AccessMode.WRITE; - SessionConfig.Builder builder = SessionConfig.builder() - .withDefaultAccessMode( formattedAccessMode ); + protected TestkitResponse createSessionStateAndResponse( + TestkitState testkitState, + BiFunction sessionStateProducer, + Function addSessionHolder) { + DriverHolder driverHolder = testkitState.getDriverHolder(data.getDriverId()); + AccessMode formattedAccessMode = data.getAccessMode().equals("r") ? AccessMode.READ : AccessMode.WRITE; + SessionConfig.Builder builder = SessionConfig.builder().withDefaultAccessMode(formattedAccessMode); - Optional.ofNullable( data.bookmarks ) - .map( bookmarks -> bookmarks.stream().map( InternalBookmark::parse ).collect( Collectors.toList() ) ) - .ifPresent( builder::withBookmarks ); + Optional.ofNullable(data.bookmarks) + .map(bookmarks -> + bookmarks.stream().map(InternalBookmark::parse).collect(Collectors.toList())) + .ifPresent(builder::withBookmarks); - Optional.ofNullable( data.database ).ifPresent( builder::withDatabase ); - Optional.ofNullable( data.impersonatedUser ).ifPresent( builder::withImpersonatedUser ); + Optional.ofNullable(data.database).ifPresent(builder::withDatabase); + Optional.ofNullable(data.impersonatedUser).ifPresent(builder::withImpersonatedUser); - if ( data.getFetchSize() != 0 ) - { - builder.withFetchSize( data.getFetchSize() ); + if (data.getFetchSize() != 0) { + builder.withFetchSize(data.getFetchSize()); } - T sessionStateHolder = sessionStateProducer.apply( driverHolder, builder.build() ); - String newId = addSessionHolder.apply( sessionStateHolder ); + T sessionStateHolder = sessionStateProducer.apply(driverHolder, builder.build()); + String newId = addSessionHolder.apply(sessionStateHolder); - return Session.builder().data( Session.SessionBody.builder().id( newId ).build() ).build(); + return Session.builder() + .data(Session.SessionBody.builder().id(newId).build()) + .build(); } - private SessionHolder createSessionState( DriverHolder driverHolder, SessionConfig sessionConfig ) - { - return new SessionHolder( driverHolder, driverHolder.getDriver().session( sessionConfig ), sessionConfig ); + private SessionHolder createSessionState(DriverHolder driverHolder, SessionConfig sessionConfig) { + return new SessionHolder(driverHolder, driverHolder.getDriver().session(sessionConfig), sessionConfig); } - private AsyncSessionHolder createAsyncSessionState( DriverHolder driverHolder, SessionConfig sessionConfig ) - { - return new AsyncSessionHolder( driverHolder, driverHolder.getDriver().asyncSession( sessionConfig ), sessionConfig ); + private AsyncSessionHolder createAsyncSessionState(DriverHolder driverHolder, SessionConfig sessionConfig) { + return new AsyncSessionHolder( + driverHolder, driverHolder.getDriver().asyncSession(sessionConfig), sessionConfig); } - private RxSessionHolder createRxSessionState( DriverHolder driverHolder, SessionConfig sessionConfig ) - { - return new RxSessionHolder( driverHolder, driverHolder.getDriver().rxSession( sessionConfig ), sessionConfig ); + private RxSessionHolder createRxSessionState(DriverHolder driverHolder, SessionConfig sessionConfig) { + return new RxSessionHolder(driverHolder, driverHolder.getDriver().rxSession(sessionConfig), sessionConfig); } @Setter @Getter - public static class NewSessionBody - { + public static class NewSessionBody { private String driverId; private String accessMode; private List bookmarks; diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResolverResolutionCompleted.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResolverResolutionCompleted.java index 38484e381d..151302c608 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResolverResolutionCompleted.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResolverResolutionCompleted.java @@ -18,27 +18,23 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.List; import lombok.Getter; import lombok.Setter; -import java.util.List; - @Setter @Getter -public class ResolverResolutionCompleted implements TestkitCallbackResult -{ +public class ResolverResolutionCompleted implements TestkitCallbackResult { private ResolverResolutionCompletedBody data; @Override - public String getCallbackId() - { + public String getCallbackId() { return data.getRequestId(); } @Setter @Getter - public static class ResolverResolutionCompletedBody - { + public static class ResolverResolutionCompletedBody { private String requestId; private List addresses; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultConsume.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultConsume.java index 560a150d74..e32cf48b94 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultConsume.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultConsume.java @@ -18,14 +18,6 @@ */ package neo4j.org.testkit.backend.messages.requests; -import lombok.Getter; -import lombok.Setter; -import neo4j.org.testkit.backend.TestkitState; -import neo4j.org.testkit.backend.messages.responses.NullRecord; -import neo4j.org.testkit.backend.messages.responses.Summary; -import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,7 +25,12 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; - +import lombok.Getter; +import lombok.Setter; +import neo4j.org.testkit.backend.TestkitState; +import neo4j.org.testkit.backend.messages.responses.NullRecord; +import neo4j.org.testkit.backend.messages.responses.Summary; +import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import org.neo4j.driver.Query; import org.neo4j.driver.Result; import org.neo4j.driver.exceptions.NoSuchRecordException; @@ -42,190 +39,167 @@ import org.neo4j.driver.summary.ProfiledPlan; import org.neo4j.driver.summary.QueryType; import org.neo4j.driver.summary.SummaryCounters; +import reactor.core.publisher.Mono; @Setter @Getter -public class ResultConsume implements TestkitRequest -{ +public class ResultConsume implements TestkitRequest { private ResultConsumeBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - try - { - Result result = testkitState.getResultHolder( data.getResultId() ).getResult(); - return createResponse( result.consume() ); - } - catch ( NoSuchRecordException ignored ) - { + public TestkitResponse process(TestkitState testkitState) { + try { + Result result = testkitState.getResultHolder(data.getResultId()).getResult(); + return createResponse(result.consume()); + } catch (NoSuchRecordException ignored) { return NullRecord.builder().build(); } } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncResultHolder( data.getResultId() ) - .thenCompose( resultCursorHolder -> resultCursorHolder.getResult().consumeAsync() ) - .thenApply( this::createResponse ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncResultHolder(data.getResultId()) + .thenCompose( + resultCursorHolder -> resultCursorHolder.getResult().consumeAsync()) + .thenApply(this::createResponse); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxResultHolder( data.getResultId() ) - .flatMap( resultHolder -> Mono.fromDirect( resultHolder.getResult().consume() ) ) - .map( this::createResponse ); + public Mono processRx(TestkitState testkitState) { + return testkitState + .getRxResultHolder(data.getResultId()) + .flatMap( + resultHolder -> Mono.fromDirect(resultHolder.getResult().consume())) + .map(this::createResponse); } - private Summary createResponse( org.neo4j.driver.summary.ResultSummary summary ) - { + private Summary createResponse(org.neo4j.driver.summary.ResultSummary summary) { Summary.ServerInfo serverInfo = Summary.ServerInfo.builder() - .address( summary.server().address() ) - .protocolVersion( summary.server().protocolVersion() ) - .agent( summary.server().agent() ) - .build(); + .address(summary.server().address()) + .protocolVersion(summary.server().protocolVersion()) + .agent(summary.server().agent()) + .build(); SummaryCounters summaryCounters = summary.counters(); Summary.Counters counters = Summary.Counters.builder() - .constraintsAdded( summaryCounters.constraintsAdded() ) - .constraintsRemoved( summaryCounters.constraintsRemoved() ) - .containsSystemUpdates( summaryCounters.containsSystemUpdates() ) - .containsUpdates( summaryCounters.containsUpdates() ) - .indexesAdded( summaryCounters.indexesAdded() ) - .indexesRemoved( summaryCounters.indexesRemoved() ) - .labelsAdded( summaryCounters.labelsAdded() ) - .labelsRemoved( summaryCounters.labelsRemoved() ) - .nodesCreated( summaryCounters.nodesCreated() ) - .nodesDeleted( summaryCounters.nodesDeleted() ) - .propertiesSet( summaryCounters.propertiesSet() ) - .relationshipsCreated( summaryCounters.relationshipsCreated() ) - .relationshipsDeleted( summaryCounters.relationshipsDeleted() ) - .systemUpdates( summaryCounters.systemUpdates() ) - .build(); + .constraintsAdded(summaryCounters.constraintsAdded()) + .constraintsRemoved(summaryCounters.constraintsRemoved()) + .containsSystemUpdates(summaryCounters.containsSystemUpdates()) + .containsUpdates(summaryCounters.containsUpdates()) + .indexesAdded(summaryCounters.indexesAdded()) + .indexesRemoved(summaryCounters.indexesRemoved()) + .labelsAdded(summaryCounters.labelsAdded()) + .labelsRemoved(summaryCounters.labelsRemoved()) + .nodesCreated(summaryCounters.nodesCreated()) + .nodesDeleted(summaryCounters.nodesDeleted()) + .propertiesSet(summaryCounters.propertiesSet()) + .relationshipsCreated(summaryCounters.relationshipsCreated()) + .relationshipsDeleted(summaryCounters.relationshipsDeleted()) + .systemUpdates(summaryCounters.systemUpdates()) + .build(); Query summaryQuery = summary.query(); Summary.Query query = Summary.Query.builder() - .text( summaryQuery.text() ) - .parameters( summaryQuery.parameters().asMap( Function.identity(), null ) ) - .build(); + .text(summaryQuery.text()) + .parameters(summaryQuery.parameters().asMap(Function.identity(), null)) + .build(); List notifications = summary.notifications().stream() - .map( s -> Summary.Notification.builder() - .code( s.code() ) - .title( s.title() ) - .description( s.description() ) - .position( toInputPosition( s.position() ) ) - .severity( s.severity() ) - .build() ) - .collect( Collectors.toList() ); + .map(s -> Summary.Notification.builder() + .code(s.code()) + .title(s.title()) + .description(s.description()) + .position(toInputPosition(s.position())) + .severity(s.severity()) + .build()) + .collect(Collectors.toList()); Summary.SummaryBody data = Summary.SummaryBody.builder() - .serverInfo( serverInfo ) - .counters( counters ) - .query( query ) - .database( summary.database().name() ) - .notifications( notifications ) - .plan( toPlan( summary.plan() ) ) - .profile( toProfile( summary.profile() ) ) - .queryType( toQueryType( summary.queryType() ) ) - .resultAvailableAfter( summary.resultAvailableAfter( TimeUnit.MILLISECONDS ) == -1 - ? null : summary.resultAvailableAfter( TimeUnit.MILLISECONDS ) ) - .resultConsumedAfter( summary.resultConsumedAfter( TimeUnit.MILLISECONDS ) == -1 - ? null : summary.resultConsumedAfter( TimeUnit.MILLISECONDS ) ) - .build(); - return Summary.builder() - .data( data ) - .build(); + .serverInfo(serverInfo) + .counters(counters) + .query(query) + .database(summary.database().name()) + .notifications(notifications) + .plan(toPlan(summary.plan())) + .profile(toProfile(summary.profile())) + .queryType(toQueryType(summary.queryType())) + .resultAvailableAfter( + summary.resultAvailableAfter(TimeUnit.MILLISECONDS) == -1 + ? null + : summary.resultAvailableAfter(TimeUnit.MILLISECONDS)) + .resultConsumedAfter( + summary.resultConsumedAfter(TimeUnit.MILLISECONDS) == -1 + ? null + : summary.resultConsumedAfter(TimeUnit.MILLISECONDS)) + .build(); + return Summary.builder().data(data).build(); } @Setter @Getter - public static class ResultConsumeBody - { + public static class ResultConsumeBody { private String resultId; } - private static Summary.InputPosition toInputPosition( InputPosition position ) - { - if ( position == null ) - { + private static Summary.InputPosition toInputPosition(InputPosition position) { + if (position == null) { return null; } return Summary.InputPosition.builder() - .offset( position.offset() ) - .line( position.line() ) - .column( position.column() ) - .build(); + .offset(position.offset()) + .line(position.line()) + .column(position.column()) + .build(); } - private static Summary.Plan toPlan( Plan plan ) - { - if ( plan == null ) - { + private static Summary.Plan toPlan(Plan plan) { + if (plan == null) { return null; } - Map args = new HashMap<>(); - plan.arguments().forEach( ( key, value ) -> args.put( key, value.asObject() ) ); + Map args = new HashMap<>(); + plan.arguments().forEach((key, value) -> args.put(key, value.asObject())); return Summary.Plan.builder() - .operatorType( plan.operatorType() ) - .args( args ) - .identifiers( plan.identifiers() ) - .children( plan.children().stream() - .map( ResultConsume::toPlan ) - .collect( Collectors.toList() ) ) - .build(); + .operatorType(plan.operatorType()) + .args(args) + .identifiers(plan.identifiers()) + .children(plan.children().stream().map(ResultConsume::toPlan).collect(Collectors.toList())) + .build(); } - private static Summary.Profile toProfile( ProfiledPlan plan ) - { - if ( plan == null ) - { + private static Summary.Profile toProfile(ProfiledPlan plan) { + if (plan == null) { return null; } - Map args = new HashMap<>(); - plan.arguments().forEach( ( key, value ) -> args.put( key, value.asObject() ) ); + Map args = new HashMap<>(); + plan.arguments().forEach((key, value) -> args.put(key, value.asObject())); return Summary.Profile.builder() - .operatorType( plan.operatorType() ) - .args( args ) - .identifiers( plan.identifiers() ) - .dbHits( plan.dbHits() ) - .rows( plan.records() ) - .hasPageCacheStats( plan.hasPageCacheStats() ) - .pageCacheHits( plan.pageCacheHits() ) - .pageCacheMisses( plan.pageCacheMisses() ) - .pageCacheHitRatio( plan.pageCacheHitRatio() ) - .time( plan.time() ) - .children( plan.children().stream() - .map( ResultConsume::toProfile ) - .collect( Collectors.toList() ) ) - .build(); + .operatorType(plan.operatorType()) + .args(args) + .identifiers(plan.identifiers()) + .dbHits(plan.dbHits()) + .rows(plan.records()) + .hasPageCacheStats(plan.hasPageCacheStats()) + .pageCacheHits(plan.pageCacheHits()) + .pageCacheMisses(plan.pageCacheMisses()) + .pageCacheHitRatio(plan.pageCacheHitRatio()) + .time(plan.time()) + .children(plan.children().stream().map(ResultConsume::toProfile).collect(Collectors.toList())) + .build(); } - private static String toQueryType( QueryType type ) - { - if ( type == null ) - { + private static String toQueryType(QueryType type) { + if (type == null) { return null; } String typeStr; - if ( type == QueryType.READ_ONLY ) - { + if (type == QueryType.READ_ONLY) { typeStr = "r"; - } - else if ( type == QueryType.READ_WRITE ) - { + } else if (type == QueryType.READ_WRITE) { typeStr = "rw"; - } - else if ( type == QueryType.WRITE_ONLY ) - { + } else if (type == QueryType.WRITE_ONLY) { typeStr = "w"; - } - else if ( type == QueryType.SCHEMA_WRITE ) - { + } else if (type == QueryType.SCHEMA_WRITE) { typeStr = "s"; - } - else - { - throw new IllegalStateException( "Unexpected query type" ); + } else { + throw new IllegalStateException("Unexpected query type"); } return typeStr; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultList.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultList.java index 90dd640567..93e042e743 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultList.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultList.java @@ -18,6 +18,9 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.List; +import java.util.concurrent.CompletionStage; +import java.util.stream.Collectors; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -26,50 +29,43 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.List; -import java.util.concurrent.CompletionStage; -import java.util.stream.Collectors; - @Setter @Getter -public class ResultList implements TestkitRequest -{ +public class ResultList implements TestkitRequest { private ResultListBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - return createResponse( testkitState.getResultHolder( data.getResultId() ).getResult().list() ); + public TestkitResponse process(TestkitState testkitState) { + return createResponse( + testkitState.getResultHolder(data.getResultId()).getResult().list()); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncResultHolder( data.getResultId() ) - .thenCompose( resultCursorHolder -> resultCursorHolder.getResult().listAsync() ) - .thenApply( this::createResponse ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncResultHolder(data.getResultId()) + .thenCompose( + resultCursorHolder -> resultCursorHolder.getResult().listAsync()) + .thenApply(this::createResponse); } @Override - public Mono processRx( TestkitState testkitState ) - { - throw new UnsupportedOperationException( "Operation not supported" ); + public Mono processRx(TestkitState testkitState) { + throw new UnsupportedOperationException("Operation not supported"); } - private RecordList createResponse( List records ) - { + private RecordList createResponse(List records) { List mappedRecords = records.stream() - .map( record -> Record.RecordBody.builder().values( record ).build() ) - .collect( Collectors.toList() ); + .map(record -> Record.RecordBody.builder().values(record).build()) + .collect(Collectors.toList()); return RecordList.builder() - .data( RecordList.RecordListBody.builder().records( mappedRecords ).build() ) - .build(); + .data(RecordList.RecordListBody.builder().records(mappedRecords).build()) + .build(); } @Setter @Getter - public static class ResultListBody - { + public static class ResultListBody { private String resultId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultNext.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultNext.java index 6a434ca3d5..26112ba18a 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultNext.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultNext.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.RxBufferedSubscriber; @@ -25,92 +26,82 @@ import neo4j.org.testkit.backend.holder.RxResultHolder; import neo4j.org.testkit.backend.messages.responses.NullRecord; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Record; import org.neo4j.driver.Result; import org.neo4j.driver.exceptions.NoSuchRecordException; +import reactor.core.publisher.Mono; @Setter @Getter -public class ResultNext implements TestkitRequest -{ +public class ResultNext implements TestkitRequest { private ResultNextBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - try - { - Result result = testkitState.getResultHolder( data.getResultId() ).getResult(); - return createResponse( result.next() ); - } - catch ( NoSuchRecordException ignored ) - { + public TestkitResponse process(TestkitState testkitState) { + try { + Result result = testkitState.getResultHolder(data.getResultId()).getResult(); + return createResponse(result.next()); + } catch (NoSuchRecordException ignored) { return NullRecord.builder().build(); } } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncResultHolder( data.getResultId() ) - .thenCompose( resultCursorHolder -> resultCursorHolder.getResult().nextAsync() ) - .thenApply( this::createResponseNullSafe ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncResultHolder(data.getResultId()) + .thenCompose( + resultCursorHolder -> resultCursorHolder.getResult().nextAsync()) + .thenApply(this::createResponseNullSafe); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxResultHolder( data.getResultId() ) - .flatMap( resultHolder -> - { - RxBufferedSubscriber subscriber = - resultHolder.getSubscriber() - .orElseGet( () -> - { - RxBufferedSubscriber subscriberInstance = - new RxBufferedSubscriber<>( - getFetchSize( resultHolder ) ); - resultHolder.setSubscriber( subscriberInstance ); - resultHolder.getResult().records() - .subscribe( subscriberInstance ); - return subscriberInstance; - } ); - return subscriber.next() - .map( this::createResponse ) - .defaultIfEmpty( NullRecord.builder().build() ); - } ); + public Mono processRx(TestkitState testkitState) { + return testkitState.getRxResultHolder(data.getResultId()).flatMap(resultHolder -> { + RxBufferedSubscriber subscriber = resultHolder + .getSubscriber() + .orElseGet(() -> { + RxBufferedSubscriber subscriberInstance = + new RxBufferedSubscriber<>(getFetchSize(resultHolder)); + resultHolder.setSubscriber(subscriberInstance); + resultHolder.getResult().records().subscribe(subscriberInstance); + return subscriberInstance; + }); + return subscriber + .next() + .map(this::createResponse) + .defaultIfEmpty(NullRecord.builder().build()); + }); } - private long getFetchSize( RxResultHolder resultHolder ) - { - long fetchSize = resultHolder.getSessionHolder().getConfig() - .fetchSize() - .orElse( resultHolder.getSessionHolder().getDriverHolder().getConfig().fetchSize() ); + private long getFetchSize(RxResultHolder resultHolder) { + long fetchSize = resultHolder + .getSessionHolder() + .getConfig() + .fetchSize() + .orElse(resultHolder + .getSessionHolder() + .getDriverHolder() + .getConfig() + .fetchSize()); return fetchSize == -1 ? Long.MAX_VALUE : fetchSize; } - private neo4j.org.testkit.backend.messages.responses.TestkitResponse createResponse( Record record ) - { + private neo4j.org.testkit.backend.messages.responses.TestkitResponse createResponse(Record record) { return neo4j.org.testkit.backend.messages.responses.Record.builder() - .data( neo4j.org.testkit.backend.messages.responses.Record.RecordBody.builder() - .values( record ) - .build() ) - .build(); + .data(neo4j.org.testkit.backend.messages.responses.Record.RecordBody.builder() + .values(record) + .build()) + .build(); } - private neo4j.org.testkit.backend.messages.responses.TestkitResponse createResponseNullSafe( Record record ) - { - return record != null ? createResponse( record ) : NullRecord.builder().build(); + private neo4j.org.testkit.backend.messages.responses.TestkitResponse createResponseNullSafe(Record record) { + return record != null ? createResponse(record) : NullRecord.builder().build(); } @Setter @Getter - public static class ResultNextBody - { + public static class ResultNextBody { private String resultId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultPeek.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultPeek.java index 4853318449..5df0ea6478 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultPeek.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/ResultPeek.java @@ -18,11 +18,10 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; -import neo4j.org.testkit.backend.RxBufferedSubscriber; import neo4j.org.testkit.backend.TestkitState; -import neo4j.org.testkit.backend.holder.RxResultHolder; import neo4j.org.testkit.backend.messages.responses.NullRecord; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import org.neo4j.driver.Record; @@ -30,60 +29,50 @@ import org.neo4j.driver.exceptions.NoSuchRecordException; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class ResultPeek implements TestkitRequest -{ +public class ResultPeek implements TestkitRequest { private ResultPeekBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - try - { - Result result = testkitState.getResultHolder( data.getResultId() ).getResult(); - return createResponse( result.peek() ); - } - catch ( NoSuchRecordException ignored ) - { + public TestkitResponse process(TestkitState testkitState) { + try { + Result result = testkitState.getResultHolder(data.getResultId()).getResult(); + return createResponse(result.peek()); + } catch (NoSuchRecordException ignored) { return NullRecord.builder().build(); } } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncResultHolder( data.getResultId() ) - .thenCompose( resultCursorHolder -> resultCursorHolder.getResult().peekAsync() ) - .thenApply( this::createResponseNullSafe ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncResultHolder(data.getResultId()) + .thenCompose( + resultCursorHolder -> resultCursorHolder.getResult().peekAsync()) + .thenApply(this::createResponseNullSafe); } @Override - public Mono processRx( TestkitState testkitState ) - { - throw new UnsupportedOperationException( "Operation not supported" ); + public Mono processRx(TestkitState testkitState) { + throw new UnsupportedOperationException("Operation not supported"); } - private TestkitResponse createResponse( Record record ) - { + private TestkitResponse createResponse(Record record) { return neo4j.org.testkit.backend.messages.responses.Record.builder() - .data( neo4j.org.testkit.backend.messages.responses.Record.RecordBody.builder() - .values( record ) - .build() ) - .build(); + .data(neo4j.org.testkit.backend.messages.responses.Record.RecordBody.builder() + .values(record) + .build()) + .build(); } - private TestkitResponse createResponseNullSafe( Record record ) - { - return record != null ? createResponse( record ) : NullRecord.builder().build(); + private TestkitResponse createResponseNullSafe(Record record) { + return record != null ? createResponse(record) : NullRecord.builder().build(); } @Setter @Getter - public static class ResultPeekBody - { + public static class ResultPeekBody { private String resultId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/RetryableNegative.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/RetryableNegative.java index c5f5c0466c..f3ca81b63c 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/RetryableNegative.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/RetryableNegative.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,77 +26,55 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class RetryableNegative implements TestkitRequest -{ +public class RetryableNegative implements TestkitRequest { private RetryableNegativeBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - SessionHolder sessionHolder = testkitState.getSessionHolder( data.sessionId ); + public TestkitResponse process(TestkitState testkitState) { + SessionHolder sessionHolder = testkitState.getSessionHolder(data.sessionId); Throwable throwable; - if ( !"".equals( data.getErrorId() ) ) - { - throwable = testkitState.getErrors().get( data.getErrorId() ); - } - else - { - throwable = new RuntimeException( "Error from client in retryable tx" ); + if (!"".equals(data.getErrorId())) { + throwable = testkitState.getErrors().get(data.getErrorId()); + } else { + throwable = new RuntimeException("Error from client in retryable tx"); } - sessionHolder.getTxWorkFuture().completeExceptionally( throwable ); + sessionHolder.getTxWorkFuture().completeExceptionally(throwable); return null; } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncSessionHolder( data.getSessionId() ) - .thenApply( - sessionHolder -> - { - Throwable throwable; - if ( !"".equals( data.getErrorId() ) ) - { - throwable = testkitState.getErrors().get( data.getErrorId() ); - } - else - { - throwable = new RuntimeException( "Error from client in retryable tx" ); - } - sessionHolder.getTxWorkFuture().completeExceptionally( throwable ); - return null; - } ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState.getAsyncSessionHolder(data.getSessionId()).thenApply(sessionHolder -> { + Throwable throwable; + if (!"".equals(data.getErrorId())) { + throwable = testkitState.getErrors().get(data.getErrorId()); + } else { + throwable = new RuntimeException("Error from client in retryable tx"); + } + sessionHolder.getTxWorkFuture().completeExceptionally(throwable); + return null; + }); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxSessionHolder( data.getSessionId() ) - .mapNotNull( - sessionHolder -> - { - Throwable throwable; - if ( !"".equals( data.getErrorId() ) ) - { - throwable = testkitState.getErrors().get( data.getErrorId() ); - } - else - { - throwable = new RuntimeException( "Error from client in retryable tx" ); - } - sessionHolder.getTxWorkFuture().completeExceptionally( throwable ); - return null; - } ); + public Mono processRx(TestkitState testkitState) { + return testkitState.getRxSessionHolder(data.getSessionId()).mapNotNull(sessionHolder -> { + Throwable throwable; + if (!"".equals(data.getErrorId())) { + throwable = testkitState.getErrors().get(data.getErrorId()); + } else { + throwable = new RuntimeException("Error from client in retryable tx"); + } + sessionHolder.getTxWorkFuture().completeExceptionally(throwable); + return null; + }); } @Setter @Getter - public static class RetryableNegativeBody - { + public static class RetryableNegativeBody { private String sessionId; private String errorId; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/RetryablePositive.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/RetryablePositive.java index 4a7990ebbc..3e6d9fe119 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/RetryablePositive.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/RetryablePositive.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,52 +26,40 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class RetryablePositive implements TestkitRequest -{ +public class RetryablePositive implements TestkitRequest { private RetryablePositiveBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - SessionHolder sessionHolder = testkitState.getSessionHolder( data.sessionId ); - if ( sessionHolder == null ) - { - throw new RuntimeException( "Could not find session" ); + public TestkitResponse process(TestkitState testkitState) { + SessionHolder sessionHolder = testkitState.getSessionHolder(data.sessionId); + if (sessionHolder == null) { + throw new RuntimeException("Could not find session"); } - sessionHolder.getTxWorkFuture().complete( null ); + sessionHolder.getTxWorkFuture().complete(null); return null; } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncSessionHolder( data.getSessionId() ) - .thenApply( sessionHolder -> - { - sessionHolder.getTxWorkFuture().complete( null ); - return null; - } ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState.getAsyncSessionHolder(data.getSessionId()).thenApply(sessionHolder -> { + sessionHolder.getTxWorkFuture().complete(null); + return null; + }); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxSessionHolder( data.getSessionId() ) - .mapNotNull( sessionHolder -> - { - sessionHolder.getTxWorkFuture().complete( null ); - return null; - } ); + public Mono processRx(TestkitState testkitState) { + return testkitState.getRxSessionHolder(data.getSessionId()).mapNotNull(sessionHolder -> { + sessionHolder.getTxWorkFuture().complete(null); + return null; + }); } @Setter @Getter - public static class RetryablePositiveBody - { + public static class RetryablePositiveBody { private String sessionId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionBeginTransaction.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionBeginTransaction.java index 0b10511fa2..fc4d7ac927 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionBeginTransaction.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionBeginTransaction.java @@ -18,6 +18,10 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.time.Duration; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -27,93 +31,77 @@ import neo4j.org.testkit.backend.holder.TransactionHolder; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import neo4j.org.testkit.backend.messages.responses.Transaction; -import reactor.core.publisher.Mono; - -import java.time.Duration; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Session; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.reactive.RxSession; +import reactor.core.publisher.Mono; @Setter @Getter -public class SessionBeginTransaction implements TestkitRequest -{ +public class SessionBeginTransaction implements TestkitRequest { private SessionBeginTransactionBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - SessionHolder sessionHolder = testkitState.getSessionHolder( data.getSessionId() ); + public TestkitResponse process(TestkitState testkitState) { + SessionHolder sessionHolder = testkitState.getSessionHolder(data.getSessionId()); Session session = sessionHolder.getSession(); TransactionConfig.Builder builder = TransactionConfig.builder(); - Optional.ofNullable( data.txMeta ).ifPresent( builder::withMetadata ); + Optional.ofNullable(data.txMeta).ifPresent(builder::withMetadata); - if ( data.getTimeout() != null ) - { - builder.withTimeout( Duration.ofMillis( data.getTimeout() ) ); + if (data.getTimeout() != null) { + builder.withTimeout(Duration.ofMillis(data.getTimeout())); } - org.neo4j.driver.Transaction transaction = session.beginTransaction( builder.build() ); - return transaction( testkitState.addTransactionHolder( new TransactionHolder( sessionHolder, transaction ) ) ); + org.neo4j.driver.Transaction transaction = session.beginTransaction(builder.build()); + return transaction(testkitState.addTransactionHolder(new TransactionHolder(sessionHolder, transaction))); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncSessionHolder( data.getSessionId() ) - .thenCompose( sessionHolder -> - { - AsyncSession session = sessionHolder.getSession(); - TransactionConfig.Builder builder = TransactionConfig.builder(); - Optional.ofNullable( data.txMeta ).ifPresent( builder::withMetadata ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState.getAsyncSessionHolder(data.getSessionId()).thenCompose(sessionHolder -> { + AsyncSession session = sessionHolder.getSession(); + TransactionConfig.Builder builder = TransactionConfig.builder(); + Optional.ofNullable(data.txMeta).ifPresent(builder::withMetadata); - if ( data.getTimeout() != null ) - { - builder.withTimeout( Duration.ofMillis( data.getTimeout() ) ); - } + if (data.getTimeout() != null) { + builder.withTimeout(Duration.ofMillis(data.getTimeout())); + } - return session.beginTransactionAsync( builder.build() ).thenApply( tx -> transaction( - testkitState.addAsyncTransactionHolder( new AsyncTransactionHolder( sessionHolder, tx ) ) ) ); - } ); + return session.beginTransactionAsync(builder.build()) + .thenApply(tx -> transaction( + testkitState.addAsyncTransactionHolder(new AsyncTransactionHolder(sessionHolder, tx)))); + }); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxSessionHolder( data.getSessionId() ) - .flatMap( sessionHolder -> - { - RxSession session = sessionHolder.getSession(); - TransactionConfig.Builder builder = TransactionConfig.builder(); - Optional.ofNullable( data.txMeta ).ifPresent( builder::withMetadata ); + public Mono processRx(TestkitState testkitState) { + return testkitState.getRxSessionHolder(data.getSessionId()).flatMap(sessionHolder -> { + RxSession session = sessionHolder.getSession(); + TransactionConfig.Builder builder = TransactionConfig.builder(); + Optional.ofNullable(data.txMeta).ifPresent(builder::withMetadata); - if ( data.getTimeout() != null ) - { - builder.withTimeout( Duration.ofMillis( data.getTimeout() ) ); - } + if (data.getTimeout() != null) { + builder.withTimeout(Duration.ofMillis(data.getTimeout())); + } - return Mono.fromDirect( session.beginTransaction( builder.build() ) ) - .map( tx -> transaction( - testkitState.addRxTransactionHolder( new RxTransactionHolder( sessionHolder, tx ) ) ) ); - } ); + return Mono.fromDirect(session.beginTransaction(builder.build())) + .map(tx -> transaction( + testkitState.addRxTransactionHolder(new RxTransactionHolder(sessionHolder, tx)))); + }); } - private Transaction transaction( String txId ) - { - return Transaction.builder().data( Transaction.TransactionBody.builder().id( txId ).build() ).build(); + private Transaction transaction(String txId) { + return Transaction.builder() + .data(Transaction.TransactionBody.builder().id(txId).build()) + .build(); } @Getter @Setter - public static class SessionBeginTransactionBody - { + public static class SessionBeginTransactionBody { private String sessionId; - private Map txMeta; + private Map txMeta; private Integer timeout; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionClose.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionClose.java index d3680a3f49..279c780dae 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionClose.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionClose.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,46 +26,43 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class SessionClose implements TestkitRequest -{ +public class SessionClose implements TestkitRequest { private SessionCloseBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - testkitState.getSessionHolder( data.getSessionId() ).getSession().close(); + public TestkitResponse process(TestkitState testkitState) { + testkitState.getSessionHolder(data.getSessionId()).getSession().close(); return createResponse(); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncSessionHolder( data.getSessionId() ) - .thenCompose( sessionHolder -> sessionHolder.getSession().closeAsync() ) - .thenApply( ignored -> createResponse() ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncSessionHolder(data.getSessionId()) + .thenCompose(sessionHolder -> sessionHolder.getSession().closeAsync()) + .thenApply(ignored -> createResponse()); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxSessionHolder( data.getSessionId() ) - .flatMap( sessionHolder -> Mono.fromDirect( sessionHolder.getSession().close() ) ) - .then( Mono.just( createResponse() ) ); + public Mono processRx(TestkitState testkitState) { + return testkitState + .getRxSessionHolder(data.getSessionId()) + .flatMap(sessionHolder -> + Mono.fromDirect(sessionHolder.getSession().close())) + .then(Mono.just(createResponse())); } - private Session createResponse() - { - return Session.builder().data( Session.SessionBody.builder().id( data.getSessionId() ).build() ).build(); + private Session createResponse() { + return Session.builder() + .data(Session.SessionBody.builder().id(data.getSessionId()).build()) + .build(); } @Setter @Getter - private static class SessionCloseBody - { + private static class SessionCloseBody { private String sessionId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionLastBookmarks.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionLastBookmarks.java index f227d94e3b..2ee796ebd6 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionLastBookmarks.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionLastBookmarks.java @@ -18,57 +18,53 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; import neo4j.org.testkit.backend.holder.SessionHolder; import neo4j.org.testkit.backend.messages.responses.Bookmarks; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Bookmark; +import reactor.core.publisher.Mono; @Setter @Getter -public class SessionLastBookmarks implements TestkitRequest -{ +public class SessionLastBookmarks implements TestkitRequest { private SessionLastBookmarksBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - SessionHolder sessionHolder = testkitState.getSessionHolder( data.getSessionId() ); + public TestkitResponse process(TestkitState testkitState) { + SessionHolder sessionHolder = testkitState.getSessionHolder(data.getSessionId()); Bookmark bookmark = sessionHolder.getSession().lastBookmark(); - return createResponse( bookmark ); + return createResponse(bookmark); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncSessionHolder( data.getSessionId() ) - .thenApply( sessionHolder -> sessionHolder.getSession().lastBookmark() ) - .thenApply( this::createResponse ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncSessionHolder(data.getSessionId()) + .thenApply(sessionHolder -> sessionHolder.getSession().lastBookmark()) + .thenApply(this::createResponse); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxSessionHolder( data.getSessionId() ) - .map( sessionHolder -> sessionHolder.getSession().lastBookmark() ) - .map( this::createResponse ); + public Mono processRx(TestkitState testkitState) { + return testkitState + .getRxSessionHolder(data.getSessionId()) + .map(sessionHolder -> sessionHolder.getSession().lastBookmark()) + .map(this::createResponse); } - private Bookmarks createResponse( Bookmark bookmark ) - { - return Bookmarks.builder().data( Bookmarks.BookmarksBody.builder().bookmarks( bookmark ).build() ).build(); + private Bookmarks createResponse(Bookmark bookmark) { + return Bookmarks.builder() + .data(Bookmarks.BookmarksBody.builder().bookmarks(bookmark).build()) + .build(); } @Setter @Getter - public static class SessionLastBookmarksBody - { + public static class SessionLastBookmarksBody { private String sessionId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionReadTransaction.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionReadTransaction.java index b032547164..297fb68f34 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionReadTransaction.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionReadTransaction.java @@ -18,6 +18,9 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutionException; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -28,123 +31,104 @@ import neo4j.org.testkit.backend.messages.responses.RetryableDone; import neo4j.org.testkit.backend.messages.responses.RetryableTry; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Mono; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; - import org.neo4j.driver.Session; import org.neo4j.driver.TransactionWork; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.AsyncTransactionWork; import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.reactive.RxTransactionWork; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Mono; @Setter @Getter -public class SessionReadTransaction implements TestkitRequest -{ +public class SessionReadTransaction implements TestkitRequest { private SessionReadTransactionBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - SessionHolder sessionHolder = testkitState.getSessionHolder( data.getSessionId() ); + public TestkitResponse process(TestkitState testkitState) { + SessionHolder sessionHolder = testkitState.getSessionHolder(data.getSessionId()); Session session = sessionHolder.getSession(); - session.readTransaction( handle( testkitState, sessionHolder ) ); + session.readTransaction(handle(testkitState, sessionHolder)); return retryableDone(); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncSessionHolder( data.getSessionId() ) - .thenCompose( sessionHolder -> - { - AsyncSession session = sessionHolder.getSession(); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncSessionHolder(data.getSessionId()) + .thenCompose(sessionHolder -> { + AsyncSession session = sessionHolder.getSession(); - AsyncTransactionWork> workWrapper = tx -> - { - String txId = testkitState.addAsyncTransactionHolder( new AsyncTransactionHolder( sessionHolder, tx ) ); - testkitState.getResponseWriter().accept( retryableTry( txId ) ); - CompletableFuture txWorkFuture = new CompletableFuture<>(); - sessionHolder.setTxWorkFuture( txWorkFuture ); - return txWorkFuture; - }; + AsyncTransactionWork> workWrapper = tx -> { + String txId = + testkitState.addAsyncTransactionHolder(new AsyncTransactionHolder(sessionHolder, tx)); + testkitState.getResponseWriter().accept(retryableTry(txId)); + CompletableFuture txWorkFuture = new CompletableFuture<>(); + sessionHolder.setTxWorkFuture(txWorkFuture); + return txWorkFuture; + }; - return session.readTransactionAsync( workWrapper ); - } ) - .thenApply( nothing -> retryableDone() ); + return session.readTransactionAsync(workWrapper); + }) + .thenApply(nothing -> retryableDone()); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxSessionHolder( data.getSessionId() ) - .flatMap( sessionHolder -> - { - RxTransactionWork> workWrapper = tx -> - { - String txId = testkitState.addRxTransactionHolder( new RxTransactionHolder( sessionHolder, tx ) ); - testkitState.getResponseWriter().accept( retryableTry( txId ) ); - CompletableFuture tryResult = new CompletableFuture<>(); - sessionHolder.setTxWorkFuture( tryResult ); - return Mono.fromCompletionStage( tryResult ); - }; + public Mono processRx(TestkitState testkitState) { + return testkitState + .getRxSessionHolder(data.getSessionId()) + .flatMap(sessionHolder -> { + RxTransactionWork> workWrapper = tx -> { + String txId = testkitState.addRxTransactionHolder(new RxTransactionHolder(sessionHolder, tx)); + testkitState.getResponseWriter().accept(retryableTry(txId)); + CompletableFuture tryResult = new CompletableFuture<>(); + sessionHolder.setTxWorkFuture(tryResult); + return Mono.fromCompletionStage(tryResult); + }; - return Mono.fromDirect( sessionHolder.getSession().readTransaction( workWrapper ) ); - } ) - .then( Mono.just( retryableDone() ) ); + return Mono.fromDirect(sessionHolder.getSession().readTransaction(workWrapper)); + }) + .then(Mono.just(retryableDone())); } - private TransactionWork handle( TestkitState testkitState, SessionHolder sessionHolder ) - { - return tx -> - { - String txId = testkitState.addTransactionHolder( new TransactionHolder( sessionHolder, tx ) ); - testkitState.getResponseWriter().accept( retryableTry( txId ) ); + private TransactionWork handle(TestkitState testkitState, SessionHolder sessionHolder) { + return tx -> { + String txId = testkitState.addTransactionHolder(new TransactionHolder(sessionHolder, tx)); + testkitState.getResponseWriter().accept(retryableTry(txId)); CompletableFuture txWorkFuture = new CompletableFuture<>(); - sessionHolder.setTxWorkFuture( txWorkFuture ); + sessionHolder.setTxWorkFuture(txWorkFuture); - try - { + try { return txWorkFuture.get(); - } - catch ( Throwable throwable ) - { + } catch (Throwable throwable) { Throwable workThrowable = throwable; - if ( workThrowable instanceof ExecutionException ) - { + if (workThrowable instanceof ExecutionException) { workThrowable = workThrowable.getCause(); } - if ( workThrowable instanceof Neo4jException ) - { + if (workThrowable instanceof Neo4jException) { throw (Neo4jException) workThrowable; - } - else - { - throw new RuntimeException( "Unexpected exception occurred in transaction work function", workThrowable ); + } else { + throw new RuntimeException( + "Unexpected exception occurred in transaction work function", workThrowable); } } }; } - private RetryableTry retryableTry( String txId ) - { - return RetryableTry.builder().data( RetryableTry.RetryableTryBody.builder().id( txId ).build() ).build(); + private RetryableTry retryableTry(String txId) { + return RetryableTry.builder() + .data(RetryableTry.RetryableTryBody.builder().id(txId).build()) + .build(); } - private RetryableDone retryableDone() - { + private RetryableDone retryableDone() { return RetryableDone.builder().build(); } @Setter @Getter - public static class SessionReadTransactionBody - { + public static class SessionReadTransactionBody { private String sessionId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionRun.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionRun.java index 37436f5d65..325e58f3a6 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionRun.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionRun.java @@ -19,6 +19,11 @@ package neo4j.org.testkit.backend.messages.requests; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.time.Duration; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -29,109 +34,90 @@ import neo4j.org.testkit.backend.messages.requests.deserializer.TestkitCypherParamDeserializer; import neo4j.org.testkit.backend.messages.responses.Result; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.Query; import org.neo4j.driver.Session; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.reactive.RxResult; import org.neo4j.driver.reactive.RxSession; +import reactor.core.publisher.Mono; @Setter @Getter -public class SessionRun implements TestkitRequest -{ +public class SessionRun implements TestkitRequest { private SessionRunBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - SessionHolder sessionHolder = testkitState.getSessionHolder( data.getSessionId() ); + public TestkitResponse process(TestkitState testkitState) { + SessionHolder sessionHolder = testkitState.getSessionHolder(data.getSessionId()); Session session = sessionHolder.getSession(); - Query query = Optional.ofNullable( data.params ) - .map( params -> new Query( data.cypher, data.params ) ) - .orElseGet( () -> new Query( data.cypher ) ); + Query query = Optional.ofNullable(data.params) + .map(params -> new Query(data.cypher, data.params)) + .orElseGet(() -> new Query(data.cypher)); TransactionConfig.Builder transactionConfig = TransactionConfig.builder(); - Optional.ofNullable( data.getTxMeta() ).ifPresent( transactionConfig::withMetadata ); - Optional.ofNullable( data.getTimeout() ).ifPresent( to -> transactionConfig.withTimeout( Duration.ofMillis( to ) ) ); - org.neo4j.driver.Result result = session.run( query, transactionConfig.build() ); - String id = testkitState.addResultHolder( new ResultHolder( sessionHolder, result ) ); + Optional.ofNullable(data.getTxMeta()).ifPresent(transactionConfig::withMetadata); + Optional.ofNullable(data.getTimeout()).ifPresent(to -> transactionConfig.withTimeout(Duration.ofMillis(to))); + org.neo4j.driver.Result result = session.run(query, transactionConfig.build()); + String id = testkitState.addResultHolder(new ResultHolder(sessionHolder, result)); - return createResponse( id, result.keys() ); + return createResponse(id, result.keys()); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncSessionHolder( data.getSessionId() ) - .thenCompose( sessionHolder -> - { - AsyncSession session = sessionHolder.getSession(); - Query query = Optional.ofNullable( data.params ) - .map( params -> new Query( data.cypher, data.params ) ) - .orElseGet( () -> new Query( data.cypher ) ); - TransactionConfig.Builder transactionConfig = TransactionConfig.builder(); - Optional.ofNullable( data.getTxMeta() ).ifPresent( transactionConfig::withMetadata ); - Optional.ofNullable( data.getTimeout() ) - .ifPresent( to -> transactionConfig.withTimeout( Duration.ofMillis( to ) ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState.getAsyncSessionHolder(data.getSessionId()).thenCompose(sessionHolder -> { + AsyncSession session = sessionHolder.getSession(); + Query query = Optional.ofNullable(data.params) + .map(params -> new Query(data.cypher, data.params)) + .orElseGet(() -> new Query(data.cypher)); + TransactionConfig.Builder transactionConfig = TransactionConfig.builder(); + Optional.ofNullable(data.getTxMeta()).ifPresent(transactionConfig::withMetadata); + Optional.ofNullable(data.getTimeout()) + .ifPresent(to -> transactionConfig.withTimeout(Duration.ofMillis(to))); - return session.runAsync( query, transactionConfig.build() ) - .thenApply( resultCursor -> - { - String id = testkitState.addAsyncResultHolder( - new ResultCursorHolder( sessionHolder, resultCursor ) ); - return createResponse( id, resultCursor.keys() ); - } ); - } ); + return session.runAsync(query, transactionConfig.build()).thenApply(resultCursor -> { + String id = testkitState.addAsyncResultHolder(new ResultCursorHolder(sessionHolder, resultCursor)); + return createResponse(id, resultCursor.keys()); + }); + }); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxSessionHolder( data.getSessionId() ) - .flatMap( sessionHolder -> - { - RxSession session = sessionHolder.getSession(); - Query query = Optional.ofNullable( data.params ) - .map( params -> new Query( data.cypher, data.params ) ) - .orElseGet( () -> new Query( data.cypher ) ); - TransactionConfig.Builder transactionConfig = TransactionConfig.builder(); - Optional.ofNullable( data.getTxMeta() ).ifPresent( transactionConfig::withMetadata ); - Optional.ofNullable( data.getTimeout() ).ifPresent( to -> transactionConfig.withTimeout( Duration.ofMillis( to ) ) ); + public Mono processRx(TestkitState testkitState) { + return testkitState.getRxSessionHolder(data.getSessionId()).flatMap(sessionHolder -> { + RxSession session = sessionHolder.getSession(); + Query query = Optional.ofNullable(data.params) + .map(params -> new Query(data.cypher, data.params)) + .orElseGet(() -> new Query(data.cypher)); + TransactionConfig.Builder transactionConfig = TransactionConfig.builder(); + Optional.ofNullable(data.getTxMeta()).ifPresent(transactionConfig::withMetadata); + Optional.ofNullable(data.getTimeout()) + .ifPresent(to -> transactionConfig.withTimeout(Duration.ofMillis(to))); - RxResult result = session.run( query, transactionConfig.build() ); - String id = testkitState.addRxResultHolder( new RxResultHolder( sessionHolder, result ) ); + RxResult result = session.run(query, transactionConfig.build()); + String id = testkitState.addRxResultHolder(new RxResultHolder(sessionHolder, result)); - // The keys() method causes RUN message exchange. - // However, it does not currently report errors. - return Mono.fromDirect( result.keys() ) - .map( keys -> createResponse( id, keys ) ); - } ); + // The keys() method causes RUN message exchange. + // However, it does not currently report errors. + return Mono.fromDirect(result.keys()).map(keys -> createResponse(id, keys)); + }); } - private Result createResponse( String resultId, List keys ) - { - return Result.builder().data( Result.ResultBody.builder().id( resultId ).keys( keys ).build() ).build(); + private Result createResponse(String resultId, List keys) { + return Result.builder() + .data(Result.ResultBody.builder().id(resultId).keys(keys).build()) + .build(); } @Setter @Getter - public static class SessionRunBody - { - @JsonDeserialize( using = TestkitCypherParamDeserializer.class ) - private Map params; + public static class SessionRunBody { + @JsonDeserialize(using = TestkitCypherParamDeserializer.class) + private Map params; private String sessionId; private String cypher; - private Map txMeta; + private Map txMeta; private Integer timeout; - } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionWriteTransaction.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionWriteTransaction.java index 65caff854e..326d8cbeff 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionWriteTransaction.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/SessionWriteTransaction.java @@ -18,6 +18,10 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.ExecutionException; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -28,128 +32,106 @@ import neo4j.org.testkit.backend.messages.responses.RetryableDone; import neo4j.org.testkit.backend.messages.responses.RetryableTry; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Mono; - -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.ExecutionException; - import org.neo4j.driver.Session; import org.neo4j.driver.TransactionWork; import org.neo4j.driver.async.AsyncSession; import org.neo4j.driver.async.AsyncTransactionWork; import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.reactive.RxTransactionWork; +import org.reactivestreams.Publisher; +import reactor.core.publisher.Mono; @Setter @Getter -public class SessionWriteTransaction implements TestkitRequest -{ +public class SessionWriteTransaction implements TestkitRequest { private SessionWriteTransactionBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - SessionHolder sessionHolder = testkitState.getSessionHolder( data.getSessionId() ); + public TestkitResponse process(TestkitState testkitState) { + SessionHolder sessionHolder = testkitState.getSessionHolder(data.getSessionId()); Session session = sessionHolder.getSession(); - session.writeTransaction( handle( testkitState, sessionHolder ) ); + session.writeTransaction(handle(testkitState, sessionHolder)); return retryableDone(); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncSessionHolder( data.getSessionId() ) - .thenCompose( sessionHolder -> - { - AsyncSession session = sessionHolder.getSession(); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncSessionHolder(data.getSessionId()) + .thenCompose(sessionHolder -> { + AsyncSession session = sessionHolder.getSession(); - AsyncTransactionWork> workWrapper = - tx -> - { - String txId = - testkitState.addAsyncTransactionHolder( new AsyncTransactionHolder( sessionHolder, tx ) ); - testkitState.getResponseWriter().accept( retryableTry( txId ) ); - CompletableFuture tryResult = new CompletableFuture<>(); - sessionHolder.setTxWorkFuture( tryResult ); - return tryResult; - }; + AsyncTransactionWork> workWrapper = tx -> { + String txId = + testkitState.addAsyncTransactionHolder(new AsyncTransactionHolder(sessionHolder, tx)); + testkitState.getResponseWriter().accept(retryableTry(txId)); + CompletableFuture tryResult = new CompletableFuture<>(); + sessionHolder.setTxWorkFuture(tryResult); + return tryResult; + }; - return session.writeTransactionAsync( workWrapper ); - } ) - .thenApply( nothing -> retryableDone() ); + return session.writeTransactionAsync(workWrapper); + }) + .thenApply(nothing -> retryableDone()); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxSessionHolder( data.getSessionId() ) - .flatMap( sessionHolder -> - { - RxTransactionWork> workWrapper = tx -> - { - String txId = testkitState.addRxTransactionHolder( new RxTransactionHolder( sessionHolder, tx ) ); - testkitState.getResponseWriter().accept( retryableTry( txId ) ); - CompletableFuture tryResult = new CompletableFuture<>(); - sessionHolder.setTxWorkFuture( tryResult ); - return Mono.fromCompletionStage( tryResult ); - }; + public Mono processRx(TestkitState testkitState) { + return testkitState + .getRxSessionHolder(data.getSessionId()) + .flatMap(sessionHolder -> { + RxTransactionWork> workWrapper = tx -> { + String txId = testkitState.addRxTransactionHolder(new RxTransactionHolder(sessionHolder, tx)); + testkitState.getResponseWriter().accept(retryableTry(txId)); + CompletableFuture tryResult = new CompletableFuture<>(); + sessionHolder.setTxWorkFuture(tryResult); + return Mono.fromCompletionStage(tryResult); + }; - return Mono.fromDirect( sessionHolder.getSession().writeTransaction( workWrapper ) ); - } ) - .then( Mono.just( retryableDone() ) ); + return Mono.fromDirect(sessionHolder.getSession().writeTransaction(workWrapper)); + }) + .then(Mono.just(retryableDone())); } - private TransactionWork handle( TestkitState testkitState, SessionHolder sessionHolder ) - { - return tx -> - { - String txId = testkitState.addTransactionHolder( new TransactionHolder( sessionHolder, tx ) ); - testkitState.getResponseWriter().accept( retryableTry( txId ) ); + private TransactionWork handle(TestkitState testkitState, SessionHolder sessionHolder) { + return tx -> { + String txId = testkitState.addTransactionHolder(new TransactionHolder(sessionHolder, tx)); + testkitState.getResponseWriter().accept(retryableTry(txId)); CompletableFuture txWorkFuture = new CompletableFuture<>(); - sessionHolder.setTxWorkFuture( txWorkFuture ); + sessionHolder.setTxWorkFuture(txWorkFuture); - try - { + try { return txWorkFuture.get(); - } - catch ( Throwable throwable ) - { + } catch (Throwable throwable) { Throwable workThrowable = throwable; - if ( workThrowable instanceof ExecutionException ) - { + if (workThrowable instanceof ExecutionException) { workThrowable = workThrowable.getCause(); } - if ( workThrowable instanceof Neo4jException ) - { + if (workThrowable instanceof Neo4jException) { throw (Neo4jException) workThrowable; - } - else - { - throw new RuntimeException( "Unexpected exception occurred in transaction work function", workThrowable ); + } else { + throw new RuntimeException( + "Unexpected exception occurred in transaction work function", workThrowable); } } }; } - private RetryableTry retryableTry( String txId ) - { - return RetryableTry.builder().data( RetryableTry.RetryableTryBody.builder().id( txId ).build() ).build(); + private RetryableTry retryableTry(String txId) { + return RetryableTry.builder() + .data(RetryableTry.RetryableTryBody.builder().id(txId).build()) + .build(); } - private RetryableDone retryableDone() - { + private RetryableDone retryableDone() { return RetryableDone.builder().build(); } @Setter @Getter - public static class SessionWriteTransactionBody - { + public static class SessionWriteTransactionBody { private String sessionId; - private Map txMeta; + private Map txMeta; private String timeout; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/StartTest.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/StartTest.java index e4823ec35d..ced093fee8 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/StartTest.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/StartTest.java @@ -18,6 +18,10 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -26,115 +30,132 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class StartTest implements TestkitRequest -{ - private static final Map COMMON_SKIP_PATTERN_TO_REASON = new HashMap<>(); - private static final Map ASYNC_SKIP_PATTERN_TO_REASON = new HashMap<>(); - private static final Map REACTIVE_SKIP_PATTERN_TO_REASON = new HashMap<>(); +public class StartTest implements TestkitRequest { + private static final Map COMMON_SKIP_PATTERN_TO_REASON = new HashMap<>(); + private static final Map ASYNC_SKIP_PATTERN_TO_REASON = new HashMap<>(); + private static final Map REACTIVE_SKIP_PATTERN_TO_REASON = new HashMap<>(); - static - { - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_no_notifications$", "An empty list is returned when there are no notifications" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_no_notification_info$", "An empty list is returned when there are no notifications" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_notifications_without_position$", "Null value is provided when position is absent" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_multiple_notifications$", "Null value is provided when position is absent" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_partial_summary_not_contains_system_updates$", "Contains updates because value is over zero" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_partial_summary_not_contains_updates$", "Contains updates because value is over zero" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_profile$", "Missing stats are reported with 0 value" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_server_info$", "Address includes domain name" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_partial_summary_contains_system_updates$", "Does not contain updates because value is zero" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_partial_summary_contains_updates$", "Does not contain updates because value is zero" ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_supports_multi_db$", "Database is None" ); - String skipMessage = "This test expects hostname verification to be turned off when all certificates are trusted"; - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestTrustAllCertsConfig\\.test_trusted_ca_wrong_hostname$", skipMessage ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestTrustAllCertsConfig\\.test_untrusted_ca_wrong_hostname$", skipMessage ); + static { + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_no_notifications$", "An empty list is returned when there are no notifications"); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_no_notification_info$", "An empty list is returned when there are no notifications"); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_notifications_without_position$", "Null value is provided when position is absent"); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_multiple_notifications$", "Null value is provided when position is absent"); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_partial_summary_not_contains_system_updates$", + "Contains updates because value is over zero"); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_partial_summary_not_contains_updates$", "Contains updates because value is over zero"); + COMMON_SKIP_PATTERN_TO_REASON.put("^.*\\.test_profile$", "Missing stats are reported with 0 value"); + COMMON_SKIP_PATTERN_TO_REASON.put("^.*\\.test_server_info$", "Address includes domain name"); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_partial_summary_contains_system_updates$", + "Does not contain updates because value is zero"); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_partial_summary_contains_updates$", "Does not contain updates because value is zero"); + COMMON_SKIP_PATTERN_TO_REASON.put("^.*\\.test_supports_multi_db$", "Database is None"); + String skipMessage = + "This test expects hostname verification to be turned off when all certificates are trusted"; + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestTrustAllCertsConfig\\.test_trusted_ca_wrong_hostname$", skipMessage); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestTrustAllCertsConfig\\.test_untrusted_ca_wrong_hostname$", skipMessage); skipMessage = "This test needs updating to implement expected behaviour"; - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestAuthenticationSchemes\\.test_custom_scheme_empty$", skipMessage ); + COMMON_SKIP_PATTERN_TO_REASON.put("^.*\\.TestAuthenticationSchemes\\.test_custom_scheme_empty$", skipMessage); skipMessage = "Driver does not implement optimization for qid in explicit transaction"; - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestOptimizations\\.test_uses_implicit_default_arguments$", skipMessage ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestOptimizations\\.test_uses_implicit_default_arguments_multi_query$", skipMessage ); - COMMON_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestOptimizations\\.test_uses_implicit_default_arguments_multi_query_nested$", skipMessage ); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestOptimizations\\.test_uses_implicit_default_arguments$", skipMessage); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestOptimizations\\.test_uses_implicit_default_arguments_multi_query$", skipMessage); + COMMON_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestOptimizations\\.test_uses_implicit_default_arguments_multi_query_nested$", skipMessage); - ASYNC_SKIP_PATTERN_TO_REASON.putAll( COMMON_SKIP_PATTERN_TO_REASON ); - ASYNC_SKIP_PATTERN_TO_REASON.put( "^.*\\.test_should_reject_server_using_verify_connectivity_bolt_3x0$", "Does not error as expected" ); + ASYNC_SKIP_PATTERN_TO_REASON.putAll(COMMON_SKIP_PATTERN_TO_REASON); + ASYNC_SKIP_PATTERN_TO_REASON.put( + "^.*\\.test_should_reject_server_using_verify_connectivity_bolt_3x0$", "Does not error as expected"); - REACTIVE_SKIP_PATTERN_TO_REASON.putAll( COMMON_SKIP_PATTERN_TO_REASON ); + REACTIVE_SKIP_PATTERN_TO_REASON.putAll(COMMON_SKIP_PATTERN_TO_REASON); // Current limitations (require further investigation or bug fixing) skipMessage = "Does not report RUN FAILURE"; - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.Routing[^.]+\\.test_should_write_successfully_on_leader_switch_using_tx_function$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestDisconnects\\.test_disconnect_after_hello$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestDisconnects\\.test_disconnect_session_on_run$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestDisconnects\\.test_disconnect_on_tx_run$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestSessionRun\\.test_raises_error_on_session_run$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestTxRun\\.test_raises_error_on_tx(_func)?_run", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestTxRun\\.test_failed_tx_run_allows(_skipping)?_rollback", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestAuthorizationV\\dx\\d\\.test_should_fail_with_auth_expired_on_run_using_tx_run$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestAuthorizationV\\dx\\d\\.test_should_fail_with_token_expired_on_run_using_tx_run$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestDirectConnectionRecvTimeout\\.test_timeout$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestDirectConnectionRecvTimeout\\.test_timeout_unmanaged_tx$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestDirectConnectionRecvTimeout\\.test_timeout_unmanaged_tx_should_fail_subsequent_usage_after_timeout$", - skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestDirectConnectionRecvTimeout\\.test_timeout_managed_tx_retry$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestRoutingConnectionRecvTimeout\\.test_timeout$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestRoutingConnectionRecvTimeout\\.test_timeout_unmanaged_tx$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestRoutingConnectionRecvTimeout\\.test_timeout_unmanaged_tx_should_fail_subsequent_usage_after_timeout$", - skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestRoutingConnectionRecvTimeout\\.test_timeout_managed_tx_retry$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestTxRun\\.test_broken_transaction_should_not_break_session$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestTxRun\\.test_does_not_update_last_bookmark_on_failure$", skipMessage ); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.Routing[^.]+\\.test_should_write_successfully_on_leader_switch_using_tx_function$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestDisconnects\\.test_disconnect_after_hello$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestDisconnects\\.test_disconnect_session_on_run$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestDisconnects\\.test_disconnect_on_tx_run$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestSessionRun\\.test_raises_error_on_session_run$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestTxRun\\.test_raises_error_on_tx(_func)?_run", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestTxRun\\.test_failed_tx_run_allows(_skipping)?_rollback", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestAuthorizationV\\dx\\d\\.test_should_fail_with_auth_expired_on_run_using_tx_run$", + skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestAuthorizationV\\dx\\d\\.test_should_fail_with_token_expired_on_run_using_tx_run$", + skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestDirectConnectionRecvTimeout\\.test_timeout$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestDirectConnectionRecvTimeout\\.test_timeout_unmanaged_tx$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestDirectConnectionRecvTimeout\\.test_timeout_unmanaged_tx_should_fail_subsequent_usage_after_timeout$", + skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestDirectConnectionRecvTimeout\\.test_timeout_managed_tx_retry$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestRoutingConnectionRecvTimeout\\.test_timeout$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestRoutingConnectionRecvTimeout\\.test_timeout_unmanaged_tx$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestRoutingConnectionRecvTimeout\\.test_timeout_unmanaged_tx_should_fail_subsequent_usage_after_timeout$", + skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestRoutingConnectionRecvTimeout\\.test_timeout_managed_tx_retry$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestTxRun\\.test_broken_transaction_should_not_break_session$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put( + "^.*\\.TestTxRun\\.test_does_not_update_last_bookmark_on_failure$", skipMessage); skipMessage = "Does not support multiple concurrent result streams on session level"; - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestSessionRun\\.test_iteration_nested$", skipMessage ); - REACTIVE_SKIP_PATTERN_TO_REASON.put( "^.*\\.TestSessionRun\\.test_partial_iteration$", skipMessage ); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestSessionRun\\.test_iteration_nested$", skipMessage); + REACTIVE_SKIP_PATTERN_TO_REASON.put("^.*\\.TestSessionRun\\.test_partial_iteration$", skipMessage); } private StartTestBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - return createResponse( COMMON_SKIP_PATTERN_TO_REASON ); + public TestkitResponse process(TestkitState testkitState) { + return createResponse(COMMON_SKIP_PATTERN_TO_REASON); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - TestkitResponse testkitResponse = createResponse( ASYNC_SKIP_PATTERN_TO_REASON ); - return CompletableFuture.completedFuture( testkitResponse ); + public CompletionStage processAsync(TestkitState testkitState) { + TestkitResponse testkitResponse = createResponse(ASYNC_SKIP_PATTERN_TO_REASON); + return CompletableFuture.completedFuture(testkitResponse); } @Override - public Mono processRx( TestkitState testkitState ) - { - TestkitResponse testkitResponse = createResponse( REACTIVE_SKIP_PATTERN_TO_REASON ); - return Mono.fromCompletionStage( CompletableFuture.completedFuture( testkitResponse ) ); + public Mono processRx(TestkitState testkitState) { + TestkitResponse testkitResponse = createResponse(REACTIVE_SKIP_PATTERN_TO_REASON); + return Mono.fromCompletionStage(CompletableFuture.completedFuture(testkitResponse)); } - private TestkitResponse createResponse( Map skipPatternToReason ) - { - return skipPatternToReason - .entrySet() - .stream() - .filter( entry -> data.getTestName().matches( entry.getKey() ) ) + private TestkitResponse createResponse(Map skipPatternToReason) { + return skipPatternToReason.entrySet().stream() + .filter(entry -> data.getTestName().matches(entry.getKey())) .findFirst() - .map( entry -> (TestkitResponse) SkipTest.builder() - .data( SkipTest.SkipTestBody.builder() - .reason( entry.getValue() ) - .build() ) - .build() ) - .orElseGet( () -> RunTest.builder().build() ); + .map(entry -> (TestkitResponse) SkipTest.builder() + .data(SkipTest.SkipTestBody.builder() + .reason(entry.getValue()) + .build()) + .build()) + .orElseGet(() -> RunTest.builder().build()); } @Setter @Getter - public static class StartTestBody - { + public static class StartTestBody { private String testName; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitCallbackResult.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitCallbackResult.java index 0a9d0ca0ba..de175180d2 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitCallbackResult.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitCallbackResult.java @@ -18,39 +18,34 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import neo4j.org.testkit.backend.TestkitState; import neo4j.org.testkit.backend.messages.responses.TestkitCallback; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - /** * This request is sent by Testkit in response to previously sent {@link TestkitCallback}. */ -public interface TestkitCallbackResult extends TestkitRequest -{ +public interface TestkitCallbackResult extends TestkitRequest { String getCallbackId(); @Override - default TestkitResponse process( TestkitState testkitState ) - { - testkitState.getCallbackIdToFuture().get( getCallbackId() ).complete( this ); + default TestkitResponse process(TestkitState testkitState) { + testkitState.getCallbackIdToFuture().get(getCallbackId()).complete(this); return null; } @Override - default CompletionStage processAsync( TestkitState testkitState ) - { - testkitState.getCallbackIdToFuture().get( getCallbackId() ).complete( this ); - return CompletableFuture.completedFuture( null ); + default CompletionStage processAsync(TestkitState testkitState) { + testkitState.getCallbackIdToFuture().get(getCallbackId()).complete(this); + return CompletableFuture.completedFuture(null); } @Override - default Mono processRx( TestkitState testkitState ) - { - testkitState.getCallbackIdToFuture().get( getCallbackId() ).complete( this ); + default Mono processRx(TestkitState testkitState) { + testkitState.getCallbackIdToFuture().get(getCallbackId()).complete(this); return Mono.empty(); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitRequest.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitRequest.java index a2e09b606c..6eb3096c47 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitRequest.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TestkitRequest.java @@ -20,34 +20,32 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import java.util.concurrent.CompletionStage; import neo4j.org.testkit.backend.TestkitState; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - -@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "name" ) -@JsonSubTypes( { - @JsonSubTypes.Type( NewDriver.class ), @JsonSubTypes.Type( NewSession.class ), - @JsonSubTypes.Type( SessionRun.class ), @JsonSubTypes.Type( ResultNext.class ), - @JsonSubTypes.Type( ResultConsume.class ), @JsonSubTypes.Type( VerifyConnectivity.class ), - @JsonSubTypes.Type( SessionClose.class ), @JsonSubTypes.Type( DriverClose.class ), - @JsonSubTypes.Type( RetryableNegative.class ), @JsonSubTypes.Type( SessionReadTransaction.class ), - @JsonSubTypes.Type( TransactionRun.class ), @JsonSubTypes.Type( RetryablePositive.class ), - @JsonSubTypes.Type( SessionBeginTransaction.class ), @JsonSubTypes.Type( TransactionCommit.class ), - @JsonSubTypes.Type( SessionLastBookmarks.class ), @JsonSubTypes.Type( SessionWriteTransaction.class ), - @JsonSubTypes.Type( ResolverResolutionCompleted.class ), @JsonSubTypes.Type( CheckMultiDBSupport.class ), - @JsonSubTypes.Type( DomainNameResolutionCompleted.class ), @JsonSubTypes.Type( StartTest.class ), - @JsonSubTypes.Type( TransactionRollback.class ), @JsonSubTypes.Type( GetFeatures.class ), - @JsonSubTypes.Type( GetRoutingTable.class ), @JsonSubTypes.Type( TransactionClose.class ), - @JsonSubTypes.Type( ResultList.class ), @JsonSubTypes.Type( GetConnectionPoolMetrics.class ), - @JsonSubTypes.Type( ResultPeek.class ), @JsonSubTypes.Type( CheckDriverIsEncrypted.class ) -} ) -public interface TestkitRequest -{ - TestkitResponse process( TestkitState testkitState ); +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "name") +@JsonSubTypes({ + @JsonSubTypes.Type(NewDriver.class), @JsonSubTypes.Type(NewSession.class), + @JsonSubTypes.Type(SessionRun.class), @JsonSubTypes.Type(ResultNext.class), + @JsonSubTypes.Type(ResultConsume.class), @JsonSubTypes.Type(VerifyConnectivity.class), + @JsonSubTypes.Type(SessionClose.class), @JsonSubTypes.Type(DriverClose.class), + @JsonSubTypes.Type(RetryableNegative.class), @JsonSubTypes.Type(SessionReadTransaction.class), + @JsonSubTypes.Type(TransactionRun.class), @JsonSubTypes.Type(RetryablePositive.class), + @JsonSubTypes.Type(SessionBeginTransaction.class), @JsonSubTypes.Type(TransactionCommit.class), + @JsonSubTypes.Type(SessionLastBookmarks.class), @JsonSubTypes.Type(SessionWriteTransaction.class), + @JsonSubTypes.Type(ResolverResolutionCompleted.class), @JsonSubTypes.Type(CheckMultiDBSupport.class), + @JsonSubTypes.Type(DomainNameResolutionCompleted.class), @JsonSubTypes.Type(StartTest.class), + @JsonSubTypes.Type(TransactionRollback.class), @JsonSubTypes.Type(GetFeatures.class), + @JsonSubTypes.Type(GetRoutingTable.class), @JsonSubTypes.Type(TransactionClose.class), + @JsonSubTypes.Type(ResultList.class), @JsonSubTypes.Type(GetConnectionPoolMetrics.class), + @JsonSubTypes.Type(ResultPeek.class), @JsonSubTypes.Type(CheckDriverIsEncrypted.class) +}) +public interface TestkitRequest { + TestkitResponse process(TestkitState testkitState); - CompletionStage processAsync( TestkitState testkitState ); + CompletionStage processAsync(TestkitState testkitState); - Mono processRx( TestkitState testkitState ); + Mono processRx(TestkitState testkitState); } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionClose.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionClose.java index 90d12e3213..2d3674a338 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionClose.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionClose.java @@ -18,58 +18,54 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; import neo4j.org.testkit.backend.holder.AbstractTransactionHolder; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import neo4j.org.testkit.backend.messages.responses.Transaction; -import reactor.core.publisher.Mono; - -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.async.AsyncTransaction; +import reactor.core.publisher.Mono; @Setter @Getter -public class TransactionClose implements TestkitRequest -{ +public class TransactionClose implements TestkitRequest { private TransactionCloseBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - testkitState.getTransactionHolder( data.getTxId() ).getTransaction().close(); - return createResponse( data.getTxId() ); + public TestkitResponse process(TestkitState testkitState) { + testkitState.getTransactionHolder(data.getTxId()).getTransaction().close(); + return createResponse(data.getTxId()); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncTransactionHolder( data.getTxId() ) - .thenApply( AbstractTransactionHolder::getTransaction ) - .thenCompose( AsyncTransaction::closeAsync ) - .thenApply( ignored -> createResponse( data.getTxId() ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncTransactionHolder(data.getTxId()) + .thenApply(AbstractTransactionHolder::getTransaction) + .thenCompose(AsyncTransaction::closeAsync) + .thenApply(ignored -> createResponse(data.getTxId())); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxTransactionHolder( data.getTxId() ) - .map( AbstractTransactionHolder::getTransaction ) - .flatMap( tx -> Mono.fromDirect( tx.close() ) ) - .then( Mono.just( createResponse( data.getTxId() ) ) ); + public Mono processRx(TestkitState testkitState) { + return testkitState + .getRxTransactionHolder(data.getTxId()) + .map(AbstractTransactionHolder::getTransaction) + .flatMap(tx -> Mono.fromDirect(tx.close())) + .then(Mono.just(createResponse(data.getTxId()))); } - private Transaction createResponse( String txId ) - { - return Transaction.builder().data( Transaction.TransactionBody.builder().id( txId ).build() ).build(); + private Transaction createResponse(String txId) { + return Transaction.builder() + .data(Transaction.TransactionBody.builder().id(txId).build()) + .build(); } @Setter @Getter - private static class TransactionCloseBody - { + private static class TransactionCloseBody { private String txId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionCommit.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionCommit.java index 4af0187078..c6cf87a8a1 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionCommit.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionCommit.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,45 +26,42 @@ import neo4j.org.testkit.backend.messages.responses.Transaction; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Getter @Setter -public class TransactionCommit implements TestkitRequest -{ +public class TransactionCommit implements TestkitRequest { private TransactionCommitBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - testkitState.getTransactionHolder( data.getTxId() ).getTransaction().commit(); - return createResponse( data.getTxId() ); + public TestkitResponse process(TestkitState testkitState) { + testkitState.getTransactionHolder(data.getTxId()).getTransaction().commit(); + return createResponse(data.getTxId()); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncTransactionHolder( data.getTxId() ).thenCompose( tx -> tx.getTransaction().commitAsync() ) - .thenApply( ignored -> createResponse( data.getTxId() ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncTransactionHolder(data.getTxId()) + .thenCompose(tx -> tx.getTransaction().commitAsync()) + .thenApply(ignored -> createResponse(data.getTxId())); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxTransactionHolder( data.getTxId() ) - .flatMap( tx -> Mono.fromDirect( tx.getTransaction().commit() ) ) - .then( Mono.just( createResponse( data.getTxId() ) ) ); + public Mono processRx(TestkitState testkitState) { + return testkitState + .getRxTransactionHolder(data.getTxId()) + .flatMap(tx -> Mono.fromDirect(tx.getTransaction().commit())) + .then(Mono.just(createResponse(data.getTxId()))); } - private Transaction createResponse( String txId ) - { - return Transaction.builder().data( Transaction.TransactionBody.builder().id( txId ).build() ).build(); + private Transaction createResponse(String txId) { + return Transaction.builder() + .data(Transaction.TransactionBody.builder().id(txId).build()) + .build(); } @Getter @Setter - public static class TransactionCommitBody - { + public static class TransactionCommitBody { private String txId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionRollback.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionRollback.java index f31b44cf22..10e21cac48 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionRollback.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionRollback.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,45 +26,42 @@ import neo4j.org.testkit.backend.messages.responses.Transaction; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Getter @Setter -public class TransactionRollback implements TestkitRequest -{ +public class TransactionRollback implements TestkitRequest { private TransactionRollbackBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - testkitState.getTransactionHolder( data.getTxId() ).getTransaction().rollback(); - return createResponse( data.getTxId() ); + public TestkitResponse process(TestkitState testkitState) { + testkitState.getTransactionHolder(data.getTxId()).getTransaction().rollback(); + return createResponse(data.getTxId()); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncTransactionHolder( data.getTxId() ).thenCompose( tx -> tx.getTransaction().rollbackAsync() ) - .thenApply( ignored -> createResponse( data.getTxId() ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState + .getAsyncTransactionHolder(data.getTxId()) + .thenCompose(tx -> tx.getTransaction().rollbackAsync()) + .thenApply(ignored -> createResponse(data.getTxId())); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxTransactionHolder( data.getTxId() ) - .flatMap( tx -> Mono.fromDirect( tx.getTransaction().rollback() ) ) - .then( Mono.just( createResponse( data.getTxId() ) ) ); + public Mono processRx(TestkitState testkitState) { + return testkitState + .getRxTransactionHolder(data.getTxId()) + .flatMap(tx -> Mono.fromDirect(tx.getTransaction().rollback())) + .then(Mono.just(createResponse(data.getTxId()))); } - private Transaction createResponse( String txId ) - { - return Transaction.builder().data( Transaction.TransactionBody.builder().id( txId ).build() ).build(); + private Transaction createResponse(String txId) { + return Transaction.builder() + .data(Transaction.TransactionBody.builder().id(txId).build()) + .build(); } @Getter @Setter - public static class TransactionRollbackBody - { + public static class TransactionRollbackBody { private String txId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionRun.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionRun.java index 4c3fe24990..6658313155 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionRun.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/TransactionRun.java @@ -19,6 +19,10 @@ package neo4j.org.testkit.backend.messages.requests; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -29,75 +33,62 @@ import neo4j.org.testkit.backend.messages.requests.deserializer.TestkitCypherParamDeserializer; import neo4j.org.testkit.backend.messages.responses.Result; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; -import reactor.core.publisher.Mono; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletionStage; - import org.neo4j.driver.reactive.RxResult; +import reactor.core.publisher.Mono; @Setter @Getter -public class TransactionRun implements TestkitRequest -{ +public class TransactionRun implements TestkitRequest { protected TransactionRunBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { - TransactionHolder transactionHolder = testkitState.getTransactionHolder( data.getTxId() ); - org.neo4j.driver.Result result = transactionHolder.getTransaction() - .run( data.getCypher(), data.getParams() != null ? data.getParams() : Collections.emptyMap() ); - String resultId = testkitState.addResultHolder( new ResultHolder( transactionHolder, result ) ); - return createResponse( resultId, result.keys() ); + public TestkitResponse process(TestkitState testkitState) { + TransactionHolder transactionHolder = testkitState.getTransactionHolder(data.getTxId()); + org.neo4j.driver.Result result = transactionHolder + .getTransaction() + .run(data.getCypher(), data.getParams() != null ? data.getParams() : Collections.emptyMap()); + String resultId = testkitState.addResultHolder(new ResultHolder(transactionHolder, result)); + return createResponse(resultId, result.keys()); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { - return testkitState.getAsyncTransactionHolder( data.getTxId() ) - .thenCompose( transactionHolder -> transactionHolder.getTransaction() - .runAsync( data.getCypher(), - data.getParams() != null ? data.getParams() : Collections.emptyMap() ) - .thenApply( resultCursor -> - { - String resultId = testkitState.addAsyncResultHolder( - new ResultCursorHolder( transactionHolder, - resultCursor ) ); - return createResponse( resultId, resultCursor.keys() ); - } ) ); + public CompletionStage processAsync(TestkitState testkitState) { + return testkitState.getAsyncTransactionHolder(data.getTxId()).thenCompose(transactionHolder -> transactionHolder + .getTransaction() + .runAsync(data.getCypher(), data.getParams() != null ? data.getParams() : Collections.emptyMap()) + .thenApply(resultCursor -> { + String resultId = + testkitState.addAsyncResultHolder(new ResultCursorHolder(transactionHolder, resultCursor)); + return createResponse(resultId, resultCursor.keys()); + })); } @Override - public Mono processRx( TestkitState testkitState ) - { - return testkitState.getRxTransactionHolder( data.getTxId() ) - .flatMap( transactionHolder -> - { - RxResult result = transactionHolder.getTransaction() - .run( data.getCypher(), - data.getParams() != null ? data.getParams() : Collections.emptyMap() ); - String resultId = testkitState.addRxResultHolder( new RxResultHolder( transactionHolder, result ) ); - // The keys() method causes RUN message exchange. - // However, it does not currently report errors. - return Mono.fromDirect( result.keys() ).map( keys -> createResponse( resultId, keys ) ); - } ); + public Mono processRx(TestkitState testkitState) { + return testkitState.getRxTransactionHolder(data.getTxId()).flatMap(transactionHolder -> { + RxResult result = transactionHolder + .getTransaction() + .run(data.getCypher(), data.getParams() != null ? data.getParams() : Collections.emptyMap()); + String resultId = testkitState.addRxResultHolder(new RxResultHolder(transactionHolder, result)); + // The keys() method causes RUN message exchange. + // However, it does not currently report errors. + return Mono.fromDirect(result.keys()).map(keys -> createResponse(resultId, keys)); + }); } - protected Result createResponse( String resultId, List keys ) - { - return Result.builder().data( Result.ResultBody.builder().id( resultId ).keys( keys ).build() ).build(); + protected Result createResponse(String resultId, List keys) { + return Result.builder() + .data(Result.ResultBody.builder().id(resultId).keys(keys).build()) + .build(); } @Setter @Getter - public static class TransactionRunBody - { + public static class TransactionRunBody { private String txId; private String cypher; - @JsonDeserialize( using = TestkitCypherParamDeserializer.class ) - private Map params; + + @JsonDeserialize(using = TestkitCypherParamDeserializer.class) + private Map params; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/VerifyConnectivity.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/VerifyConnectivity.java index 6b2c0a7899..5258a4794b 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/VerifyConnectivity.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/VerifyConnectivity.java @@ -18,6 +18,7 @@ */ package neo4j.org.testkit.backend.messages.requests; +import java.util.concurrent.CompletionStage; import lombok.Getter; import lombok.Setter; import neo4j.org.testkit.backend.TestkitState; @@ -25,47 +26,40 @@ import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import reactor.core.publisher.Mono; -import java.util.concurrent.CompletionStage; - @Setter @Getter -public class VerifyConnectivity implements TestkitRequest -{ +public class VerifyConnectivity implements TestkitRequest { private VerifyConnectivityBody data; @Override - public TestkitResponse process( TestkitState testkitState ) - { + public TestkitResponse process(TestkitState testkitState) { String id = data.getDriverId(); - testkitState.getDriverHolder( id ).getDriver().verifyConnectivity(); - return createResponse( id ); + testkitState.getDriverHolder(id).getDriver().verifyConnectivity(); + return createResponse(id); } @Override - public CompletionStage processAsync( TestkitState testkitState ) - { + public CompletionStage processAsync(TestkitState testkitState) { String id = data.getDriverId(); - return testkitState.getDriverHolder( id ) - .getDriver() - .verifyConnectivityAsync() - .thenApply( ignored -> createResponse( id ) ); + return testkitState + .getDriverHolder(id) + .getDriver() + .verifyConnectivityAsync() + .thenApply(ignored -> createResponse(id)); } @Override - public Mono processRx( TestkitState testkitState ) - { - return Mono.fromCompletionStage( processAsync( testkitState ) ); + public Mono processRx(TestkitState testkitState) { + return Mono.fromCompletionStage(processAsync(testkitState)); } - private Driver createResponse( String id ) - { - return Driver.builder().data( Driver.DriverBody.builder().id( id ).build() ).build(); + private Driver createResponse(String id) { + return Driver.builder().data(Driver.DriverBody.builder().id(id).build()).build(); } @Setter @Getter - public static class VerifyConnectivityBody - { + public static class VerifyConnectivityBody { private String driverId; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/deserializer/TestkitCypherParamDeserializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/deserializer/TestkitCypherParamDeserializer.java index 1fa031bfbd..929c67ba30 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/deserializer/TestkitCypherParamDeserializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/deserializer/TestkitCypherParamDeserializer.java @@ -18,92 +18,74 @@ */ package neo4j.org.testkit.backend.messages.requests.deserializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherTypeToJavaType; + import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherTypeToJavaType; - -public class TestkitCypherParamDeserializer extends StdDeserializer> -{ - public TestkitCypherParamDeserializer() - { - super( Map.class ); +public class TestkitCypherParamDeserializer extends StdDeserializer> { + public TestkitCypherParamDeserializer() { + super(Map.class); } - public TestkitCypherParamDeserializer( Class typeClass ) - { - super( typeClass ); + public TestkitCypherParamDeserializer(Class typeClass) { + super(typeClass); } @Override - public Map deserialize( JsonParser p, DeserializationContext ctxt ) throws IOException, JsonProcessingException - { - Map result = new HashMap<>(); + public Map deserialize(JsonParser p, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + Map result = new HashMap<>(); String key; - if ( p.isExpectedStartObjectToken() ) - { + if (p.isExpectedStartObjectToken()) { key = p.nextFieldName(); - } - else - { + } else { JsonToken t = p.getCurrentToken(); - if ( t == JsonToken.END_OBJECT ) - { + if (t == JsonToken.END_OBJECT) { return Collections.emptyMap(); } - if ( t != JsonToken.FIELD_NAME ) - { - ctxt.reportWrongTokenException( this, JsonToken.FIELD_NAME, null ); + if (t != JsonToken.FIELD_NAME) { + ctxt.reportWrongTokenException(this, JsonToken.FIELD_NAME, null); } key = p.getCurrentName(); } - for ( ; key != null; key = p.nextFieldName() ) - { + for (; key != null; key = p.nextFieldName()) { String paramType = null; - if ( p.nextToken() == JsonToken.START_OBJECT ) - { + if (p.nextToken() == JsonToken.START_OBJECT) { String fieldName = p.nextFieldName(); - if ( fieldName.equals( "name" ) ) - { + if (fieldName.equals("name")) { paramType = p.nextTextValue(); - Class mapValueType = cypherTypeToJavaType( paramType ); + Class mapValueType = cypherTypeToJavaType(paramType); p.nextFieldName(); // next is data which we can drop p.nextToken(); p.nextToken(); p.nextToken(); - if ( mapValueType == null ) - { - result.put( key, null ); - } else - { - if ( paramType.equals( "CypherMap" ) ) // special recursive case for maps - { - result.put( key, deserialize( p, ctxt ) ); - } - else + if (mapValueType == null) { + result.put(key, null); + } else { + if (paramType.equals("CypherMap")) // special recursive case for maps { - result.put( key, p.readValueAs( mapValueType ) ); + result.put(key, deserialize(p, ctxt)); + } else { + result.put(key, p.readValueAs(mapValueType)); } } - } } - p.nextToken(); //close value + p.nextToken(); // close value p.nextToken(); // close map } return result; } } - diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/deserializer/TestkitListDeserializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/deserializer/TestkitListDeserializer.java index 42a11ca066..034fd24116 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/deserializer/TestkitListDeserializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/deserializer/TestkitListDeserializer.java @@ -18,83 +18,69 @@ */ package neo4j.org.testkit.backend.messages.requests.deserializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherTypeToJavaType; + import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; - import java.io.IOException; import java.util.ArrayList; import java.util.List; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherTypeToJavaType; - -public class TestkitListDeserializer extends StdDeserializer> -{ +public class TestkitListDeserializer extends StdDeserializer> { private final TestkitCypherParamDeserializer mapDeserializer; - public TestkitListDeserializer() - { - super( List.class ); + public TestkitListDeserializer() { + super(List.class); mapDeserializer = new TestkitCypherParamDeserializer(); } @Override - public List deserialize( JsonParser p, DeserializationContext ctxt ) throws IOException, JsonProcessingException - { + public List deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { List result = new ArrayList<>(); JsonToken t = p.getCurrentToken(); - if ( t == JsonToken.END_OBJECT ) - { + if (t == JsonToken.END_OBJECT) { return result; } - if ( t != JsonToken.START_ARRAY ) - { - ctxt.reportWrongTokenException( this, JsonToken.FIELD_NAME, null ); + if (t != JsonToken.START_ARRAY) { + ctxt.reportWrongTokenException(this, JsonToken.FIELD_NAME, null); } JsonToken nextToken = p.nextToken(); // standard list - if ( nextToken == JsonToken.VALUE_STRING ) - { - while ( nextToken != JsonToken.END_ARRAY && nextToken != null ) - { - result.add( p.readValueAs( String.class ) ); + if (nextToken == JsonToken.VALUE_STRING) { + while (nextToken != JsonToken.END_ARRAY && nextToken != null) { + result.add(p.readValueAs(String.class)); nextToken = p.nextToken(); } return result; } - //cypher parameter list - while ( nextToken != JsonToken.END_ARRAY ) - { + // cypher parameter list + while (nextToken != JsonToken.END_ARRAY) { String paramType = null; - if ( nextToken == JsonToken.START_OBJECT ) - { + if (nextToken == JsonToken.START_OBJECT) { String fieldName = p.nextFieldName(); - if ( fieldName.equals( "name" ) ) - { + if (fieldName.equals("name")) { paramType = p.nextTextValue(); - Class mapValueType = cypherTypeToJavaType( paramType ); + Class mapValueType = cypherTypeToJavaType(paramType); p.nextFieldName(); // next is data which we can drop p.nextToken(); p.nextToken(); p.nextToken(); - if ( mapValueType == null ) - { - result.add( null ); - } - else - { - if ( paramType.equals( "CypherMap" ) ) // special recursive case for maps + if (mapValueType == null) { + result.add(null); + } else { + if (paramType.equals("CypherMap")) // special recursive case for maps { - result.add( mapDeserializer.deserialize( p, ctxt ) ); + result.add(mapDeserializer.deserialize(p, ctxt)); } else { - result.add( p.readValueAs( mapValueType ) ); + result.add(p.readValueAs(mapValueType)); } } } @@ -103,4 +89,4 @@ public List deserialize( JsonParser p, DeserializationContext ctxt ) throws I } return result; } -} \ No newline at end of file +} diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/BackendError.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/BackendError.java index 703562939f..3f830e5055 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/BackendError.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/BackendError.java @@ -23,20 +23,17 @@ @Getter @Builder -public class BackendError implements TestkitResponse -{ +public class BackendError implements TestkitResponse { private final BackendErrorBody data; @Override - public String testkitName() - { + public String testkitName() { return "BackendError"; } @Getter @Builder - public static class BackendErrorBody - { + public static class BackendErrorBody { private String msg; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Bookmarks.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Bookmarks.java index 2492aa25a7..32a3db495b 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Bookmarks.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Bookmarks.java @@ -20,25 +20,21 @@ import lombok.Builder; import lombok.Getter; - import org.neo4j.driver.Bookmark; @Getter @Builder -public class Bookmarks implements TestkitResponse -{ +public class Bookmarks implements TestkitResponse { BookmarksBody data; @Override - public String testkitName() - { + public String testkitName() { return "Bookmarks"; } @Getter @Builder - public static class BookmarksBody - { + public static class BookmarksBody { private Bookmark bookmarks; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/ConnectionPoolMetrics.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/ConnectionPoolMetrics.java index fbbee3989c..c3464a058e 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/ConnectionPoolMetrics.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/ConnectionPoolMetrics.java @@ -23,20 +23,17 @@ @Getter @Builder -public class ConnectionPoolMetrics implements TestkitResponse -{ +public class ConnectionPoolMetrics implements TestkitResponse { private final ConnectionPoolMetricsBody data; @Override - public String testkitName() - { + public String testkitName() { return "ConnectionPoolMetrics"; } @Getter @Builder - public static class ConnectionPoolMetricsBody - { + public static class ConnectionPoolMetricsBody { private int inUse; private int idle; } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DomainNameResolutionRequired.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DomainNameResolutionRequired.java index 61be8a5a83..549a1606f9 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DomainNameResolutionRequired.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DomainNameResolutionRequired.java @@ -23,26 +23,22 @@ @Getter @Builder -public class DomainNameResolutionRequired implements TestkitCallback -{ +public class DomainNameResolutionRequired implements TestkitCallback { private DomainNameResolutionRequiredBody data; @Override - public String testkitName() - { + public String testkitName() { return "DomainNameResolutionRequired"; } @Override - public String getCallbackId() - { + public String getCallbackId() { return data.getId(); } @Getter @Builder - public static class DomainNameResolutionRequiredBody - { + public static class DomainNameResolutionRequiredBody { private String id; private String name; diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Driver.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Driver.java index 9407b92b0e..3a6e499224 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Driver.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Driver.java @@ -23,20 +23,17 @@ @Getter @Builder -public class Driver implements TestkitResponse -{ +public class Driver implements TestkitResponse { private final DriverBody data; @Override - public String testkitName() - { + public String testkitName() { return "Driver"; } @Getter @Builder - public static class DriverBody - { + public static class DriverBody { private final String id; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DriverError.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DriverError.java index 9b07cebbf5..6883ef4c9d 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DriverError.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DriverError.java @@ -23,20 +23,17 @@ @Getter @Builder -public class DriverError implements TestkitResponse -{ +public class DriverError implements TestkitResponse { private DriverErrorBody data; @Override - public String testkitName() - { + public String testkitName() { return "DriverError"; } @Getter @Builder - public static class DriverErrorBody - { + public static class DriverErrorBody { private String id; private String errorType; diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DriverIsEncrypted.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DriverIsEncrypted.java index 2f70a897ad..c49b64dba8 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DriverIsEncrypted.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/DriverIsEncrypted.java @@ -23,20 +23,17 @@ @Getter @Builder -public class DriverIsEncrypted implements TestkitResponse -{ +public class DriverIsEncrypted implements TestkitResponse { private final DriverIsEncryptedBody data; @Override - public String testkitName() - { + public String testkitName() { return "DriverIsEncrypted"; } @Getter @Builder - public static class DriverIsEncryptedBody - { + public static class DriverIsEncryptedBody { private final boolean encrypted; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/FeatureList.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/FeatureList.java index 03d2fe96c4..83f758af7c 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/FeatureList.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/FeatureList.java @@ -18,27 +18,23 @@ */ package neo4j.org.testkit.backend.messages.responses; +import java.util.Set; import lombok.Builder; import lombok.Getter; -import java.util.Set; - @Getter @Builder -public class FeatureList implements TestkitResponse -{ +public class FeatureList implements TestkitResponse { private final FeatureListBody data; @Override - public String testkitName() - { + public String testkitName() { return "FeatureList"; } @Getter @Builder - public static class FeatureListBody - { + public static class FeatureListBody { private final Set features; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/MultiDBSupport.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/MultiDBSupport.java index 0d126c011f..3112b397b8 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/MultiDBSupport.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/MultiDBSupport.java @@ -23,20 +23,17 @@ @Getter @Builder -public class MultiDBSupport implements TestkitResponse -{ +public class MultiDBSupport implements TestkitResponse { private final MultiDBSupportBody data; @Override - public String testkitName() - { + public String testkitName() { return "MultiDBSupport"; } @Getter @Builder - public static class MultiDBSupportBody - { + public static class MultiDBSupportBody { private final String id; private final boolean available; diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/NullRecord.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/NullRecord.java index 1cfd546213..e4374d88a2 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/NullRecord.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/NullRecord.java @@ -23,11 +23,9 @@ @Getter @Builder -public class NullRecord implements TestkitResponse -{ +public class NullRecord implements TestkitResponse { @Override - public String testkitName() - { + public String testkitName() { return "NullRecord"; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Record.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Record.java index 4000c2dcd5..10f70e1644 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Record.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Record.java @@ -23,20 +23,17 @@ @Getter @Builder -public class Record implements TestkitResponse -{ +public class Record implements TestkitResponse { private RecordBody data; @Override - public String testkitName() - { + public String testkitName() { return "Record"; } @Getter @Builder - public static class RecordBody - { + public static class RecordBody { private org.neo4j.driver.Record values; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RecordList.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RecordList.java index bad292f2b4..58dcb19315 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RecordList.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RecordList.java @@ -18,27 +18,23 @@ */ package neo4j.org.testkit.backend.messages.responses; +import java.util.List; import lombok.Builder; import lombok.Getter; -import java.util.List; - @Getter @Builder -public class RecordList implements TestkitResponse -{ +public class RecordList implements TestkitResponse { private final RecordListBody data; @Override - public String testkitName() - { + public String testkitName() { return "RecordList"; } @Getter @Builder - public static class RecordListBody - { + public static class RecordListBody { private final List records; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/ResolverResolutionRequired.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/ResolverResolutionRequired.java index 14961f3478..432b36c087 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/ResolverResolutionRequired.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/ResolverResolutionRequired.java @@ -23,26 +23,22 @@ @Getter @Builder -public class ResolverResolutionRequired implements TestkitCallback -{ +public class ResolverResolutionRequired implements TestkitCallback { private ResolverResolutionRequiredBody data; @Override - public String testkitName() - { + public String testkitName() { return "ResolverResolutionRequired"; } @Override - public String getCallbackId() - { + public String getCallbackId() { return data.getId(); } @Getter @Builder - public static class ResolverResolutionRequiredBody - { + public static class ResolverResolutionRequiredBody { private String id; private String address; diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Result.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Result.java index c620ad82aa..9e0c687cae 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Result.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Result.java @@ -18,27 +18,23 @@ */ package neo4j.org.testkit.backend.messages.responses; +import java.util.List; import lombok.Builder; import lombok.Getter; -import java.util.List; - @Getter @Builder -public class Result implements TestkitResponse -{ +public class Result implements TestkitResponse { private ResultBody data; @Override - public String testkitName() - { + public String testkitName() { return "Result"; } @Getter @Builder - public static class ResultBody - { + public static class ResultBody { private String id; private List keys; diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RetryableDone.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RetryableDone.java index c2fa2a6e9f..db8f6f1186 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RetryableDone.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RetryableDone.java @@ -23,11 +23,9 @@ @Getter @Builder -public class RetryableDone implements TestkitResponse -{ +public class RetryableDone implements TestkitResponse { @Override - public String testkitName() - { + public String testkitName() { return "RetryableDone"; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RetryableTry.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RetryableTry.java index ce09a92c04..3fbec5d7c1 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RetryableTry.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RetryableTry.java @@ -23,20 +23,17 @@ @Getter @Builder -public class RetryableTry implements TestkitResponse -{ +public class RetryableTry implements TestkitResponse { private RetryableTryBody data; @Override - public String testkitName() - { + public String testkitName() { return "RetryableTry"; } @Getter @Builder - public static class RetryableTryBody - { + public static class RetryableTryBody { private String id; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RoutingTable.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RoutingTable.java index d13156a75b..fef64d9805 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RoutingTable.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RoutingTable.java @@ -18,27 +18,23 @@ */ package neo4j.org.testkit.backend.messages.responses; +import java.util.List; import lombok.Builder; import lombok.Getter; -import java.util.List; - @Getter @Builder -public class RoutingTable implements TestkitResponse -{ +public class RoutingTable implements TestkitResponse { private RoutingTableBody data; @Override - public String testkitName() - { + public String testkitName() { return "RoutingTable"; } @Getter @Builder - public static class RoutingTableBody - { + public static class RoutingTableBody { private String database; private long ttl; private List routers; diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RunTest.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RunTest.java index be60a64cef..3f354bc247 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RunTest.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/RunTest.java @@ -21,11 +21,9 @@ import lombok.Builder; @Builder -public class RunTest implements TestkitResponse -{ +public class RunTest implements TestkitResponse { @Override - public String testkitName() - { + public String testkitName() { return "RunTest"; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Session.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Session.java index 8fcde7fcde..2eddfe25ff 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Session.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Session.java @@ -23,20 +23,17 @@ @Getter @Builder -public class Session implements TestkitResponse -{ +public class Session implements TestkitResponse { private SessionBody data; @Override - public String testkitName() - { + public String testkitName() { return "Session"; } @Getter @Builder - public static class SessionBody - { + public static class SessionBody { private String id; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/SkipTest.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/SkipTest.java index 6ccf9204ed..19ada73e97 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/SkipTest.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/SkipTest.java @@ -23,20 +23,17 @@ @Getter @Builder -public class SkipTest implements TestkitResponse -{ +public class SkipTest implements TestkitResponse { private SkipTestBody data; @Override - public String testkitName() - { + public String testkitName() { return "SkipTest"; } @Getter @Builder - public static class SkipTestBody - { + public static class SkipTestBody { private final String reason; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Summary.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Summary.java index d651f1c6cd..4a888e4e82 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Summary.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Summary.java @@ -18,31 +18,26 @@ */ package neo4j.org.testkit.backend.messages.responses; +import java.util.List; +import java.util.Map; import lombok.Builder; import lombok.Getter; import lombok.experimental.SuperBuilder; - -import java.util.List; -import java.util.Map; - import org.neo4j.driver.Value; @Getter @Builder -public class Summary implements TestkitResponse -{ +public class Summary implements TestkitResponse { private SummaryBody data; @Override - public String testkitName() - { + public String testkitName() { return "Summary"; } @Getter @Builder - public static class SummaryBody - { + public static class SummaryBody { private ServerInfo serverInfo; private Counters counters; @@ -66,8 +61,7 @@ public static class SummaryBody @Getter @Builder - public static class ServerInfo - { + public static class ServerInfo { private String address; private String protocolVersion; @@ -77,8 +71,7 @@ public static class ServerInfo @Getter @Builder - public static class Counters - { + public static class Counters { private int constraintsAdded; private int constraintsRemoved; @@ -110,17 +103,15 @@ public static class Counters @Getter @Builder - public static class Query - { + public static class Query { private String text; - private Map parameters; + private Map parameters; } @Getter @Builder - public static class Notification - { + public static class Notification { private String code; private String title; @@ -134,8 +125,7 @@ public static class Notification @Getter @Builder - public static class InputPosition - { + public static class InputPosition { private int offset; private int line; @@ -145,11 +135,10 @@ public static class InputPosition @Getter @SuperBuilder - public static class Plan - { + public static class Plan { private String operatorType; - private Map args; + private Map args; private List identifiers; @@ -158,8 +147,7 @@ public static class Plan @Getter @SuperBuilder - public static class Profile extends Plan - { + public static class Profile extends Plan { private long dbHits; private long rows; diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/TestkitCallback.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/TestkitCallback.java index f43e37ccf8..4f87c70260 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/TestkitCallback.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/TestkitCallback.java @@ -24,7 +24,6 @@ * This is a special type of {@link TestkitResponse} that is typically sent during driver action processing to request some action or data from Testkit, which * must respond with {@link TestkitCallbackResult}. */ -public interface TestkitCallback extends TestkitResponse -{ +public interface TestkitCallback extends TestkitResponse { String getCallbackId(); } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/TestkitResponse.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/TestkitResponse.java index a9f7e07c00..0593311088 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/TestkitResponse.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/TestkitResponse.java @@ -20,8 +20,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; -@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, property = "name" ) -public interface TestkitResponse -{ +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "name") +public interface TestkitResponse { String testkitName(); } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Transaction.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Transaction.java index f5f65b8729..a90a77d05a 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Transaction.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/Transaction.java @@ -23,20 +23,17 @@ @Getter @Builder -public class Transaction implements TestkitResponse -{ +public class Transaction implements TestkitResponse { private final TransactionBody data; @Override - public String testkitName() - { + public String testkitName() { return "Transaction"; } @Getter @Builder - public static class TransactionBody - { + public static class TransactionBody { private final String id; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/GenUtils.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/GenUtils.java index 59ba8e4455..8e506f7fdc 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/GenUtils.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/GenUtils.java @@ -19,73 +19,63 @@ package neo4j.org.testkit.backend.messages.responses.serializer; import com.fasterxml.jackson.core.JsonGenerator; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; - import java.io.IOException; import java.util.List; import java.util.Map; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; -@AllArgsConstructor( access = AccessLevel.PRIVATE ) -public final class GenUtils -{ - public static void object( JsonGenerator gen, RunnableWithIOException runnable ) throws IOException - { +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public final class GenUtils { + public static void object(JsonGenerator gen, RunnableWithIOException runnable) throws IOException { gen.writeStartObject(); runnable.run(); gen.writeEndObject(); } - public static void list( JsonGenerator gen, List list ) throws IOException - { + public static void list(JsonGenerator gen, List list) throws IOException { gen.writeStartArray(); - for ( T element : list ) - { - gen.writeObject( element ); + for (T element : list) { + gen.writeObject(element); } gen.writeEndArray(); } - public static void cypherObject( JsonGenerator gen, String name, T value ) throws IOException - { - cypherObject( gen, name, () -> gen.writeObjectField("value", value ) ); + public static void cypherObject(JsonGenerator gen, String name, T value) throws IOException { + cypherObject(gen, name, () -> gen.writeObjectField("value", value)); } - public static void cypherObject( JsonGenerator gen, String name, RunnableWithIOException runnable ) throws IOException - { - object( gen, () -> - { - gen.writeStringField( "name", name ); - gen.writeFieldName( "data" ); - object( gen, runnable ); - } ); + public static void cypherObject(JsonGenerator gen, String name, RunnableWithIOException runnable) + throws IOException { + object(gen, () -> { + gen.writeStringField("name", name); + gen.writeFieldName("data"); + object(gen, runnable); + }); } - public static Class cypherTypeToJavaType( String typeString ) - { - switch ( typeString ) - { - case "CypherBool": - return Boolean.class; - case "CypherInt": - return Integer.class; - case "CypherFloat": - return Double.class; - case "CypherString": - return String.class; - case "CypherList": - return List.class; - case "CypherMap": - return Map.class; - case "CypherNull": - return null; - default: - return null; + public static Class cypherTypeToJavaType(String typeString) { + switch (typeString) { + case "CypherBool": + return Boolean.class; + case "CypherInt": + return Integer.class; + case "CypherFloat": + return Double.class; + case "CypherString": + return String.class; + case "CypherList": + return List.class; + case "CypherMap": + return Map.class; + case "CypherNull": + return null; + default: + return null; } } - interface RunnableWithIOException - { + interface RunnableWithIOException { void run() throws IOException; } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitBookmarkSerializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitBookmarkSerializer.java index a786a22462..36eb8f0c66 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitBookmarkSerializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitBookmarkSerializer.java @@ -21,29 +21,23 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; import java.util.Set; - import org.neo4j.driver.Bookmark; -public class TestkitBookmarkSerializer extends StdSerializer -{ - public TestkitBookmarkSerializer() - { - super( Bookmark.class ); +public class TestkitBookmarkSerializer extends StdSerializer { + public TestkitBookmarkSerializer() { + super(Bookmark.class); } @Override - public void serialize( Bookmark value, JsonGenerator gen, SerializerProvider provider ) throws IOException - { + public void serialize(Bookmark value, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeStartArray(); Set bookmarks = value.values(); - for ( String bm : bookmarks ) - { - gen.writeString( bm ); + for (String bm : bookmarks) { + gen.writeString(bm); } gen.writeEndArray(); diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitListValueSerializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitListValueSerializer.java index 7df23d16bd..31d8c96e08 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitListValueSerializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitListValueSerializer.java @@ -18,32 +18,27 @@ */ package neo4j.org.testkit.backend.messages.responses.serializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.list; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; import java.util.function.Function; - import org.neo4j.driver.internal.value.ListValue; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.list; - -public class TestkitListValueSerializer extends StdSerializer -{ - public TestkitListValueSerializer() - { - super( ListValue.class ); +public class TestkitListValueSerializer extends StdSerializer { + public TestkitListValueSerializer() { + super(ListValue.class); } @Override - public void serialize( ListValue listValue, JsonGenerator gen, SerializerProvider serializerProvider ) throws IOException - { - cypherObject( gen, "CypherList", () -> - { - gen.writeFieldName( "value" ); - list( gen, listValue.asList( Function.identity() ) ); + public void serialize(ListValue listValue, JsonGenerator gen, SerializerProvider serializerProvider) + throws IOException { + cypherObject(gen, "CypherList", () -> { + gen.writeFieldName("value"); + list(gen, listValue.asList(Function.identity())); }); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitMapValueSerializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitMapValueSerializer.java index d5a857c873..b9487563d7 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitMapValueSerializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitMapValueSerializer.java @@ -18,40 +18,34 @@ */ package neo4j.org.testkit.backend.messages.responses.serializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.object; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; import java.util.Map; import java.util.function.Function; - import org.neo4j.driver.Value; import org.neo4j.driver.internal.value.MapValue; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.object; - -public class TestkitMapValueSerializer extends StdSerializer -{ - public TestkitMapValueSerializer() - { - super( MapValue.class ); +public class TestkitMapValueSerializer extends StdSerializer { + public TestkitMapValueSerializer() { + super(MapValue.class); } @Override - public void serialize( MapValue mapValue, JsonGenerator gen, SerializerProvider serializerProvider ) throws IOException - { - cypherObject( gen, "CypherMap", () -> - { - gen.writeFieldName( "value" ); - object( gen, () -> - { - for ( Map.Entry entry : mapValue.asMap( Function.identity() ).entrySet() ) - { - gen.writeObjectField( entry.getKey(), entry.getValue() ); + public void serialize(MapValue mapValue, JsonGenerator gen, SerializerProvider serializerProvider) + throws IOException { + cypherObject(gen, "CypherMap", () -> { + gen.writeFieldName("value"); + object(gen, () -> { + for (Map.Entry entry : + mapValue.asMap(Function.identity()).entrySet()) { + gen.writeObjectField(entry.getKey(), entry.getValue()); } - } ); - } ); + }); + }); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitNodeValueSerializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitNodeValueSerializer.java index 19dd829cf4..28a662012d 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitNodeValueSerializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitNodeValueSerializer.java @@ -18,14 +18,14 @@ */ package neo4j.org.testkit.backend.messages.responses.serializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; import java.util.function.Function; import java.util.stream.StreamSupport; - import org.neo4j.driver.internal.value.IntegerValue; import org.neo4j.driver.internal.value.ListValue; import org.neo4j.driver.internal.value.MapValue; @@ -33,31 +33,25 @@ import org.neo4j.driver.internal.value.StringValue; import org.neo4j.driver.types.Node; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; - -public class TestkitNodeValueSerializer extends StdSerializer -{ - public TestkitNodeValueSerializer() - { - super( NodeValue.class ); +public class TestkitNodeValueSerializer extends StdSerializer { + public TestkitNodeValueSerializer() { + super(NodeValue.class); } @Override - public void serialize( NodeValue nodeValue, JsonGenerator gen, SerializerProvider serializerProvider ) throws IOException - { + public void serialize(NodeValue nodeValue, JsonGenerator gen, SerializerProvider serializerProvider) + throws IOException { - cypherObject( gen, "Node", () -> - { + cypherObject(gen, "Node", () -> { Node node = nodeValue.asNode(); - gen.writeObjectField( "id", new IntegerValue( node.id() ) ); - - StringValue[] labels = StreamSupport.stream( node.labels().spliterator(), false ) - .map( StringValue::new ) - .toArray( StringValue[]::new ); + gen.writeObjectField("id", new IntegerValue(node.id())); - gen.writeObjectField( "labels", new ListValue( labels ) ); - gen.writeObjectField( "props", new MapValue( node.asMap( Function.identity() ) ) ); + StringValue[] labels = StreamSupport.stream(node.labels().spliterator(), false) + .map(StringValue::new) + .toArray(StringValue[]::new); - } ); + gen.writeObjectField("labels", new ListValue(labels)); + gen.writeObjectField("props", new MapValue(node.asMap(Function.identity()))); + }); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitPathValueSerializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitPathValueSerializer.java index e56346e856..3918ea8d52 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitPathValueSerializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitPathValueSerializer.java @@ -18,42 +18,37 @@ */ package neo4j.org.testkit.backend.messages.responses.serializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; import java.util.stream.StreamSupport; - import org.neo4j.driver.internal.value.ListValue; import org.neo4j.driver.internal.value.NodeValue; import org.neo4j.driver.internal.value.PathValue; import org.neo4j.driver.internal.value.RelationshipValue; import org.neo4j.driver.types.Path; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; - -public class TestkitPathValueSerializer extends StdSerializer -{ - public TestkitPathValueSerializer() - { - super( PathValue.class ); +public class TestkitPathValueSerializer extends StdSerializer { + public TestkitPathValueSerializer() { + super(PathValue.class); } @Override - public void serialize( PathValue pathValue, JsonGenerator gen, SerializerProvider provider ) throws IOException - { - cypherObject( gen, "Path", () -> - { + public void serialize(PathValue pathValue, JsonGenerator gen, SerializerProvider provider) throws IOException { + cypherObject(gen, "Path", () -> { Path path = pathValue.asPath(); - NodeValue[] nodes = StreamSupport.stream( path.nodes().spliterator(), false ) - .map( NodeValue::new ) - .toArray( NodeValue[]::new ); - gen.writeObjectField( "nodes", new ListValue( nodes ) ); - RelationshipValue[] relationships = StreamSupport.stream( path.relationships().spliterator(), false ) - .map( RelationshipValue::new ) - .toArray( RelationshipValue[]::new ); - gen.writeObjectField( "relationships", new ListValue( relationships ) ); - } ); + NodeValue[] nodes = StreamSupport.stream(path.nodes().spliterator(), false) + .map(NodeValue::new) + .toArray(NodeValue[]::new); + gen.writeObjectField("nodes", new ListValue(nodes)); + RelationshipValue[] relationships = StreamSupport.stream( + path.relationships().spliterator(), false) + .map(RelationshipValue::new) + .toArray(RelationshipValue[]::new); + gen.writeObjectField("relationships", new ListValue(relationships)); + }); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitRecordSerializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitRecordSerializer.java index 7cdb0c6a26..356ecd2813 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitRecordSerializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitRecordSerializer.java @@ -18,27 +18,22 @@ */ package neo4j.org.testkit.backend.messages.responses.serializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.list; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; - import org.neo4j.driver.Record; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.list; - -public class TestkitRecordSerializer extends StdSerializer -{ +public class TestkitRecordSerializer extends StdSerializer { - public TestkitRecordSerializer() - { - super( org.neo4j.driver.Record.class ); + public TestkitRecordSerializer() { + super(org.neo4j.driver.Record.class); } @Override - public void serialize( Record record, JsonGenerator gen, SerializerProvider provider ) throws IOException - { - list( gen, record.values() ); + public void serialize(Record record, JsonGenerator gen, SerializerProvider provider) throws IOException { + list(gen, record.values()); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitRelationshipValueSerializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitRelationshipValueSerializer.java index 8bbbcc41ad..fca2262d4f 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitRelationshipValueSerializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitRelationshipValueSerializer.java @@ -18,39 +18,34 @@ */ package neo4j.org.testkit.backend.messages.responses.serializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; import java.util.function.Function; - import org.neo4j.driver.internal.value.IntegerValue; import org.neo4j.driver.internal.value.MapValue; import org.neo4j.driver.internal.value.RelationshipValue; import org.neo4j.driver.internal.value.StringValue; import org.neo4j.driver.types.Relationship; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; - -public class TestkitRelationshipValueSerializer extends StdSerializer -{ - public TestkitRelationshipValueSerializer() - { - super( RelationshipValue.class ); +public class TestkitRelationshipValueSerializer extends StdSerializer { + public TestkitRelationshipValueSerializer() { + super(RelationshipValue.class); } @Override - public void serialize( RelationshipValue relationshipValue, JsonGenerator gen, SerializerProvider provider ) throws IOException - { - cypherObject( gen, "Relationship", () -> - { + public void serialize(RelationshipValue relationshipValue, JsonGenerator gen, SerializerProvider provider) + throws IOException { + cypherObject(gen, "Relationship", () -> { Relationship relationship = relationshipValue.asRelationship(); - gen.writeObjectField( "id", new IntegerValue( relationship.id() ) ); - gen.writeObjectField( "startNodeId", new IntegerValue( relationship.startNodeId() ) ); - gen.writeObjectField( "endNodeId", new IntegerValue( relationship.endNodeId() ) ); - gen.writeObjectField( "type", new StringValue( relationship.type() ) ); - gen.writeObjectField( "props", new MapValue( relationship.asMap( Function.identity() ) ) ); - } ); + gen.writeObjectField("id", new IntegerValue(relationship.id())); + gen.writeObjectField("startNodeId", new IntegerValue(relationship.startNodeId())); + gen.writeObjectField("endNodeId", new IntegerValue(relationship.endNodeId())); + gen.writeObjectField("type", new StringValue(relationship.type())); + gen.writeObjectField("props", new MapValue(relationship.asMap(Function.identity()))); + }); } } diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitValueSerializer.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitValueSerializer.java index 28f88a8e33..a3ada4d893 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitValueSerializer.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/responses/serializer/TestkitValueSerializer.java @@ -18,39 +18,32 @@ */ package neo4j.org.testkit.backend.messages.responses.serializer; +import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; - import org.neo4j.driver.Value; import org.neo4j.driver.internal.types.InternalTypeSystem; -import static neo4j.org.testkit.backend.messages.responses.serializer.GenUtils.cypherObject; - -public class TestkitValueSerializer extends StdSerializer -{ - public TestkitValueSerializer( ) - { - super( Value.class ); +public class TestkitValueSerializer extends StdSerializer { + public TestkitValueSerializer() { + super(Value.class); } @Override - public void serialize( Value value, JsonGenerator gen, SerializerProvider provider ) throws IOException - { - if ( InternalTypeSystem.TYPE_SYSTEM.BOOLEAN().isTypeOf( value ) ) - { - cypherObject( gen, "CypherBool", value.asBoolean() ); - } else if ( InternalTypeSystem.TYPE_SYSTEM.NULL().isTypeOf( value ) ) { - cypherObject( gen, "CypherNull", () -> gen.writeNullField( "value" ) ); - } else if ( InternalTypeSystem.TYPE_SYSTEM.INTEGER().isTypeOf( value ) ) { - cypherObject( gen, "CypherInt", value.asInt() ); - } else if ( InternalTypeSystem.TYPE_SYSTEM.FLOAT().isTypeOf( value ) ) { - cypherObject( gen, "CypherFloat", value.asDouble() ); - } else if ( InternalTypeSystem.TYPE_SYSTEM.STRING().isTypeOf( value ) ) { - cypherObject( gen, "CypherString", value.asString() ); + public void serialize(Value value, JsonGenerator gen, SerializerProvider provider) throws IOException { + if (InternalTypeSystem.TYPE_SYSTEM.BOOLEAN().isTypeOf(value)) { + cypherObject(gen, "CypherBool", value.asBoolean()); + } else if (InternalTypeSystem.TYPE_SYSTEM.NULL().isTypeOf(value)) { + cypherObject(gen, "CypherNull", () -> gen.writeNullField("value")); + } else if (InternalTypeSystem.TYPE_SYSTEM.INTEGER().isTypeOf(value)) { + cypherObject(gen, "CypherInt", value.asInt()); + } else if (InternalTypeSystem.TYPE_SYSTEM.FLOAT().isTypeOf(value)) { + cypherObject(gen, "CypherFloat", value.asDouble()); + } else if (InternalTypeSystem.TYPE_SYSTEM.STRING().isTypeOf(value)) { + cypherObject(gen, "CypherString", value.asString()); } - } } diff --git a/testkit-backend/src/test/java/neo4j/org/testkit/backend/MessageDeserializerTest.java b/testkit-backend/src/test/java/neo4j/org/testkit/backend/MessageDeserializerTest.java index 3b14f34605..f6e6744cf0 100644 --- a/testkit-backend/src/test/java/neo4j/org/testkit/backend/MessageDeserializerTest.java +++ b/testkit-backend/src/test/java/neo4j/org/testkit/backend/MessageDeserializerTest.java @@ -18,6 +18,10 @@ */ package neo4j.org.testkit.backend; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import neo4j.org.testkit.backend.channel.handler.TestkitRequestResponseMapperHandler; @@ -27,59 +31,50 @@ import neo4j.org.testkit.backend.messages.requests.TestkitRequest; import org.junit.jupiter.api.Test; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; - -class MessageDeserializerTest -{ +class MessageDeserializerTest { private static final ObjectMapper mapper = TestkitRequestResponseMapperHandler.newObjectMapper(); @Test - void testDeserializeNewDriver() throws JsonProcessingException - { + void testDeserializeNewDriver() throws JsonProcessingException { Object message = mapper.readValue( - "{\"name\": \"NewDriver\", \"data\": {\"uri\": \"bolt://localhost:7687\", " + - "\"authorizationToken\": {\"name\": \"AuthorizationToken\", \"data\": {\"scheme\": \"basic\", \"principal\": \"neo4j\", " + - "\"credentials\": \"pass\", \"realm\": \"\", \"ticket\": \"\"}}, \"userAgent\": null}}", - TestkitRequest.class ); + "{\"name\": \"NewDriver\", \"data\": {\"uri\": \"bolt://localhost:7687\", " + + "\"authorizationToken\": {\"name\": \"AuthorizationToken\", \"data\": {\"scheme\": \"basic\", \"principal\": \"neo4j\", " + + "\"credentials\": \"pass\", \"realm\": \"\", \"ticket\": \"\"}}, \"userAgent\": null}}", + TestkitRequest.class); - assertThat( message, instanceOf( NewDriver.class ) ); + assertThat(message, instanceOf(NewDriver.class)); NewDriver newDriver = (NewDriver) message; - assertThat( newDriver.getData().getUri(), equalTo( "bolt://localhost:7687" ) ); - assertThat( newDriver.getData().getAuthorizationToken().getTokens().getScheme(), equalTo( "basic" ) ); - assertThat( newDriver.getData().getAuthorizationToken().getTokens().getPrincipal(), equalTo( "neo4j" ) ); + assertThat(newDriver.getData().getUri(), equalTo("bolt://localhost:7687")); + assertThat(newDriver.getData().getAuthorizationToken().getTokens().getScheme(), equalTo("basic")); + assertThat(newDriver.getData().getAuthorizationToken().getTokens().getPrincipal(), equalTo("neo4j")); } @Test - void testDeserializerNewSession() throws JsonProcessingException - { + void testDeserializerNewSession() throws JsonProcessingException { Object message = mapper.readValue( - "{\"name\": \"NewSession\", " + - "\"data\": {\"driverId\": \"0\", \"accessMode\": \"w\", \"bookmarks\": null, \"database\": null, \"fetchSize\": null}}", - TestkitRequest.class ); + "{\"name\": \"NewSession\", " + + "\"data\": {\"driverId\": \"0\", \"accessMode\": \"w\", \"bookmarks\": null, \"database\": null, \"fetchSize\": null}}", + TestkitRequest.class); - assertThat( message, instanceOf( NewSession.class ) ); + assertThat(message, instanceOf(NewSession.class)); NewSession sessionRequest = (NewSession) message; - assertThat( sessionRequest.getData().getDriverId(), equalTo( "0" ) ); - assertThat( sessionRequest.getData().getAccessMode(), equalTo( "w" ) ); + assertThat(sessionRequest.getData().getDriverId(), equalTo("0")); + assertThat(sessionRequest.getData().getAccessMode(), equalTo("w")); } @Test - void testDeserializerNewSessionRun() throws JsonProcessingException - { + void testDeserializerNewSessionRun() throws JsonProcessingException { Object message = mapper.readValue( - "{\"name\": \"SessionRun\", \"data\": {\"sessionId\": \"1\", \"cypher\": \"RETURN $x as y\", " + - "\"params\": {\"x\": {\"name\": \"CypherBool\", \"data\": {\"value\": true}}}, \"txMeta\": null, \"timeout\": null}}", - TestkitRequest.class ); + "{\"name\": \"SessionRun\", \"data\": {\"sessionId\": \"1\", \"cypher\": \"RETURN $x as y\", " + + "\"params\": {\"x\": {\"name\": \"CypherBool\", \"data\": {\"value\": true}}}, \"txMeta\": null, \"timeout\": null}}", + TestkitRequest.class); - assertThat( message, instanceOf( SessionRun.class ) ); + assertThat(message, instanceOf(SessionRun.class)); SessionRun sessionRun = (SessionRun) message; - assertThat( sessionRun.getData().getSessionId(), equalTo( "1" ) ); - assertThat( sessionRun.getData().getCypher(), equalTo( "RETURN $x as y" ) ); + assertThat(sessionRun.getData().getSessionId(), equalTo("1")); + assertThat(sessionRun.getData().getCypher(), equalTo("RETURN $x as y")); } - -} \ No newline at end of file +} diff --git a/testkit-backend/src/test/java/neo4j/org/testkit/backend/MessageSerializerTest.java b/testkit-backend/src/test/java/neo4j/org/testkit/backend/MessageSerializerTest.java index 6e0311d784..7f572d7bb6 100644 --- a/testkit-backend/src/test/java/neo4j/org/testkit/backend/MessageSerializerTest.java +++ b/testkit-backend/src/test/java/neo4j/org/testkit/backend/MessageSerializerTest.java @@ -18,27 +18,27 @@ */ package neo4j.org.testkit.backend; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import neo4j.org.testkit.backend.channel.handler.TestkitRequestResponseMapperHandler; import neo4j.org.testkit.backend.messages.responses.Driver; import org.junit.jupiter.api.Test; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; - -public class MessageSerializerTest -{ +public class MessageSerializerTest { private static final ObjectMapper mapper = TestkitRequestResponseMapperHandler.newObjectMapper(); @Test - void shouldSerializerNewDriverResponse() throws JsonProcessingException - { - Driver response = Driver.builder().data( Driver.DriverBody.builder().id( "1" ).build() ).build(); + void shouldSerializerNewDriverResponse() throws JsonProcessingException { + Driver response = Driver.builder() + .data(Driver.DriverBody.builder().id("1").build()) + .build(); String expectedOutput = "{\"name\":\"Driver\",\"data\":{\"id\":\"1\"}}"; - String serializedResponse = mapper.writeValueAsString( response ); + String serializedResponse = mapper.writeValueAsString(response); - assertThat( serializedResponse, equalTo( expectedOutput ) ); + assertThat(serializedResponse, equalTo(expectedOutput)); } }