diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/BoltServerAddress.java b/driver/src/main/java/org/neo4j/driver/internal/BoltServerAddress.java similarity index 99% rename from driver/src/main/java/org/neo4j/driver/internal/async/BoltServerAddress.java rename to driver/src/main/java/org/neo4j/driver/internal/BoltServerAddress.java index 09319d24d4..28ab4c097d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/BoltServerAddress.java +++ b/driver/src/main/java/org/neo4j/driver/internal/BoltServerAddress.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.neo4j.driver.internal.async; +package org.neo4j.driver.internal; import java.net.InetAddress; import java.net.InetSocketAddress; 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 50eceaa612..e9ff1f5043 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DirectConnectionProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DirectConnectionProvider.java @@ -20,7 +20,6 @@ import java.util.concurrent.CompletionStage; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.internal.spi.ConnectionProvider; 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 e2e9cf5003..633abd2651 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java @@ -25,7 +25,6 @@ import java.net.URI; import java.security.GeneralSecurityException; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.async.BootstrapFactory; import org.neo4j.driver.internal.async.ChannelConnector; import org.neo4j.driver.internal.async.ChannelConnectorImpl; @@ -143,11 +142,9 @@ private InternalDriver createDriver( URI uri, BoltServerAddress address, protected InternalDriver createDirectDriver( BoltServerAddress address, Config config, SecurityPlan securityPlan, RetryLogic retryLogic, ConnectionPool connectionPool ) { - ConnectionProvider connectionProvider = - new DirectConnectionProvider( address, connectionPool ); - SessionFactory sessionFactory = - createSessionFactory( connectionProvider, retryLogic, config ); - return createDriver( config, securityPlan, sessionFactory ); + ConnectionProvider connectionProvider = new DirectConnectionProvider( address, connectionPool ); + SessionFactory sessionFactory = createSessionFactory( connectionProvider, retryLogic, config ); + return createDriver( sessionFactory, securityPlan, config ); } /** @@ -166,7 +163,7 @@ protected InternalDriver createRoutingDriver( BoltServerAddress address, Connect ConnectionProvider connectionProvider = createLoadBalancer( address, connectionPool, eventExecutorGroup, config, routingSettings ); SessionFactory sessionFactory = createSessionFactory( connectionProvider, retryLogic, config ); - return createDriver( config, securityPlan, sessionFactory ); + return createDriver( sessionFactory, securityPlan, config ); } /** @@ -174,9 +171,9 @@ protected InternalDriver createRoutingDriver( BoltServerAddress address, Connect *

* This method is protected only for testing */ - protected InternalDriver createDriver( Config config, SecurityPlan securityPlan, SessionFactory sessionFactory ) + protected InternalDriver createDriver( SessionFactory sessionFactory, SecurityPlan securityPlan, Config config ) { - return new InternalDriver( securityPlan, sessionFactory ); + return new InternalDriver( securityPlan, sessionFactory, config.logging() ); } /** diff --git a/driver/src/main/java/org/neo4j/driver/internal/ExplicitTransaction.java b/driver/src/main/java/org/neo4j/driver/internal/ExplicitTransaction.java index a9d2548c17..134db0401e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/ExplicitTransaction.java +++ b/driver/src/main/java/org/neo4j/driver/internal/ExplicitTransaction.java @@ -25,7 +25,6 @@ import java.util.function.BiConsumer; import java.util.function.BiFunction; -import org.neo4j.driver.internal.async.InternalStatementResultCursor; import org.neo4j.driver.internal.async.QueryRunner; import org.neo4j.driver.internal.async.ResultCursorsHolder; import org.neo4j.driver.internal.handlers.BeginTxResponseHandler; 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 6597a6467d..57c576c1e8 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java @@ -24,6 +24,8 @@ import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.v1.AccessMode; import org.neo4j.driver.v1.Driver; +import org.neo4j.driver.v1.Logger; +import org.neo4j.driver.v1.Logging; import org.neo4j.driver.v1.Session; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -33,13 +35,15 @@ public class InternalDriver implements Driver { private final SecurityPlan securityPlan; private final SessionFactory sessionFactory; + private final Logger log; private AtomicBoolean closed = new AtomicBoolean( false ); - InternalDriver( SecurityPlan securityPlan, SessionFactory sessionFactory ) + InternalDriver( SecurityPlan securityPlan, SessionFactory sessionFactory, Logging logging ) { this.securityPlan = securityPlan; this.sessionFactory = sessionFactory; + this.log = logging.getLog( Driver.class.getSimpleName() ); } @Override @@ -108,6 +112,7 @@ public CompletionStage closeAsync() { if ( closed.compareAndSet( false, true ) ) { + log.info( "Driver instance is closing" ); return sessionFactory.close(); } return completedFuture( null ); diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/InternalStatementResultCursor.java b/driver/src/main/java/org/neo4j/driver/internal/InternalStatementResultCursor.java similarity index 99% rename from driver/src/main/java/org/neo4j/driver/internal/async/InternalStatementResultCursor.java rename to driver/src/main/java/org/neo4j/driver/internal/InternalStatementResultCursor.java index 1f2e0ae6f2..877301b5f2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/InternalStatementResultCursor.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalStatementResultCursor.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.neo4j.driver.internal.async; +package org.neo4j.driver.internal; import java.util.ArrayList; import java.util.List; diff --git a/driver/src/main/java/org/neo4j/driver/internal/NetworkSession.java b/driver/src/main/java/org/neo4j/driver/internal/NetworkSession.java index f40fa53819..7e4279d245 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/NetworkSession.java +++ b/driver/src/main/java/org/neo4j/driver/internal/NetworkSession.java @@ -24,9 +24,8 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicBoolean; -import org.neo4j.driver.internal.async.InternalStatementResultCursor; import org.neo4j.driver.internal.async.QueryRunner; -import org.neo4j.driver.internal.logging.DelegatingLogger; +import org.neo4j.driver.internal.logging.PrefixedLogger; import org.neo4j.driver.internal.retry.RetryLogic; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionProvider; @@ -74,7 +73,7 @@ public NetworkSession( ConnectionProvider connectionProvider, AccessMode mode, R this.connectionProvider = connectionProvider; this.mode = mode; this.retryLogic = retryLogic; - this.logger = new DelegatingLogger( logging.getLog( LOG_NAME ), String.valueOf( hashCode() ) ); + this.logger = new PrefixedLogger( "[" + hashCode() + "]", logging.getLog( LOG_NAME ) ); } @Override 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 0452474ea0..6f90373f84 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/RoutingErrorHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/RoutingErrorHandler.java @@ -18,8 +18,6 @@ */ package org.neo4j.driver.internal; -import org.neo4j.driver.internal.async.BoltServerAddress; - /** * Interface used for tracking errors when connected to a cluster. */ diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelAttributes.java b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelAttributes.java index 342253fdfd..d9f1dd83e4 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelAttributes.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelAttributes.java @@ -21,6 +21,7 @@ import io.netty.channel.Channel; import io.netty.util.AttributeKey; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.util.ServerVersion; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnectedListener.java b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnectedListener.java index d709c60aa7..d5997d3c17 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnectedListener.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnectedListener.java @@ -24,6 +24,8 @@ import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPromise; +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; import org.neo4j.driver.v1.exceptions.ServiceUnavailableException; @@ -36,6 +38,7 @@ public class ChannelConnectedListener implements ChannelFutureListener private final ChannelPipelineBuilder pipelineBuilder; private final ChannelPromise handshakeCompletedPromise; private final Logging logging; + private final Logger log; public ChannelConnectedListener( BoltServerAddress address, ChannelPipelineBuilder pipelineBuilder, ChannelPromise handshakeCompletedPromise, Logging logging ) @@ -44,6 +47,7 @@ public ChannelConnectedListener( BoltServerAddress address, ChannelPipelineBuild this.pipelineBuilder = pipelineBuilder; this.handshakeCompletedPromise = handshakeCompletedPromise; this.logging = logging; + this.log = logging.getLog( getClass().getSimpleName() ); } @Override @@ -53,8 +57,10 @@ public void operationComplete( ChannelFuture future ) if ( future.isSuccess() ) { + log.trace( "Channel %s connected, running bolt handshake", channel ); + ChannelPipeline pipeline = channel.pipeline(); - pipeline.addLast( new HandshakeResponseHandler( pipelineBuilder, handshakeCompletedPromise, logging ) ); + pipeline.addLast( new HandshakeHandler( pipelineBuilder, handshakeCompletedPromise, logging ) ); ChannelFuture handshakeFuture = channel.writeAndFlush( handshake() ); handshakeFuture.addListener( channelFuture -> diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnector.java b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnector.java index 4584f791d9..025264778b 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnector.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnector.java @@ -21,6 +21,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 ); diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnectorImpl.java b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnectorImpl.java index 0da426a1f3..bf44514d37 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnectorImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelConnectorImpl.java @@ -26,6 +26,7 @@ import java.util.Map; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.ConnectionSettings; import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.security.SecurityPlan; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelPipelineBuilderImpl.java b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelPipelineBuilderImpl.java index 5201adca7f..7da5424e2e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelPipelineBuilderImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/ChannelPipelineBuilderImpl.java @@ -20,6 +20,7 @@ import io.netty.channel.ChannelPipeline; +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; @@ -33,7 +34,7 @@ public class ChannelPipelineBuilderImpl implements ChannelPipelineBuilder public void build( MessageFormat messageFormat, ChannelPipeline pipeline, Logging logging ) { // inbound handlers - pipeline.addLast( new ChunkDecoder() ); + pipeline.addLast( new ChunkDecoder( logging ) ); pipeline.addLast( new MessageDecoder() ); pipeline.addLast( new InboundMessageHandler( messageFormat, logging ) ); diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/HandshakeResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/async/HandshakeHandler.java similarity index 70% rename from driver/src/main/java/org/neo4j/driver/internal/async/HandshakeResponseHandler.java rename to driver/src/main/java/org/neo4j/driver/internal/async/HandshakeHandler.java index 517f2af74c..91f1fe9fa3 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/HandshakeResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/HandshakeHandler.java @@ -28,45 +28,83 @@ import java.util.List; import javax.net.ssl.SSLHandshakeException; +import org.neo4j.driver.internal.logging.PrefixedLogger; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1; +import org.neo4j.driver.internal.util.ErrorUtil; import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; import org.neo4j.driver.v1.exceptions.ClientException; import org.neo4j.driver.v1.exceptions.SecurityException; +import org.neo4j.driver.v1.exceptions.ServiceUnavailableException; import static org.neo4j.driver.internal.async.ProtocolUtil.HTTP; import static org.neo4j.driver.internal.async.ProtocolUtil.NO_PROTOCOL_VERSION; import static org.neo4j.driver.internal.async.ProtocolUtil.PROTOCOL_VERSION_1; -public class HandshakeResponseHandler extends ReplayingDecoder +public class HandshakeHandler extends ReplayingDecoder { private final ChannelPipelineBuilder pipelineBuilder; private final ChannelPromise handshakeCompletedPromise; private final Logging logging; - private final Logger log; - public HandshakeResponseHandler( ChannelPipelineBuilder pipelineBuilder, ChannelPromise handshakeCompletedPromise, + private boolean failed; + private Logger log; + + public HandshakeHandler( ChannelPipelineBuilder pipelineBuilder, ChannelPromise handshakeCompletedPromise, Logging logging ) { this.pipelineBuilder = pipelineBuilder; this.handshakeCompletedPromise = handshakeCompletedPromise; this.logging = logging; - this.log = logging.getLog( getClass().getSimpleName() ); + } + + @Override + public void handlerAdded( ChannelHandlerContext ctx ) + { + log = new PrefixedLogger( ctx.channel().toString(), logging, getClass() ); + } + + @Override + protected void handlerRemoved0( ChannelHandlerContext ctx ) + { + failed = false; + log = null; + } + + @Override + public void channelInactive( ChannelHandlerContext ctx ) + { + log.debug( "Channel is inactive" ); + + if ( !failed ) + { + // channel became inactive while doing bolt handshake, not because of some previous error + ServiceUnavailableException error = ErrorUtil.newConnectionTerminatedError(); + fail( ctx, error ); + } } @Override public void exceptionCaught( ChannelHandlerContext ctx, Throwable error ) { - // todo: test this unwrapping and SSLHandshakeException propagation - Throwable cause = error instanceof DecoderException ? error.getCause() : error; - if ( cause instanceof SSLHandshakeException ) + if ( failed ) { - fail( ctx, new SecurityException( "Failed to establish secured connection with the server", cause ) ); + log.warn( "Another fatal error occurred in the pipeline", error ); } else { - fail( ctx, cause ); + failed = true; + + Throwable cause = error instanceof DecoderException ? error.getCause() : error; + if ( cause instanceof SSLHandshakeException ) + { + fail( ctx, new SecurityException( "Failed to establish secured connection with the server", cause ) ); + } + else + { + fail( ctx, cause ); + } } } @@ -74,7 +112,7 @@ public void exceptionCaught( ChannelHandlerContext ctx, Throwable error ) protected void decode( ChannelHandlerContext ctx, ByteBuf in, List out ) { int serverSuggestedVersion = in.readInt(); - log.debug( "Server suggested protocol version: %s", serverSuggestedVersion ); + log.debug( "Server suggested protocol version %s during handshake", serverSuggestedVersion ); ChannelPipeline pipeline = ctx.pipeline(); // this is a one-time handler, remove it when protocol version has been read @@ -101,7 +139,7 @@ protected void decode( ChannelHandlerContext ctx, ByteBuf in, List out ) private void fail( ChannelHandlerContext ctx, Throwable error ) { - ctx.close().addListener( future -> handshakeCompletedPromise.setFailure( error ) ); + ctx.close().addListener( future -> handshakeCompletedPromise.tryFailure( error ) ); } private static Throwable protocolNoSupportedByServerError() diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/Main.java b/driver/src/main/java/org/neo4j/driver/internal/async/Main.java deleted file mode 100644 index cfe5f94a1f..0000000000 --- a/driver/src/main/java/org/neo4j/driver/internal/async/Main.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2002-2017 "Neo Technology," - * Network Engine for Objects in Lund AB [http://neotechnology.com] - * - * This file is part of Neo4j. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.neo4j.driver.internal.async; - -import io.netty.util.internal.ConcurrentSet; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; - -import org.neo4j.driver.v1.AccessMode; -import org.neo4j.driver.v1.AuthToken; -import org.neo4j.driver.v1.AuthTokens; -import org.neo4j.driver.v1.Config; -import org.neo4j.driver.v1.Driver; -import org.neo4j.driver.v1.GraphDatabase; -import org.neo4j.driver.v1.Record; -import org.neo4j.driver.v1.Session; -import org.neo4j.driver.v1.StatementResult; -import org.neo4j.driver.v1.StatementResultCursor; -import org.neo4j.driver.v1.Transaction; - -// todo: remove this class -public class Main -{ - private static final int ITERATIONS = 200; - - private static final String QUERY1 = "RETURN 1"; - private static final String QUERY2 = "MATCH (n:ActiveItem) RETURN n LIMIT 50000"; - - private static final String QUERY3 = - "MATCH (s:Sku{sku_no: {skuNo}})-[:HAS_ITEM_SOURCE]->(i:ItemSource{itemsource: {itemSource}})\n" + - "//Get master sku for auxiliary item\n" + - "OPTIONAL MATCH (s)-[:AUXILIARY_FOR]->(master_sku:Sku) WHERE NOT s.display_auxiliary_content\n" + - "//Get New item for Used item\n" + - "OPTIONAL MATCH (s)-[:USED_VERSION_OF]->(new_sku:Sku)\n" + - "//Get other items like kit details and bundle includes\n" + - "OPTIONAL MATCH (s)-[r:RELATED_ITEM]->(ri:Sku)\n" + - "WITH i, r, coalesce(ri, master_sku, new_sku, s) as sku, coalesce(master_sku, new_sku, s) as final_sku\n" + - "OPTIONAL MATCH (sku)-[:DESCRIBED_AS]->(d:Desc)\n" + - "OPTIONAL MATCH (sku)-[:FEATURED_WITH]->(f:Feature)\n" + - "//Get itemsource of related item\n" + - "OPTIONAL MATCH (sku)-[:HAS_ITEM_SOURCE]->(relatedItemSource:ItemSource)" + - "<-[:KIT_CONTAINS|INCLUDES_ITEMSOURCE*1..2]-(i)\n" + - "WITH i, final_sku, sku, d, f, relatedItemSource, r\n" + - "\tORDER BY f.seqnum\n" + - "WITH final_sku, sku, r, d, i, relatedItemSource, CASE WHEN f IS NOT null THEN collect({\n" + - "\ttitle: f.title,\n" + - "\tbody: f.body,\n" + - "\tisHeader: f.is_header,\n" + - "\tnote: f.note\n" + - "}) END as featureList ORDER BY coalesce(r.seqnum,0)\n" + - "//Get description of kit header or bundle heder\n" + - "OPTIONAL MATCH (final_sku)-[:DESCRIBED_AS]->(mainDescription:Desc) WHERE r is not null\n" + - "RETURN\n" + - "collect(DISTINCT CASE WHEN mainDescription is not null THEN\n" + - "{\n" + - "\titemName: null,\n" + - "\tdescription: {\n" + - "\t\ttext: mainDescription.description,\n" + - "\t\tnote: mainDescription.description_note\n" + - "\t},\n" + - "\tfeatures: {\n" + - "\t \tnote: null,\n" + - "\t\tfeatureList: null\n" + - "\t},\n" + - "\tupc: i.upc,\n" + - "\thasThirdPartyContent: final_sku.has_third_party_content\n" + - "} END)\n" + - "+\n" + - "collect({\n" + - "\titemName: r.item_name,\n" + - "\tdescription: {\n" + - "\t\ttext: d.description,\n" + - "\t\tnote: d.description_note\n" + - "\t},\n" + - "\tfeatures: {\n" + - "\t\tnote: d.feature_note,\n" + - "\t\tfeatureList: featureList\n" + - "\t},\n" + - "\tupc: coalesce(relatedItemSource, i).upc,\n" + - "\thasThirdPartyContent: sku.has_third_party_content\n" + - "}) AS overview;\n"; - - private static final String QUERY = QUERY2; - - private static final Map PARAMS1 = new HashMap<>(); - private static final Map PARAMS2 = new HashMap<>(); - - private static final Map PARAMS = PARAMS1; - - private static final String SCHEME = "bolt+routing"; - private static final String USER = "neo4j"; - private static final String PASSWORD = "test"; - private static final String HOST = "ec2-34-249-23-195.eu-west-1.compute.amazonaws.com"; - private static final int PORT = 26000; - private static final String URI = SCHEME + "://" + HOST + ":" + PORT; - - static - { - PARAMS1.put( "skuNo", 366421 ); - PARAMS1.put( "itemSource", "REG" ); - PARAMS1.put( "catalogId", 2 ); - PARAMS1.put( "locale", "en" ); - Map tmpObj = new HashMap<>(); - tmpObj.put( "skuNo", 366421 ); - tmpObj.put( "itemSource", "REG" ); - PARAMS1.put( "itemList", Collections.singletonList( tmpObj ) ); - } - - public static void main( String[] args ) throws Throwable - { - testSessionRun(); - testSessionRunAsync(); - - testTxRun(); - testTxRunAsync(); - } - - private static void testSessionRun() throws Throwable - { - test( "Session#run()", new Action() - { - @Override - public void apply( Driver driver, MutableInt recordsRead, Set serversUsed ) - { - try ( Session session = driver.session( AccessMode.READ ) ) - { - StatementResult result = session.run( QUERY, PARAMS ); - while ( result.hasNext() ) - { - Record record = result.next(); - useRecord( record ); - recordsRead.increment(); - } - serversUsed.add( result.summary().server().address() ); - } - } - } ); - } - - private static void testSessionRunAsync() throws Throwable - { - test( "Session#runAsync()", new Action() - { - @Override - public void apply( Driver driver, MutableInt recordsRead, Set serversUsed ) - { - Session session = driver.session( AccessMode.READ ); - CompletionStage cursorFuture = session.runAsync( QUERY, PARAMS ); - StatementResultCursor cursor = await( cursorFuture ); - Record record; - while ( (record = await( cursor.nextAsync() )) != null ) - { - useRecord( record ); - recordsRead.increment(); - } - serversUsed.add( await( cursor.summaryAsync() ).server().address() ); - await( session.closeAsync() ); - } - } ); - } - - private static void testTxRun() throws Throwable - { - test( "Transaction#run()", new Action() - { - @Override - public void apply( Driver driver, MutableInt recordsRead, Set serversUsed ) - { - try ( Session session = driver.session( AccessMode.READ ); - Transaction tx = session.beginTransaction() ) - { - StatementResult result = tx.run( QUERY, PARAMS ); - while ( result.hasNext() ) - { - Record record = result.next(); - useRecord( record ); - recordsRead.increment(); - } - tx.success(); - serversUsed.add( result.summary().server().address() ); - } - } - } ); - } - - private static void testTxRunAsync() throws Throwable - { - test( "Transaction#runAsync()", new Action() - { - @Override - public void apply( Driver driver, MutableInt recordsRead, Set serversUsed ) - { - Session session = driver.session( AccessMode.READ ); - Transaction tx = await( session.beginTransactionAsync() ); - StatementResultCursor cursor = await( tx.runAsync( QUERY, PARAMS ) ); - Record record; - while ( (record = await( cursor.nextAsync() )) != null ) - { - useRecord( record ); - recordsRead.increment(); - } - serversUsed.add( await( cursor.summaryAsync() ).server().address() ); - await( tx.commitAsync() ); - await( session.closeAsync() ); - } - } ); - } - - private static void test( String actionName, Action action ) throws Throwable - { - AuthToken authToken = AuthTokens.basic( USER, PASSWORD ); - Config config = Config.build().withoutEncryption().toConfig(); - - List timings = new ArrayList<>(); - MutableInt recordsRead = new MutableInt(); - ConcurrentSet serversUsed = new ConcurrentSet<>(); - - try ( Driver driver = GraphDatabase.driver( URI, authToken, config ) ) - { - for ( int i = 0; i < ITERATIONS; i++ ) - { - long start = System.nanoTime(); - - action.apply( driver, recordsRead, serversUsed ); - - long end = System.nanoTime(); - timings.add( TimeUnit.NANOSECONDS.toMillis( end - start ) ); - } - } - - timings = clean( timings ); - - System.out.println( "============================================================" ); - System.out.println( actionName + ": mean --> " + mean( timings ) + "ms, stdDev --> " + stdDev( timings ) ); - System.out.println( actionName + ": timings --> " + timings ); - System.out.println( actionName + ": recordsRead --> " + recordsRead ); - System.out.println( actionName + ": serversUsed --> " + serversUsed ); - System.out.println( "============================================================" ); - } - - private static List clean( List timings ) - { - int warmup = timings.size() / 10; // remove first 10% of measurements, they are just a warmup :) - return timings.subList( warmup, timings.size() ); - } - - private static long mean( List timings ) - { - long sum = 0; - for ( Long timing : timings ) - { - sum += timing; - } - return sum / timings.size(); - } - - private static double stdDev( List timings ) - { - long mean = mean( timings ); - long sum = 0; - for ( Long timing : timings ) - { - sum += ((timing - mean) * (timing - mean)); - } - - double squaredDiffMean = sum / timings.size(); - return (Math.sqrt( squaredDiffMean )); - } - - private static T await( CompletionStage stage ) - { - try - { - return stage.toCompletableFuture().get(); - } - catch ( Throwable t ) - { - throw new RuntimeException( t ); - } - } - - private static void useRecord( Record record ) - { - if ( record.keys().size() > 5 ) - { - System.out.println( "Hello" ); - } - - if ( record.get( 0 ).isNull() ) - { - System.out.println( " " ); - } - - if ( record.get( "A" ) == null ) - { - System.out.println( "World" ); - } - -// System.out.println( record ); - } - - private interface Action - { - void apply( Driver driver, MutableInt recordsRead, Set serversUsed ); - } - - private static class MutableInt - { - int value; - - void increment() - { - value++; - } - - @Override - public String toString() - { - return String.valueOf( value ); - } - } -} diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/NettyChannelInitializer.java b/driver/src/main/java/org/neo4j/driver/internal/async/NettyChannelInitializer.java index fe9608f260..64c0c7a433 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/NettyChannelInitializer.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/NettyChannelInitializer.java @@ -25,6 +25,7 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +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; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnection.java b/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnection.java index 9532de17e6..7ae902ac80 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnection.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnection.java @@ -26,6 +26,7 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicBoolean; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.handlers.ResetResponseHandler; import org.neo4j.driver.internal.messaging.Message; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnectionState.java b/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnectionState.java deleted file mode 100644 index 5697370001..0000000000 --- a/driver/src/main/java/org/neo4j/driver/internal/async/NettyConnectionState.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2002-2017 "Neo Technology," - * Network Engine for Objects in Lund AB [http://neotechnology.com] - * - * This file is part of Neo4j. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.neo4j.driver.internal.async; - -import java.util.concurrent.atomic.AtomicInteger; - -public class NettyConnectionState -{ - private final AtomicInteger usageCounter = new AtomicInteger(); - - public boolean markInUse() - { - int current; - do - { - current = usageCounter.get(); - if ( current == -1 ) - { - return false; - } - } - while ( !usageCounter.compareAndSet( current, current + 1 ) ); - return true; - } - - public boolean release() - { - int current; - int next; - do - { - current = usageCounter.get(); - if ( current == -1 ) - { - return false; - } - next = current - 1; - } - while ( !usageCounter.compareAndSet( current, next ) ); - return next == -1; - } - - public boolean forceRelease() - { - int previous = usageCounter.getAndSet( -1 ); - if ( previous == -1 ) - { - return false; - } - else - { - return true; - } - } - - public boolean isInUse() - { - return usageCounter.get() >=0; - } -} diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/QueryRunner.java b/driver/src/main/java/org/neo4j/driver/internal/async/QueryRunner.java index 9097e735ea..bd1f34ed85 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/QueryRunner.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/QueryRunner.java @@ -23,6 +23,7 @@ import java.util.concurrent.CompletionStage; import org.neo4j.driver.internal.ExplicitTransaction; +import org.neo4j.driver.internal.InternalStatementResultCursor; import org.neo4j.driver.internal.handlers.PullAllResponseHandler; import org.neo4j.driver.internal.handlers.RunResponseHandler; import org.neo4j.driver.internal.handlers.SessionPullAllResponseHandler; 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 819d7f56e2..62ae386ebb 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 @@ -23,6 +23,8 @@ import java.util.Objects; import java.util.concurrent.CompletionStage; +import org.neo4j.driver.internal.InternalStatementResultCursor; + import static java.util.concurrent.CompletableFuture.completedFuture; public class ResultCursorsHolder diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/RoutingConnection.java b/driver/src/main/java/org/neo4j/driver/internal/async/RoutingConnection.java index 0c164fd464..78fc44ca51 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/RoutingConnection.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/RoutingConnection.java @@ -21,7 +21,9 @@ import java.util.Map; import java.util.concurrent.CompletionStage; +import org.neo4j.driver.internal.BoltServerAddress; 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 org.neo4j.driver.internal.util.ServerVersion; diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelErrorHandler.java b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChannelErrorHandler.java similarity index 79% rename from driver/src/main/java/org/neo4j/driver/internal/async/ChannelErrorHandler.java rename to driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChannelErrorHandler.java index a82b05b982..283ffc0e80 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/ChannelErrorHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChannelErrorHandler.java @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.neo4j.driver.internal.async; +package org.neo4j.driver.internal.async.inbound; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; @@ -24,7 +24,8 @@ import java.io.IOException; -import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; +import org.neo4j.driver.internal.logging.PrefixedLogger; +import org.neo4j.driver.internal.util.ErrorUtil; import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; import org.neo4j.driver.v1.exceptions.ServiceUnavailableException; @@ -34,42 +35,42 @@ public class ChannelErrorHandler extends ChannelInboundHandlerAdapter { - private final Logger log; + private final Logging logging; private InboundMessageDispatcher messageDispatcher; + private Logger log; private boolean failed; public ChannelErrorHandler( Logging logging ) { - this.log = logging.getLog( getClass().getSimpleName() ); + this.logging = logging; } @Override public void handlerAdded( ChannelHandlerContext ctx ) { messageDispatcher = requireNonNull( messageDispatcher( ctx.channel() ) ); + log = new PrefixedLogger( ctx.channel().toString(), logging, getClass() ); } @Override public void handlerRemoved( ChannelHandlerContext ctx ) { messageDispatcher = null; + log = null; failed = false; } @Override public void channelInactive( ChannelHandlerContext ctx ) { - log.debug( "Channel inactive: %s", ctx.channel() ); + log.debug( "Channel is inactive" ); 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 - ServiceUnavailableException error = new ServiceUnavailableException( - "Connection to the database terminated. " + - "This can happen due to network instabilities, or due to restarts of the database" ); - + ServiceUnavailableException error = ErrorUtil.newConnectionTerminatedError(); fail( ctx, error ); } } @@ -79,12 +80,12 @@ public void exceptionCaught( ChannelHandlerContext ctx, Throwable error ) { if ( failed ) { - log.warn( "Another fatal error in the pipeline of " + ctx.channel(), error ); + log.warn( "Another fatal error occurred in the pipeline", error ); } else { failed = true; - log.error( "Fatal error in the pipeline of " + ctx.channel(), error ); + log.error( "Fatal error occurred in the pipeline", error ); fail( ctx, error ); } } @@ -93,7 +94,7 @@ private void fail( ChannelHandlerContext ctx, Throwable error ) { Throwable cause = transformError( error ); messageDispatcher.handleFatalError( cause ); - log.debug( "Closing channel because of an error: %s", ctx.channel() ); + log.debug( "Closing channel because of a failure '%s'", error ); ctx.close(); } 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 27c1464a0d..7bd0821860 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 @@ -18,8 +18,16 @@ */ package org.neo4j.driver.internal.async.inbound; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; +import org.neo4j.driver.internal.logging.PrefixedLogger; +import org.neo4j.driver.v1.Logger; +import org.neo4j.driver.v1.Logging; + +import static io.netty.buffer.ByteBufUtil.prettyHexDump; + public class ChunkDecoder extends LengthFieldBasedFrameDecoder { private static final int MAX_FRAME_LENGTH = Short.MAX_VALUE; @@ -28,8 +36,38 @@ public class ChunkDecoder extends LengthFieldBasedFrameDecoder private static final int LENGTH_ADJUSTMENT = 0; private static final int INITIAL_BYTES_TO_STRIP = LENGTH_FIELD_LENGTH; - public ChunkDecoder() + 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 ); + this.logging = logging; + } + + @Override + public void handlerAdded( ChannelHandlerContext ctx ) + { + log = new PrefixedLogger( ctx.channel().toString(), logging, getClass() ); + } + + @Override + protected void handlerRemoved0( ChannelHandlerContext ctx ) + { + log = null; + } + + @Override + 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 + buffer.readableBytes(); + String hexDump = prettyHexDump( buffer, readerIndexWithChunkHeader, lengthWithChunkHeader ); + log.trace( "S:\n%s", hexDump ); + } + return super.extractFrame( ctx, buffer, index, length ); } } 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 dd74dacf2a..0549ba09b7 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 @@ -26,6 +26,7 @@ import java.util.Queue; import org.neo4j.driver.internal.handlers.AckFailureResponseHandler; +import org.neo4j.driver.internal.logging.PrefixedLogger; import org.neo4j.driver.internal.messaging.MessageHandler; import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.internal.util.ErrorUtil; @@ -49,7 +50,7 @@ public class InboundMessageDispatcher implements MessageHandler public InboundMessageDispatcher( Channel channel, Logging logging ) { this.channel = requireNonNull( channel ); - this.log = logging.getLog( getClass().getSimpleName() ); + this.log = new PrefixedLogger( channel.toString(), logging, getClass() ); } public void queue( ResponseHandler handler ) @@ -112,8 +113,8 @@ public void handleAckFailureMessage() @Override public void handleSuccessMessage( Map meta ) { + log.debug( "S: SUCCESS %s", meta ); ResponseHandler handler = handlers.remove(); - log.debug( "Received SUCCESS message with metadata %s for handler %s", meta, handler ); handler.onSuccess( meta ); } @@ -122,7 +123,7 @@ public void handleRecordMessage( Value[] fields ) { if ( log.isDebugEnabled() ) { - log.debug( "Received RECORD message with metadata %s", Arrays.toString( fields ) ); + log.debug( "S: RECORD %s", Arrays.toString( fields ) ); } ResponseHandler handler = handlers.peek(); handler.onRecord( fields ); @@ -131,7 +132,8 @@ public void handleRecordMessage( Value[] fields ) @Override public void handleFailureMessage( String code, String message ) { - log.debug( "Received FAILURE message with code '%s' and message '%s'", code, message ); + log.debug( "S: FAILURE %s \"%s\"", code, message ); + currentError = ErrorUtil.newNeo4jError( code, message ); if ( ErrorUtil.isFatal( currentError ) ) @@ -152,8 +154,9 @@ public void handleFailureMessage( String code, String message ) @Override public void handleIgnoredMessage() { + log.debug( "S: IGNORED" ); + ResponseHandler handler = handlers.remove(); - log.debug( "Received IGNORED message for handler %s", handler ); if ( currentError != null ) { handler.onFailure( currentError ); @@ -166,8 +169,6 @@ public void handleIgnoredMessage() public void handleFatalError( Throwable error ) { - log.warn( "Fatal error occurred", error ); - currentError = error; fatalErrorOccurred = true; 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 b586129a09..8bab421666 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 @@ -23,6 +23,7 @@ import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.DecoderException; +import org.neo4j.driver.internal.logging.PrefixedLogger; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; @@ -35,27 +36,30 @@ public class InboundMessageHandler extends SimpleChannelInboundHandler { private final ByteBufInput input; private final MessageFormat.Reader reader; - private final Logger log; + private final Logging logging; private InboundMessageDispatcher messageDispatcher; + private Logger log; public InboundMessageHandler( MessageFormat messageFormat, Logging logging ) { this.input = new ByteBufInput(); this.reader = messageFormat.newReader( input ); - this.log = logging.getLog( getClass().getSimpleName() ); + this.logging = logging; } @Override public void handlerAdded( ChannelHandlerContext ctx ) { messageDispatcher = requireNonNull( messageDispatcher( ctx.channel() ) ); + log = new PrefixedLogger( ctx.channel().toString(), logging, getClass() ); } @Override public void handlerRemoved( ChannelHandlerContext ctx ) { messageDispatcher = null; + log = null; } @Override @@ -63,14 +67,14 @@ 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\n", + log.warn( "Message ignored because of the previous fatal error. Channel will be closed. Message:\n%s", prettyHexDump( msg ) ); return; } if ( log.isTraceEnabled() ) { - log.trace( "Inbound message received:\n%s\n", prettyHexDump( msg ) ); + log.trace( "S:\n%s", prettyHexDump( msg ) ); } input.start( msg ); 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 05bc216309..70018c2b38 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 @@ -25,6 +25,7 @@ import java.util.List; +import org.neo4j.driver.internal.logging.PrefixedLogger; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageFormat; import org.neo4j.driver.v1.Logger; @@ -40,25 +41,39 @@ public class OutboundMessageHandler extends MessageToMessageEncoder private final MessageFormat messageFormat; private final ChunkAwareByteBufOutput output; private final MessageFormat.Writer writer; - private final Logger log; + private final Logging logging; + + private Logger log; public OutboundMessageHandler( MessageFormat messageFormat, Logging logging ) { - this( messageFormat, true, logging.getLog( NAME ) ); + this( messageFormat, true, logging ); } - private OutboundMessageHandler( MessageFormat messageFormat, boolean byteArraySupportEnabled, Logger log ) + private OutboundMessageHandler( MessageFormat messageFormat, boolean byteArraySupportEnabled, Logging logging ) { this.messageFormat = messageFormat; this.output = new ChunkAwareByteBufOutput(); this.writer = messageFormat.newWriter( output, byteArraySupportEnabled ); - this.log = log; + this.logging = logging; + } + + @Override + public void handlerAdded( ChannelHandlerContext ctx ) + { + log = new PrefixedLogger( ctx.channel().toString(), logging, getClass() ); + } + + @Override + public void handlerRemoved( ChannelHandlerContext ctx ) + { + log = null; } @Override protected void encode( ChannelHandlerContext ctx, Message msg, List out ) { - log.debug( "Sending message %s", msg ); + log.debug( "C: %s", msg ); ByteBuf messageBuf = ctx.alloc().ioBuffer(); output.start( messageBuf ); @@ -77,7 +92,7 @@ protected void encode( ChannelHandlerContext ctx, Message msg, List out if ( log.isTraceEnabled() ) { - log.trace( "Message %s encoded as\n%s\n", msg, prettyHexDump( messageBuf ) ); + log.trace( "C:\n%s", prettyHexDump( messageBuf ) ); } out.add( messageBuf ); @@ -86,6 +101,6 @@ protected void encode( ChannelHandlerContext ctx, Message msg, List out public OutboundMessageHandler withoutByteArraySupport() { - return new OutboundMessageHandler( messageFormat, false, log ); + return new OutboundMessageHandler( messageFormat, false, logging ); } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ActiveChannelTracker.java b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ActiveChannelTracker.java index 0400a74915..81741b45a0 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/ActiveChannelTracker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/ActiveChannelTracker.java @@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; 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 0b576cdd95..66299e9b37 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 @@ -24,6 +24,7 @@ import io.netty.channel.pool.ChannelPool; import io.netty.util.concurrent.Future; +import java.util.Map; import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionStage; import java.util.concurrent.ConcurrentHashMap; @@ -31,7 +32,7 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.ChannelConnector; import org.neo4j.driver.internal.async.NettyConnection; import org.neo4j.driver.internal.spi.Connection; @@ -61,16 +62,16 @@ public ConnectionPoolImpl( ChannelConnector connector, Bootstrap bootstrap, Pool this.connector = connector; this.bootstrap = bootstrap; this.activeChannelTracker = new ActiveChannelTracker( logging ); - this.channelHealthChecker = new NettyChannelHealthChecker( settings, clock ); + this.channelHealthChecker = new NettyChannelHealthChecker( settings, clock, logging ); this.settings = settings; this.clock = clock; - this.log = logging.getLog( getClass().getSimpleName() ); + this.log = logging.getLog( ConnectionPool.class.getSimpleName() ); } @Override - public CompletionStage acquire( final BoltServerAddress address ) + public CompletionStage acquire( BoltServerAddress address ) { - log.debug( "Acquiring connection from pool for address: %s", address ); + log.debug( "Acquiring connection from pool towards %s", address ); assertNotClosed(); ChannelPool pool = getOrCreatePool( address ); @@ -87,7 +88,7 @@ public CompletionStage acquire( final BoltServerAddress address ) @Override public void purge( BoltServerAddress address ) { - log.info( "Purging connections for address: %s", address ); + log.info( "Purging connections towards %s", address ); // purge active connections activeChannelTracker.purge( address ); @@ -117,11 +118,14 @@ public CompletionStage close() { if ( closed.compareAndSet( false, true ) ) { - log.info( "Closing the connection pool" ); try { - for ( ChannelPool pool : pools.values() ) + for ( Map.Entry entry : pools.entrySet() ) { + BoltServerAddress address = entry.getKey(); + ChannelPool pool = entry.getValue(); + + log.info( "Closing connection pool towards %s", address ); pool.close(); } 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 d5085c4164..c324c59f08 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthChecker.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelHealthChecker.java @@ -26,8 +26,9 @@ import org.neo4j.driver.internal.handlers.PingResponseHandler; import org.neo4j.driver.internal.messaging.ResetMessage; import org.neo4j.driver.internal.util.Clock; +import org.neo4j.driver.v1.Logger; +import org.neo4j.driver.v1.Logging; -import static java.util.Objects.requireNonNull; import static org.neo4j.driver.internal.async.ChannelAttributes.creationTimestamp; import static org.neo4j.driver.internal.async.ChannelAttributes.lastUsedTimestamp; import static org.neo4j.driver.internal.async.ChannelAttributes.messageDispatcher; @@ -36,11 +37,13 @@ public class NettyChannelHealthChecker implements ChannelHealthChecker { private final PoolSettings poolSettings; private final Clock clock; + private final Logger log; - public NettyChannelHealthChecker( PoolSettings poolSettings, Clock clock ) + public NettyChannelHealthChecker( PoolSettings poolSettings, Clock clock, Logging logging ) { - this.poolSettings = requireNonNull( poolSettings ); - this.clock = requireNonNull( clock ); + this.poolSettings = poolSettings; + this.clock = clock; + this.log = logging.getLog( getClass().getSimpleName() ); } @Override @@ -63,9 +66,16 @@ private boolean isTooOld( Channel channel ) { long creationTimestampMillis = creationTimestamp( channel ); long currentTimestampMillis = clock.millis(); + long ageMillis = currentTimestampMillis - creationTimestampMillis; + long maxAgeMillis = poolSettings.maxConnectionLifetime(); + + boolean tooOld = ageMillis > maxAgeMillis; + + log.trace( "Can't acquire channel %s from the pool because it is too old: %s > %s", + channel, ageMillis, maxAgeMillis ); - return ageMillis > poolSettings.maxConnectionLifetime(); + return tooOld; } return false; } @@ -78,7 +88,11 @@ private boolean hasBeenIdleForTooLong( Channel channel ) if ( lastUsedTimestamp != null ) { long idleTime = clock.millis() - lastUsedTimestamp; - return idleTime > poolSettings.idleTimeBeforeConnectionTest(); + boolean idleTooLong = idleTime > poolSettings.idleTimeBeforeConnectionTest(); + + log.trace( "Channel %s has been idle for %s and needs a ping", channel, idleTime ); + + return idleTooLong; } } return false; @@ -87,7 +101,7 @@ private boolean hasBeenIdleForTooLong( Channel channel ) private Future ping( Channel channel ) { Promise result = channel.eventLoop().newPromise(); - messageDispatcher( channel ).queue( new PingResponseHandler( result ) ); + messageDispatcher( channel ).queue( new PingResponseHandler( result, channel, log ) ); 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 b643010543..2024465743 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 @@ -24,7 +24,7 @@ import io.netty.channel.pool.ChannelPoolHandler; import io.netty.channel.pool.FixedChannelPool; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.ChannelConnector; import static java.util.Objects.requireNonNull; diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/AddressSet.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/AddressSet.java index 04cf6fd355..5f6fc0bfc2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/AddressSet.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/AddressSet.java @@ -21,7 +21,7 @@ import java.util.Arrays; import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; public class AddressSet { 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 9b9e4d9a56..3fa6227988 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,7 +22,7 @@ import java.util.Objects; import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.Record; import org.neo4j.driver.v1.Value; import org.neo4j.driver.v1.util.Function; 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 1218f4738f..83e9b4b7f3 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 @@ -23,7 +23,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.v1.AccessMode; diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/DnsResolver.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/DnsResolver.java index 6b20c1dd02..4c28630842 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/DnsResolver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/DnsResolver.java @@ -23,7 +23,7 @@ import java.util.HashSet; import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.Logger; public class DnsResolver implements HostNameResolver diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/HostNameResolver.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/HostNameResolver.java index b33efcfeb9..a8cf803466 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/HostNameResolver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/HostNameResolver.java @@ -20,7 +20,7 @@ import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; public interface HostNameResolver { 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 e1c9463148..fa2c41ef47 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 @@ -28,7 +28,7 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeUnit; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.internal.util.Futures; @@ -232,9 +232,7 @@ private CompletionStage lookupOnRouter( BoltServerAddress ro } else { - ClusterComposition cluster = response.clusterComposition(); - logger.info( "Got cluster composition %s", cluster ); - return cluster; + return response.clusterComposition(); } } ); } 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 c575148770..75c9fa71bc 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 @@ -72,8 +72,8 @@ private ClusterCompositionResponse processRoutingResponse( RoutingProcedureRespo } List records = response.records(); + log.info( "Received response from %s procedure: %s", invokedProcedureString( response ), records ); - log.info( "Got getServers response: %s", records ); long now = clock.millis(); // the record size is wrong 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 400e7d4879..859920f071 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,7 +20,7 @@ import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.AccessMode; public interface RoutingTable 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 4ecd4691e0..333045431d 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 @@ -18,7 +18,7 @@ */ package org.neo4j.driver.internal.cluster.loadbalancing; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; 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 4988bf6b3d..a89b9bd8aa 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 @@ -24,8 +24,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.RoutingErrorHandler; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.async.RoutingConnection; import org.neo4j.driver.internal.cluster.AddressSet; import org.neo4j.driver.internal.cluster.ClusterComposition; 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 7d145e6023..e446d6d48b 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 @@ -18,7 +18,7 @@ */ package org.neo4j.driver.internal.cluster.loadbalancing; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; /** * A facility to select most appropriate reader or writer among the given addresses for request processing. diff --git a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinLoadBalancingStrategy.java b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinLoadBalancingStrategy.java index 06294a86b1..6d2f4af361 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinLoadBalancingStrategy.java +++ b/driver/src/main/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinLoadBalancingStrategy.java @@ -18,7 +18,7 @@ */ package org.neo4j.driver.internal.cluster.loadbalancing; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; 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 b98581c423..d1e499d4fa 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 @@ -18,33 +18,39 @@ */ package org.neo4j.driver.internal.handlers; +import io.netty.channel.Channel; import io.netty.util.concurrent.Promise; import java.util.Map; import org.neo4j.driver.internal.spi.ResponseHandler; +import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Value; -import static java.util.Objects.requireNonNull; - public class PingResponseHandler implements ResponseHandler { private final Promise result; + private final Channel channel; + private final Logger log; - public PingResponseHandler( Promise result ) + public PingResponseHandler( Promise result, Channel channel, Logger log ) { - this.result = requireNonNull( result ); + this.result = result; + this.channel = channel; + this.log = log; } @Override 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 ); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/RoutingResponseHandler.java b/driver/src/main/java/org/neo4j/driver/internal/handlers/RoutingResponseHandler.java similarity index 98% rename from driver/src/main/java/org/neo4j/driver/internal/async/RoutingResponseHandler.java rename to driver/src/main/java/org/neo4j/driver/internal/handlers/RoutingResponseHandler.java index 8d01c2b1e6..6e11e16daf 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/RoutingResponseHandler.java +++ b/driver/src/main/java/org/neo4j/driver/internal/handlers/RoutingResponseHandler.java @@ -16,12 +16,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.neo4j.driver.internal.async; +package org.neo4j.driver.internal.handlers; import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletionException; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.RoutingErrorHandler; import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.internal.util.Futures; diff --git a/driver/src/main/java/org/neo4j/driver/internal/logging/DelegatingLogger.java b/driver/src/main/java/org/neo4j/driver/internal/logging/PrefixedLogger.java similarity index 83% rename from driver/src/main/java/org/neo4j/driver/internal/logging/DelegatingLogger.java rename to driver/src/main/java/org/neo4j/driver/internal/logging/PrefixedLogger.java index 83d74e69e8..540df9df1e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/logging/DelegatingLogger.java +++ b/driver/src/main/java/org/neo4j/driver/internal/logging/PrefixedLogger.java @@ -19,20 +19,26 @@ package org.neo4j.driver.internal.logging; import org.neo4j.driver.v1.Logger; +import org.neo4j.driver.v1.Logging; import static java.util.Objects.requireNonNull; -public class DelegatingLogger implements Logger +public class PrefixedLogger implements Logger { private final Logger delegate; private final String messagePrefix; - public DelegatingLogger( Logger delegate ) + public PrefixedLogger( Logger delegate ) { - this( delegate, null ); + this( null, delegate ); } - public DelegatingLogger( Logger delegate, String messagePrefix ) + public PrefixedLogger( String messagePrefix, Logging logging, Class owner ) + { + this( messagePrefix, logging.getLog( owner.getSimpleName() ) ); + } + + public PrefixedLogger( String messagePrefix, Logger delegate ) { this.delegate = requireNonNull( delegate ); this.messagePrefix = messagePrefix; @@ -98,6 +104,6 @@ private String messageWithPrefix( String message ) { 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/messaging/AckFailureMessage.java b/driver/src/main/java/org/neo4j/driver/internal/messaging/AckFailureMessage.java index ee423e9d8f..6fe845a184 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/messaging/AckFailureMessage.java +++ b/driver/src/main/java/org/neo4j/driver/internal/messaging/AckFailureMessage.java @@ -39,7 +39,7 @@ public void dispatch( MessageHandler handler ) throws IOException @Override public String toString() { - return "[ACK_FAILURE]"; + return "ACK_FAILURE"; } @Override 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 77d7353c40..49cb6d20d0 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 @@ -18,13 +18,6 @@ */ package org.neo4j.driver.internal.security; -import org.neo4j.driver.internal.async.BoltServerAddress; -import org.neo4j.driver.v1.*; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; import java.io.File; import java.io.IOException; import java.security.GeneralSecurityException; @@ -32,6 +25,13 @@ import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import org.neo4j.driver.internal.BoltServerAddress; +import org.neo4j.driver.v1.Logger; import static org.neo4j.driver.internal.util.CertificateTool.loadX509Cert; diff --git a/driver/src/main/java/org/neo4j/driver/internal/security/TrustOnFirstUseTrustManager.java b/driver/src/main/java/org/neo4j/driver/internal/security/TrustOnFirstUseTrustManager.java index f18e66bbbd..9e5de04c47 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/security/TrustOnFirstUseTrustManager.java +++ b/driver/src/main/java/org/neo4j/driver/internal/security/TrustOnFirstUseTrustManager.java @@ -18,6 +18,8 @@ */ package org.neo4j.driver.internal.security; +import io.netty.buffer.ByteBufUtil; + import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -30,8 +32,7 @@ import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; -import org.neo4j.driver.internal.async.BoltServerAddress; -import org.neo4j.driver.internal.util.BytePrinter; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.Logger; import static java.lang.String.format; @@ -202,7 +203,7 @@ public static String fingerprint( X509Certificate cert ) throws CertificateExcep { MessageDigest md = MessageDigest.getInstance( "SHA-512" ); md.update( cert.getEncoded() ); - return BytePrinter.compactHex( md.digest() ); + return ByteBufUtil.hexDump( md.digest() ); } catch( NoSuchAlgorithmException e ) { 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 e3d2aeaab8..a344aef336 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 @@ -21,7 +21,7 @@ import java.util.Map; import java.util.concurrent.CompletionStage; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.v1.Value; 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 2c18176016..e6a215756c 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,7 +20,7 @@ import java.util.concurrent.CompletionStage; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; public interface ConnectionPool { 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 6247dec107..482a97595c 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,7 +19,7 @@ package org.neo4j.driver.internal.summary; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.v1.summary.ServerInfo; diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/BytePrinter.java b/driver/src/main/java/org/neo4j/driver/internal/util/BytePrinter.java deleted file mode 100644 index 0b3401cf91..0000000000 --- a/driver/src/main/java/org/neo4j/driver/internal/util/BytePrinter.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2002-2017 "Neo Technology," - * Network Engine for Objects in Lund AB [http://neotechnology.com] - * - * This file is part of Neo4j. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.neo4j.driver.internal.util; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; - -import static java.nio.ByteBuffer.wrap; - -public class BytePrinter -{ - /** - * Print a full byte array as nicely formatted groups of hex numbers. - * Output looks like: - *

- * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - */ - public static void print( byte[] bytes, PrintStream out ) - { - print( wrap( bytes ), out, 0, bytes.length ); - } - - /** - * Print a full byte buffer as nicely formatted groups of hex numbers. - * Output looks like: - *

- * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * - * @param bytes - * @param out - */ - public static void print( ByteBuffer bytes, PrintStream out ) - { - print( bytes, out, 0, bytes.limit() ); - } - - /** - * Print a subsection of a byte buffer as nicely formatted groups of hex numbers. - * Output looks like: - *

- * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * - * @param bytes - * @param out - */ - public static void print( ByteBuffer bytes, PrintStream out, int offset, int length ) - { - for ( int i = offset; i < offset + length; i++ ) - { - print( bytes.get( i ), out ); - if ( (i - offset + 1) % 32 == 0 ) - { - out.println(); - } - else if ( (i - offset + 1) % 8 == 0 ) - { - out.print( " " ); - } - else - { - out.print( " " ); - } - } - } - - /** - * Print a single byte as a hex number. The number will always be two characters wide. - * - * @param b - * @param out - */ - public static void print( byte b, PrintStream out ) - { - out.print( hex( b ) ); - } - - /** - * This should not be in this class, move to a dedicated ascii-art class when appropriate. - *

- * Use this to standardize the width of some text output to all be left-justified and space-padded - * on the right side to fill up the given column width. - * - * @param str - * @param columnWidth - * @return - */ - public static String ljust( String str, int columnWidth ) - { - return String.format( "%-" + columnWidth + "s", str ); - } - - /** - * This should not be in this class, move to a dedicated ascii-art class when appropriate. - *

- * Use this to standardize the width of some text output to all be right-justified and space-padded - * on the left side to fill up the given column width. - * - * @param str - * @param columnWidth - * @return - */ - public static String rjust( String str, int columnWidth ) - { - return String.format( "%" + columnWidth + "s", str ); - } - - /** - * Convert a single byte to a human-readable hex number. The number will always be two characters wide. - * - * @param b - * @return - */ - public static String hex( byte b ) - { - return String.format( "%02x", b ); - } - - /** - * Convert a subsection of a byte buffer to a human readable string of nicely formatted hex numbers. - * Output looks like: - *

- * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * - * @param bytes - * @param offset - * @param length - * @return - */ - public static String hex( ByteBuffer bytes, int offset, int length ) - { - try - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintStream ps; - ps = new PrintStream( baos, true, "UTF-8" ); - print( bytes, ps, offset, length ); - return baos.toString( "UTF-8" ); - } - catch ( UnsupportedEncodingException e ) - { - throw new RuntimeException( e ); - } - } - - /** - * Convert a full byte buffer from 0 to position to a human readable string of nicely formatted hex numbers. - * Output looks like: - *

- * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * - * @param bytes - * @return - */ - public static String hex( ByteBuffer bytes ) - { - return hex( bytes, 0, bytes.position() ); - } - - /** - * Convert a full byte buffer to a human readable string of nicely formatted hex numbers. - * Output looks like: - *

- * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 - * - * @param bytes - * @return - */ - public static String hex( byte[] bytes ) - { - return hex( wrap( bytes ), 0, bytes.length ); - } - - /** - * Convert a full byte buffer to a human readable string of nicely formatted hex numbers. - * Output looks like: - *

- * 0102030405060708 - * - * @param bytes - * @return - */ - public static String compactHex( byte[] bytes ) - { - StringBuilder sb = new StringBuilder(); - for ( byte b : bytes ) - { - sb.append( hex(b) ); - } - return sb.toString(); - } - - public static byte[] hexStringToBytes( String s ) - { - int len = s.length(); - ByteArrayOutputStream data = new ByteArrayOutputStream( 1024 ); - for ( int i = 0; i < len; ) - { - int firstDigit = Character.digit( s.charAt( i ), 16 ); - if ( firstDigit != -1 ) - { - int secondDigit = Character.digit( s.charAt( i + 1 ), 16 ); - int toWrite = (firstDigit << 4) + secondDigit; - data.write( toWrite ); - i += 2; - } - else - { - i += 1; - } - } - return data.toByteArray(); - } - - public static String hexInOneLine( ByteBuffer bytes, int offset, int length ) - { - try - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintStream out; - out = new PrintStream( baos, true, "UTF-8" ); - for ( int i = offset; i < offset + length; i++ ) - { - print( bytes.get( i ), out ); - if ( i == offset + length - 1 ) - { - // no pending blanks - } - else if ( (i - offset + 1) % 8 == 0 ) - { - out.print( " " ); - } - else - { - out.print( " " ); - } - } - return baos.toString( "UTF-8" ); - } - catch ( UnsupportedEncodingException e ) - { - throw new RuntimeException( e ); - } - } -} 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 caa40a807f..e25512bc3d 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 @@ -22,6 +22,7 @@ import org.neo4j.driver.v1.exceptions.ClientException; import org.neo4j.driver.v1.exceptions.DatabaseException; import org.neo4j.driver.v1.exceptions.Neo4jException; +import org.neo4j.driver.v1.exceptions.ServiceUnavailableException; import org.neo4j.driver.v1.exceptions.TransientException; public final class ErrorUtil @@ -30,6 +31,13 @@ private ErrorUtil() { } + public static ServiceUnavailableException newConnectionTerminatedError() + { + return new ServiceUnavailableException( "Connection to the database terminated. " + + "This can happen due to network instabilities, " + + "or due to restarts of the database" ); + } + public static Neo4jException newNeo4jError( String code, String message ) { String classification = extractClassification( code ); 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 5ae36752a4..df053ec562 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DirectConnectionProviderTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DirectConnectionProviderTest.java @@ -23,7 +23,6 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.spi.ConnectionPool; diff --git a/driver/src/test/java/org/neo4j/driver/internal/DirectDriverTest.java b/driver/src/test/java/org/neo4j/driver/internal/DirectDriverTest.java index c9314b026c..3f3e0adee9 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DirectDriverTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DirectDriverTest.java @@ -26,7 +26,6 @@ import java.util.Arrays; import java.util.List; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.v1.Driver; import org.neo4j.driver.v1.GraphDatabase; @@ -42,7 +41,7 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; -import static org.neo4j.driver.internal.async.BoltServerAddress.LOCAL_DEFAULT; +import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; import static org.neo4j.driver.internal.util.Matchers.directDriverWithAddress; import static org.neo4j.driver.v1.Values.parameters; import static org.neo4j.driver.v1.util.StubServer.INSECURE_CONFIG; 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 98bd6023e0..4b9a47a055 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java @@ -30,7 +30,6 @@ import java.util.Arrays; import java.util.List; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.cluster.RoutingSettings; import org.neo4j.driver.internal.cluster.loadbalancing.LoadBalancer; import org.neo4j.driver.internal.retry.RetryLogic; @@ -167,7 +166,7 @@ private static class ThrowingDriverFactory extends DriverFactory } @Override - protected InternalDriver createDriver( Config config, SecurityPlan securityPlan, SessionFactory sessionFactory ) + protected InternalDriver createDriver( SessionFactory sessionFactory, SecurityPlan securityPlan, Config config ) { throw new UnsupportedOperationException( "Can't create direct driver" ); } @@ -193,7 +192,7 @@ private static class SessionFactoryCapturingDriverFactory extends DriverFactory SessionFactory capturedSessionFactory; @Override - protected InternalDriver createDriver( Config config, SecurityPlan securityPlan, SessionFactory sessionFactory ) + protected InternalDriver createDriver( SessionFactory sessionFactory, SecurityPlan securityPlan, Config config ) { InternalDriver driver = mock( InternalDriver.class ); when( driver.verifyConnectivity() ).thenReturn( completedFuture( null ) ); 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 148b09380e..bc618a839d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.internal.util.Futures.getBlocking; public class InternalDriverTest @@ -56,7 +57,7 @@ public void shouldNotCloseSessionFactoryMultipleTimes() private static InternalDriver newDriver( SessionFactory sessionFactory ) { - return new InternalDriver( SecurityPlan.insecure(), sessionFactory ); + return new InternalDriver( SecurityPlan.insecure(), sessionFactory, DEV_NULL_LOGGING ); } private static SessionFactory sessionFactoryMock() diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalStatementResultTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalStatementResultTest.java index a5d3dbeffc..a044ecf163 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalStatementResultTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalStatementResultTest.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.neo4j.driver.internal.async.InternalStatementResultCursor; import org.neo4j.driver.internal.handlers.PullAllResponseHandler; import org.neo4j.driver.internal.handlers.RunResponseHandler; import org.neo4j.driver.internal.handlers.SessionPullAllResponseHandler; @@ -55,7 +54,7 @@ import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.neo4j.driver.internal.async.BoltServerAddress.LOCAL_DEFAULT; +import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; import static org.neo4j.driver.v1.Records.column; import static org.neo4j.driver.v1.Values.ofString; import static org.neo4j.driver.v1.Values.value; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelAttributesTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelAttributesTest.java index 5e84d3c13f..ab7a8d7038 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelAttributesTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelAttributesTest.java @@ -21,6 +21,7 @@ import io.netty.channel.embedded.EmbeddedChannel; import org.junit.Test; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.util.ServerVersion; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelConnectedListenerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelConnectedListenerTest.java index d3fdbf1fa3..c7a23de0d9 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelConnectedListenerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelConnectedListenerTest.java @@ -33,7 +33,7 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.neo4j.driver.internal.async.BoltServerAddress.LOCAL_DEFAULT; +import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; import static org.neo4j.driver.internal.async.ProtocolUtil.handshake; import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.v1.util.TestUtil.await; @@ -83,7 +83,7 @@ public void shouldWriteHandshakeWhenChannelConnected() listener.operationComplete( channelConnectedPromise ); - assertNotNull( channel.pipeline().get( HandshakeResponseHandler.class ) ); + assertNotNull( channel.pipeline().get( HandshakeHandler.class ) ); assertTrue( channel.finish() ); assertEquals( handshake(), channel.readOutbound() ); } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelConnectorImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelConnectorImplTest.java index 69b8e08e44..3aaf496c50 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelConnectorImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelConnectorImplTest.java @@ -30,6 +30,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.ConnectionSettings; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.util.FakeClock; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelErrorHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelErrorHandlerTest.java index 9ea766ee9f..fd4e522c04 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelErrorHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelErrorHandlerTest.java @@ -26,6 +26,7 @@ import java.io.IOException; +import org.neo4j.driver.internal.async.inbound.ChannelErrorHandler; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.v1.exceptions.ServiceUnavailableException; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelPipelineBuilderImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelPipelineBuilderImplTest.java index 5953854b32..f5c3800d3f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/ChannelPipelineBuilderImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/ChannelPipelineBuilderImplTest.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.Map; +import org.neo4j.driver.internal.async.inbound.ChannelErrorHandler; import org.neo4j.driver.internal.async.inbound.ChunkDecoder; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.async.inbound.InboundMessageHandler; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/HandshakeResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/HandshakeHandlerTest.java similarity index 55% rename from driver/src/test/java/org/neo4j/driver/internal/async/HandshakeResponseHandlerTest.java rename to driver/src/test/java/org/neo4j/driver/internal/async/HandshakeHandlerTest.java index b4acd812a3..f05f16026a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/HandshakeResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/HandshakeHandlerTest.java @@ -20,16 +20,23 @@ import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.handler.codec.DecoderException; import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.io.IOException; +import javax.net.ssl.SSLHandshakeException; + import org.neo4j.driver.internal.async.inbound.ChunkDecoder; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; 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.util.ErrorUtil; import org.neo4j.driver.v1.exceptions.ClientException; +import org.neo4j.driver.v1.exceptions.SecurityException; +import org.neo4j.driver.v1.exceptions.ServiceUnavailableException; import static io.netty.buffer.Unpooled.copyInt; import static org.hamcrest.Matchers.instanceOf; @@ -46,7 +53,7 @@ import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.v1.util.TestUtil.await; -public class HandshakeResponseHandlerTest +public class HandshakeHandlerTest { private final EmbeddedChannel channel = new EmbeddedChannel(); @@ -66,7 +73,7 @@ public void tearDown() public void shouldFailGivenPromiseWhenExceptionCaught() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeResponseHandler handler = newHandler( handshakeCompletedPromise ); + HandshakeHandler handler = newHandler( handshakeCompletedPromise ); channel.pipeline().addLast( handler ); RuntimeException cause = new RuntimeException( "Error!" ); @@ -87,17 +94,104 @@ public void shouldFailGivenPromiseWhenExceptionCaught() assertNull( await( channel.closeFuture() ) ); } + @Test + public void shouldFailGivenPromiseWhenMultipleExceptionsCaught() + { + ChannelPromise handshakeCompletedPromise = channel.newPromise(); + 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 ); + + try + { + // promise should fail + await( handshakeCompletedPromise ); + fail( "Exception expected" ); + } + catch ( RuntimeException e ) + { + assertEquals( error1, e ); + } + + // channel should be closed + assertNull( await( channel.closeFuture() ) ); + + try + { + channel.checkException(); + fail( "Exception expected" ); + } + catch ( RuntimeException e ) + { + assertEquals( error2, e ); + } + } + + @Test + public void shouldUnwrapDecoderException() + { + ChannelPromise handshakeCompletedPromise = channel.newPromise(); + HandshakeHandler handler = newHandler( handshakeCompletedPromise ); + channel.pipeline().addLast( handler ); + + IOException cause = new IOException( "Error!" ); + channel.pipeline().fireExceptionCaught( new DecoderException( cause ) ); + + try + { + // promise should fail + await( handshakeCompletedPromise ); + fail( "Exception expected" ); + } + catch ( Exception e ) + { + assertEquals( cause, e ); + } + + // channel should be closed + assertNull( await( channel.closeFuture() ) ); + } + + @Test + public void shouldTranslateSSLHandshakeException() + { + ChannelPromise handshakeCompletedPromise = channel.newPromise(); + HandshakeHandler handler = newHandler( handshakeCompletedPromise ); + channel.pipeline().addLast( handler ); + + SSLHandshakeException error = new SSLHandshakeException( "Invalid certificate" ); + channel.pipeline().fireExceptionCaught( error ); + + try + { + // promise should fail + await( handshakeCompletedPromise ); + fail( "Exception expected" ); + } + catch ( SecurityException e ) + { + assertEquals( error, e.getCause() ); + } + + // channel should be closed + assertNull( await( channel.closeFuture() ) ); + } + @Test public void shouldSelectProtocolV1WhenServerSuggests() { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeResponseHandler handler = newHandler( handshakeCompletedPromise ); + HandshakeHandler handler = newHandler( handshakeCompletedPromise ); channel.pipeline().addLast( handler ); channel.pipeline().fireChannelRead( copyInt( PROTOCOL_VERSION_1 ) ); // handshake handler itself should be removed - assertNull( channel.pipeline().get( HandshakeResponseHandler.class ) ); + assertNull( channel.pipeline().get( HandshakeHandler.class ) ); // all inbound handlers should be set assertNotNull( channel.pipeline().get( ChunkDecoder.class ) ); @@ -129,16 +223,40 @@ public void shouldFailGivenPromiseWhenServerSuggestsUnknownProtocol() testFailure( 42, "Protocol error" ); } + @Test + public void shouldFailGivenPromiseWhenChannelInactive() + { + ChannelPromise handshakeCompletedPromise = channel.newPromise(); + HandshakeHandler handler = newHandler( handshakeCompletedPromise ); + channel.pipeline().addLast( handler ); + + channel.pipeline().fireChannelInactive(); + + try + { + // promise should fail + await( handshakeCompletedPromise ); + fail( "Exception expected" ); + } + catch ( ServiceUnavailableException e ) + { + assertEquals( ErrorUtil.newConnectionTerminatedError().getMessage(), e.getMessage() ); + } + + // channel should be closed + assertNull( await( channel.closeFuture() ) ); + } + private void testFailure( int serverSuggestedVersion, String expectedMessagePrefix ) { ChannelPromise handshakeCompletedPromise = channel.newPromise(); - HandshakeResponseHandler handler = newHandler( handshakeCompletedPromise ); + HandshakeHandler handler = newHandler( handshakeCompletedPromise ); channel.pipeline().addLast( handler ); channel.pipeline().fireChannelRead( copyInt( serverSuggestedVersion ) ); // handshake handler itself should be removed - assertNull( channel.pipeline().get( HandshakeResponseHandler.class ) ); + assertNull( channel.pipeline().get( HandshakeHandler.class ) ); try { @@ -156,9 +274,9 @@ private void testFailure( int serverSuggestedVersion, String expectedMessagePref assertNull( await( channel.closeFuture() ) ); } - private static HandshakeResponseHandler newHandler( ChannelPromise handshakeCompletedPromise ) + private static HandshakeHandler newHandler( ChannelPromise handshakeCompletedPromise ) { - return new HandshakeResponseHandler( new ChannelPipelineBuilderImpl(), handshakeCompletedPromise, + return new HandshakeHandler( new ChannelPipelineBuilderImpl(), handshakeCompletedPromise, DEV_NULL_LOGGING ); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/NettyChannelInitializerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/NettyChannelInitializerTest.java index c1232b31b5..3c6491d317 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/NettyChannelInitializerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/NettyChannelInitializerTest.java @@ -32,7 +32,7 @@ import static org.junit.Assert.assertNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.neo4j.driver.internal.async.BoltServerAddress.LOCAL_DEFAULT; +import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; import static org.neo4j.driver.internal.async.ChannelAttributes.creationTimestamp; import static org.neo4j.driver.internal.async.ChannelAttributes.messageDispatcher; import static org.neo4j.driver.internal.async.ChannelAttributes.serverAddress; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/NettyConnectionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/NettyConnectionTest.java index 94401b2a4c..4b45a4e6e4 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/NettyConnectionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/NettyConnectionTest.java @@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.handlers.NoOpResponseHandler; import org.neo4j.driver.internal.spi.ResponseHandler; 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 ade998a6f6..0848992c26 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 @@ -24,6 +24,7 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeoutException; +import org.neo4j.driver.internal.InternalStatementResultCursor; import org.neo4j.driver.internal.util.Futures; import static java.util.concurrent.CompletableFuture.completedFuture; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/RoutingConnectionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/RoutingConnectionTest.java index e0145b655b..b02ffa4ceb 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/RoutingConnectionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/RoutingConnectionTest.java @@ -22,6 +22,7 @@ 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; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/RoutingResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/RoutingResponseHandlerTest.java index f3f09910ac..f71eeb1cf8 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/RoutingResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/RoutingResponseHandlerTest.java @@ -24,6 +24,7 @@ import java.util.concurrent.CompletionException; import org.neo4j.driver.internal.RoutingErrorHandler; +import org.neo4j.driver.internal.handlers.RoutingResponseHandler; import org.neo4j.driver.internal.spi.ResponseHandler; import org.neo4j.driver.v1.AccessMode; import org.neo4j.driver.v1.exceptions.ClientException; @@ -37,7 +38,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; -import static org.neo4j.driver.internal.async.BoltServerAddress.LOCAL_DEFAULT; +import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; public class RoutingResponseHandlerTest { 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 5ab70724c7..c59b5c365e 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 @@ -22,30 +22,46 @@ import io.netty.channel.embedded.EmbeddedChannel; import org.junit.After; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.neo4j.driver.v1.Logger; +import org.neo4j.driver.v1.Logging; + +import static io.netty.buffer.ByteBufUtil.prettyHexDump; import static io.netty.buffer.Unpooled.buffer; import static io.netty.buffer.Unpooled.copyShort; import static io.netty.buffer.Unpooled.wrappedBuffer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.v1.util.TestUtil.assertByteBufEquals; public class ChunkDecoderTest { - private final EmbeddedChannel channel = new EmbeddedChannel( new ChunkDecoder() ); + private ByteBuf buffer; + private EmbeddedChannel channel = new EmbeddedChannel( newChunkDecoder() ); @After public void tearDown() { - channel.finishAndReleaseAll(); + if ( buffer != null ) + { + buffer.release( buffer.refCnt() ); + } + if ( channel != null ) + { + channel.finishAndReleaseAll(); + } } @Test public void shouldDecodeFullChunk() { - EmbeddedChannel channel = new EmbeddedChannel( new ChunkDecoder() ); - // whole chunk with header and body arrives at once ByteBuf input = buffer(); input.writeShort( 7 ); @@ -70,8 +86,6 @@ public void shouldDecodeFullChunk() @Test public void shouldDecodeSplitChunk() { - EmbeddedChannel channel = new EmbeddedChannel( new ChunkDecoder() ); - // first part of the chunk contains size header and some bytes ByteBuf input1 = buffer(); input1.writeShort( 9 ); @@ -113,8 +127,6 @@ public void shouldDecodeSplitChunk() @Test public void shouldDecodeEmptyChunk() { - EmbeddedChannel channel = new EmbeddedChannel( new ChunkDecoder() ); - // chunk contains just the size header which is zero ByteBuf input = copyShort( 0 ); assertTrue( channel.writeInbound( input ) ); @@ -125,4 +137,67 @@ public void shouldDecodeEmptyChunk() // it should have no size header and empty body assertByteBufEquals( wrappedBuffer( new byte[0] ), channel.readInbound() ); } + + @Test + public void shouldLogEmptyChunkOnTraceLevel() + { + Logger logger = newTraceLogger(); + 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() ); + + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass( String.class ); + verify( logger ).trace( anyString(), messageCaptor.capture() ); + + // pretty hex dump should be logged + assertEquals( prettyHexDump( buffer ), messageCaptor.getValue() ); + // single empty chunk should be available for reading + assertEquals( 1, channel.inboundMessages().size() ); + assertByteBufEquals( wrappedBuffer( new byte[0] ), channel.readInbound() ); + } + + @Test + public void shouldLogNonEmptyChunkOnTraceLevel() + { + Logger logger = newTraceLogger(); + channel = new EmbeddedChannel( new ChunkDecoder( newLogging( logger ) ) ); + + byte[] bytes = "Hello".getBytes(); + buffer = buffer(); + buffer.writeShort( bytes.length ); + buffer.writeBytes( bytes ); + + 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() ); + + // pretty hex dump should be logged + assertEquals( prettyHexDump( buffer ), messageCaptor.getValue() ); + // single chunk should be available for reading + assertEquals( 1, channel.inboundMessages().size() ); + assertByteBufEquals( wrappedBuffer( bytes ), channel.readInbound() ); + } + + private static ChunkDecoder newChunkDecoder() + { + return new ChunkDecoder( DEV_NULL_LOGGING ); + } + + 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( anyString() ) ).thenReturn( logger ); + return logging; + } } 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 92795ace32..2a12dea5c6 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 @@ -65,8 +65,6 @@ public void shouldDecodeMessageWithMultipleChunks() @Test public void shouldDecodeMultipleConsecutiveMessages() { - EmbeddedChannel channel = new EmbeddedChannel( new MessageDecoder() ); - channel.writeInbound( wrappedBuffer( new byte[]{1, 2, 3} ) ); channel.writeInbound( wrappedBuffer( new byte[0] ) ); 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 060250c97f..8acca7d8aa 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 @@ -30,7 +30,7 @@ import java.util.Map; import org.neo4j.driver.internal.async.ChannelAttributes; -import org.neo4j.driver.internal.async.ChannelErrorHandler; +import org.neo4j.driver.internal.async.inbound.ChannelErrorHandler; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.messaging.Message; import org.neo4j.driver.internal.messaging.MessageFormat; diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ActiveChannelTrackerTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ActiveChannelTrackerTest.java index 2ecd2b1781..1cc874534e 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/pool/ActiveChannelTrackerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/pool/ActiveChannelTrackerTest.java @@ -22,7 +22,7 @@ import io.netty.channel.embedded.EmbeddedChannel; import org.junit.Test; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertEquals; 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 6ebe54b941..b58033c90b 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 @@ -24,8 +24,8 @@ import org.junit.Rule; import org.junit.Test; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.ConnectionSettings; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.async.BootstrapFactory; import org.neo4j.driver.internal.async.ChannelConnectorImpl; import org.neo4j.driver.internal.security.SecurityPlan; 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 b1139df7cb..c787c550cf 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 @@ -72,7 +72,7 @@ public void shouldDropTooOldChannelsWhenMaxLifetimeEnabled() DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST, maxConnectionLifetime, DEFAULT_MAX_CONNECTION_POOL_SIZE, DEFAULT_CONNECTION_ACQUISITION_TIMEOUT ); Clock clock = Clock.SYSTEM; - NettyChannelHealthChecker healthChecker = new NettyChannelHealthChecker( settings, clock ); + NettyChannelHealthChecker healthChecker = newHealthChecker( settings, clock ); setCreationTimestamp( channel, clock.millis() - maxConnectionLifetime * 2 ); Future healthy = healthChecker.isHealthy( channel ); @@ -86,7 +86,7 @@ public void shouldAllowVeryOldChannelsWhenMaxLifetimeDisabled() PoolSettings settings = new PoolSettings( DEFAULT_MAX_IDLE_CONNECTION_POOL_SIZE, DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST, NOT_CONFIGURED, DEFAULT_MAX_CONNECTION_POOL_SIZE, DEFAULT_CONNECTION_ACQUISITION_TIMEOUT ); - NettyChannelHealthChecker healthChecker = new NettyChannelHealthChecker( settings, Clock.SYSTEM ); + NettyChannelHealthChecker healthChecker = newHealthChecker( settings, Clock.SYSTEM ); setCreationTimestamp( channel, 0 ); Future healthy = healthChecker.isHealthy( channel ); @@ -125,7 +125,7 @@ private void testPing( boolean resetMessageSuccessful ) idleTimeBeforeConnectionTest, NOT_CONFIGURED, DEFAULT_MAX_CONNECTION_POOL_SIZE, DEFAULT_CONNECTION_ACQUISITION_TIMEOUT ); Clock clock = Clock.SYSTEM; - NettyChannelHealthChecker healthChecker = new NettyChannelHealthChecker( settings, clock ); + NettyChannelHealthChecker healthChecker = newHealthChecker( settings, clock ); setCreationTimestamp( channel, clock.millis() ); setLastUsedTimestamp( channel, clock.millis() - idleTimeBeforeConnectionTest * 2 ); @@ -153,7 +153,7 @@ private void testActiveConnectionCheck( boolean channelActive ) DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST, NOT_CONFIGURED, DEFAULT_MAX_CONNECTION_POOL_SIZE, DEFAULT_CONNECTION_ACQUISITION_TIMEOUT ); Clock clock = Clock.SYSTEM; - NettyChannelHealthChecker healthChecker = new NettyChannelHealthChecker( settings, clock ); + NettyChannelHealthChecker healthChecker = newHealthChecker( settings, clock ); setCreationTimestamp( channel, clock.millis() ); @@ -169,4 +169,9 @@ private void testActiveConnectionCheck( boolean channelActive ) assertThat( await( healthy ), is( false ) ); } } + + 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/cluster/AddressSetTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/AddressSetTest.java index 0c43fc70d1..ce92997dba 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/AddressSetTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/AddressSetTest.java @@ -24,7 +24,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import static java.util.Collections.singleton; import static org.junit.Assert.assertArrayEquals; 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 750908fadf..bfbf08476b 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 @@ -27,8 +27,8 @@ import java.util.Map; import java.util.Set; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.InternalRecord; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.v1.Record; import org.neo4j.driver.v1.Value; diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterCompositionUtil.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterCompositionUtil.java index edb97eac4f..9f93b203c1 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterCompositionUtil.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/ClusterCompositionUtil.java @@ -25,7 +25,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import static java.util.Arrays.asList; 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 2dbcfdbfed..fb09b75b16 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 @@ -22,7 +22,7 @@ import java.util.List; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.FakeClock; import static java.util.Arrays.asList; diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/DnsResolverTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/DnsResolverTest.java index 4cfb795fe5..2bc6f841fc 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/DnsResolverTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/DnsResolverTest.java @@ -23,7 +23,7 @@ import java.net.UnknownHostException; import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.Logger; import static org.hamcrest.Matchers.greaterThanOrEqualTo; 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 6444ca746b..f067c249fa 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 @@ -27,7 +27,7 @@ import java.util.Map; import java.util.concurrent.CompletionStage; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.cluster.ClusterCompositionResponse.Failure; import org.neo4j.driver.internal.cluster.ClusterCompositionResponse.Success; import org.neo4j.driver.internal.spi.Connection; 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 c92ab4bcbd..beb7693537 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 @@ -26,8 +26,8 @@ import java.util.Set; import java.util.concurrent.CompletionStage; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.InternalRecord; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.internal.util.Clock; import org.neo4j.driver.internal.value.StringValue; diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureRunnerTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureRunnerTest.java index a692c9be19..975b26d93a 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureRunnerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/RoutingProcedureRunnerTest.java @@ -24,7 +24,7 @@ import java.util.List; import java.util.concurrent.CompletionStage; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.spi.Connection; import org.neo4j.driver.v1.Record; import org.neo4j.driver.v1.Statement; 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 3cf18f0ad4..b2de08d2f3 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 @@ -22,7 +22,7 @@ import org.junit.Test; import org.mockito.Mock; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.spi.ConnectionPool; import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; 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 b24cafde4b..e031b04e93 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 @@ -27,7 +27,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.cluster.AddressSet; import org.neo4j.driver.internal.cluster.ClusterComposition; import org.neo4j.driver.internal.cluster.ClusterRoutingTable; @@ -57,7 +57,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.neo4j.driver.internal.async.BoltServerAddress.LOCAL_DEFAULT; +import static org.neo4j.driver.internal.BoltServerAddress.LOCAL_DEFAULT; import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.A; import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.B; import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.C; diff --git a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinLoadBalancingStrategyTest.java b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinLoadBalancingStrategyTest.java index e10667dc5e..4037ccf803 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinLoadBalancingStrategyTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/RoundRobinLoadBalancingStrategyTest.java @@ -20,7 +20,7 @@ import org.junit.Test; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.Logger; import org.neo4j.driver.v1.Logging; diff --git a/driver/src/test/java/org/neo4j/driver/internal/handlers/InitResponseHandlerTest.java b/driver/src/test/java/org/neo4j/driver/internal/handlers/InitResponseHandlerTest.java index 3a1dd62c90..50f2ea0b8c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/handlers/InitResponseHandlerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/handlers/InitResponseHandlerTest.java @@ -30,7 +30,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import org.neo4j.driver.internal.async.ChannelErrorHandler; +import org.neo4j.driver.internal.async.inbound.ChannelErrorHandler; import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher; import org.neo4j.driver.internal.async.outbound.OutboundMessageHandler; import org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1; 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 d60319f85e..542aee7cc7 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,19 +18,21 @@ */ 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.Test; -import java.util.Collections; - import org.neo4j.driver.v1.Value; +import static java.util.Collections.emptyMap; import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.neo4j.driver.internal.logging.DevNullLogger.DEV_NULL_LOGGER; public class PingResponseHandlerTest { @@ -38,9 +40,9 @@ public class PingResponseHandlerTest public void shouldResolvePromiseOnSuccess() { Promise promise = newPromise(); - PingResponseHandler handler = new PingResponseHandler( promise ); + PingResponseHandler handler = newHandler( promise ); - handler.onSuccess( Collections.emptyMap() ); + handler.onSuccess( emptyMap() ); assertTrue( promise.isSuccess() ); assertTrue( promise.getNow() ); @@ -50,7 +52,7 @@ public void shouldResolvePromiseOnSuccess() public void shouldResolvePromiseOnFailure() { Promise promise = newPromise(); - PingResponseHandler handler = new PingResponseHandler( promise ); + PingResponseHandler handler = newHandler( promise ); handler.onFailure( new RuntimeException() ); @@ -61,7 +63,7 @@ public void shouldResolvePromiseOnFailure() @Test public void shouldNotSupportRecordMessages() { - PingResponseHandler handler = new PingResponseHandler( newPromise() ); + PingResponseHandler handler = newHandler( newPromise() ); try { @@ -78,4 +80,9 @@ private static Promise newPromise() { return ImmediateEventExecutor.INSTANCE.newPromise(); } + + private static PingResponseHandler newHandler( Promise result ) + { + return new PingResponseHandler( result, mock( Channel.class ), DEV_NULL_LOGGER ); + } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/logging/DelegatingLoggerTest.java b/driver/src/test/java/org/neo4j/driver/internal/logging/PrefixedLoggerTest.java similarity index 76% rename from driver/src/test/java/org/neo4j/driver/internal/logging/DelegatingLoggerTest.java rename to driver/src/test/java/org/neo4j/driver/internal/logging/PrefixedLoggerTest.java index 8a25a22a24..a46be21789 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/logging/DelegatingLoggerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/logging/PrefixedLoggerTest.java @@ -34,7 +34,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -public class DelegatingLoggerTest +public class PrefixedLoggerTest { private static final String PREFIX = "Output"; private static final String MESSAGE = "Hello World!"; @@ -45,7 +45,7 @@ public void shouldThrowWhenDelegateIsNull() { try { - new DelegatingLogger( null ); + new PrefixedLogger( null ); fail( "Exception expected" ); } catch ( Exception e ) @@ -57,7 +57,7 @@ public void shouldThrowWhenDelegateIsNull() @Test public void shouldAllowNullPrefix() { - assertNotNull( new DelegatingLogger( newLoggerMock(), null ) ); + assertNotNull( new PrefixedLogger( null, newLoggerMock() ) ); } @Test @@ -65,7 +65,7 @@ public void shouldDelegateIsDebugEnabled() { Logger delegate = newLoggerMock( true, false ); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); assertTrue( logger.isDebugEnabled() ); verify( delegate ).isDebugEnabled(); @@ -76,7 +76,7 @@ public void shouldDelegateIsTraceEnabled() { Logger delegate = newLoggerMock( false, true ); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); assertTrue( logger.isTraceEnabled() ); verify( delegate ).isTraceEnabled(); @@ -87,7 +87,7 @@ public void shouldNotDelegateDebugLogWhenDebugDisabled() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); logger.debug( MESSAGE ); verify( delegate, never() ).debug( anyString(), anyVararg() ); @@ -98,7 +98,7 @@ public void shouldNotDelegateTraceLogWhenTraceDisabled() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); logger.trace( MESSAGE ); verify( delegate, never() ).trace( anyString(), anyVararg() ); @@ -108,7 +108,7 @@ public void shouldNotDelegateTraceLogWhenTraceDisabled() public void shouldDelegateErrorMessageWhenNoPrefix() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); logger.error( MESSAGE, ERROR ); @@ -119,7 +119,7 @@ public void shouldDelegateErrorMessageWhenNoPrefix() public void shouldDelegateInfoMessageWhenNoPrefix() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); logger.info( MESSAGE ); @@ -130,7 +130,7 @@ public void shouldDelegateInfoMessageWhenNoPrefix() public void shouldDelegateWarnMessageWhenNoPrefix() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); logger.warn( MESSAGE ); @@ -141,7 +141,7 @@ public void shouldDelegateWarnMessageWhenNoPrefix() public void shouldDelegateWarnMessageWithoutErrorWhenNoPrefix() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); Exception cause = new Exception(); logger.warn( MESSAGE, cause ); @@ -153,7 +153,7 @@ public void shouldDelegateWarnMessageWithoutErrorWhenNoPrefix() public void shouldDelegateDebugMessageWhenNoPrefix() { Logger delegate = newLoggerMock( true, false ); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); logger.debug( MESSAGE ); @@ -164,7 +164,7 @@ public void shouldDelegateDebugMessageWhenNoPrefix() public void shouldDelegateTraceMessageWhenNoPrefix() { Logger delegate = newLoggerMock( false, true ); - DelegatingLogger logger = new DelegatingLogger( delegate ); + PrefixedLogger logger = new PrefixedLogger( delegate ); logger.trace( MESSAGE ); @@ -175,67 +175,67 @@ public void shouldDelegateTraceMessageWhenNoPrefix() public void shouldDelegateErrorMessageWithPrefix() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate, PREFIX ); + PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); logger.error( MESSAGE, ERROR ); - verify( delegate ).error( "[Output] Hello World!", ERROR ); + verify( delegate ).error( "Output Hello World!", ERROR ); } @Test public void shouldDelegateInfoMessageWithPrefix() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate, PREFIX ); + PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); logger.info( MESSAGE ); - verify( delegate ).info( "[Output] Hello World!" ); + verify( delegate ).info( "Output Hello World!" ); } @Test public void shouldDelegateWarnMessageWithPrefix() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate, PREFIX ); + PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); logger.warn( MESSAGE ); - verify( delegate ).warn( "[Output] Hello World!" ); + verify( delegate ).warn( "Output Hello World!" ); } @Test public void shouldDelegateWarnMessageWithErrorWithPrefix() { Logger delegate = newLoggerMock(); - DelegatingLogger logger = new DelegatingLogger( delegate, PREFIX ); + PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); Exception cause = new Exception(); logger.warn( MESSAGE, cause ); - verify( delegate ).warn( "[Output] Hello World!", cause ); + verify( delegate ).warn( "Output Hello World!", cause ); } @Test public void shouldDelegateDebugMessageWithPrefix() { Logger delegate = newLoggerMock( true, false ); - DelegatingLogger logger = new DelegatingLogger( delegate, PREFIX ); + PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); logger.debug( MESSAGE ); - verify( delegate ).debug( "[Output] Hello World!" ); + verify( delegate ).debug( "Output Hello World!" ); } @Test public void shouldDelegateTraceMessageWithPrefix() { Logger delegate = newLoggerMock( false, true ); - DelegatingLogger logger = new DelegatingLogger( delegate, PREFIX ); + PrefixedLogger logger = new PrefixedLogger( PREFIX, delegate ); logger.trace( MESSAGE ); - verify( delegate ).trace( "[Output] Hello World!" ); + verify( delegate ).trace( "Output Hello World!" ); } private static Logger newLoggerMock() 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 76bca15696..b68a007935 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 @@ -24,10 +24,10 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import static org.junit.Assert.assertEquals; -import static org.neo4j.driver.internal.async.BoltServerAddress.DEFAULT_PORT; +import static org.neo4j.driver.internal.BoltServerAddress.DEFAULT_PORT; @RunWith( Parameterized.class ) public class BoltServerAddressParsingTest 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 ca8cf1a053..2b9b2732ca 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 @@ -22,12 +22,12 @@ import java.net.SocketAddress; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertThat; -import static org.neo4j.driver.internal.async.BoltServerAddress.DEFAULT_PORT; +import static org.neo4j.driver.internal.BoltServerAddress.DEFAULT_PORT; public class BoltServerAddressTest { 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 aad7c72347..e8f55f6f01 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,6 @@ */ package org.neo4j.driver.internal.packstream; -import org.hamcrest.MatcherAssert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -34,8 +33,6 @@ import java.util.LinkedHashMap; import java.util.Map; -import org.neo4j.driver.internal.util.BytePrinter; - import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.asList; import static org.hamcrest.CoreMatchers.equalTo; @@ -467,8 +464,6 @@ public void testCanPackAndUnpackSpecialStringFromBytes() throws Throwable PackStream.Packer packer = machine.packer(); byte[] bytes = code.getBytes( UTF_8 ); - MatcherAssert.assertThat( BytePrinter.hex( bytes ).trim(), equalTo( "4d 6a c3 b6 6c 6e 69 72" ) ); - assertThat( new String( bytes, UTF_8 ), equalTo( code ) ); packer.packString( bytes ); diff --git a/driver/src/test/java/org/neo4j/driver/internal/security/TrustOnFirstUseTrustManagerTest.java b/driver/src/test/java/org/neo4j/driver/internal/security/TrustOnFirstUseTrustManagerTest.java index c39c473d77..a349249413 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/security/TrustOnFirstUseTrustManagerTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/security/TrustOnFirstUseTrustManagerTest.java @@ -31,7 +31,7 @@ import java.security.cert.X509Certificate; import java.util.Scanner; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.Logger; import static org.hamcrest.CoreMatchers.containsString; diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ChannelTrackingConnector.java b/driver/src/test/java/org/neo4j/driver/internal/util/ChannelTrackingConnector.java index ceef4d3890..a3a9dc219b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ChannelTrackingConnector.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ChannelTrackingConnector.java @@ -24,7 +24,7 @@ import java.util.List; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.async.ChannelConnector; public class ChannelTrackingConnector implements ChannelConnector diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/ChannelTrackingDriverFactory.java b/driver/src/test/java/org/neo4j/driver/internal/util/ChannelTrackingDriverFactory.java index cfa268119a..61ad1220ae 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/ChannelTrackingDriverFactory.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/ChannelTrackingDriverFactory.java @@ -25,8 +25,8 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.ConnectionSettings; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.async.ChannelConnector; import org.neo4j.driver.internal.security.SecurityPlan; import org.neo4j.driver.internal.spi.ConnectionPool; 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 455cfb946f..bfc93390a2 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 @@ -25,11 +25,11 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.DirectConnectionProvider; import org.neo4j.driver.internal.InternalDriver; import org.neo4j.driver.internal.SessionFactory; import org.neo4j.driver.internal.SessionFactoryImpl; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.cluster.AddressSet; import org.neo4j.driver.internal.cluster.RoutingTable; import org.neo4j.driver.internal.cluster.loadbalancing.LoadBalancer; diff --git a/driver/src/test/java/org/neo4j/driver/v1/integration/ConnectionHandlingIT.java b/driver/src/test/java/org/neo4j/driver/v1/integration/ConnectionHandlingIT.java index 3261bd9dc9..1ca806270c 100644 --- a/driver/src/test/java/org/neo4j/driver/v1/integration/ConnectionHandlingIT.java +++ b/driver/src/test/java/org/neo4j/driver/v1/integration/ConnectionHandlingIT.java @@ -29,9 +29,9 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.ConnectionSettings; import org.neo4j.driver.internal.DriverFactory; -import org.neo4j.driver.internal.async.BoltServerAddress; import org.neo4j.driver.internal.async.ChannelConnector; import org.neo4j.driver.internal.async.pool.ConnectionPoolImpl; import org.neo4j.driver.internal.async.pool.PoolSettings; diff --git a/driver/src/test/java/org/neo4j/driver/v1/integration/EncryptionIT.java b/driver/src/test/java/org/neo4j/driver/v1/integration/EncryptionIT.java index 8e3b274564..af95544e60 100644 --- a/driver/src/test/java/org/neo4j/driver/v1/integration/EncryptionIT.java +++ b/driver/src/test/java/org/neo4j/driver/v1/integration/EncryptionIT.java @@ -20,13 +20,22 @@ import org.junit.Rule; import org.junit.Test; -import org.neo4j.driver.v1.*; + +import org.neo4j.driver.v1.Config; +import org.neo4j.driver.v1.Driver; +import org.neo4j.driver.v1.GraphDatabase; +import org.neo4j.driver.v1.Record; +import org.neo4j.driver.v1.Session; +import org.neo4j.driver.v1.StatementResult; +import org.neo4j.driver.v1.exceptions.ServiceUnavailableException; +import org.neo4j.driver.v1.util.Neo4jSettings; +import org.neo4j.driver.v1.util.Neo4jSettings.BoltTlsLevel; import org.neo4j.driver.v1.util.TestNeo4j; import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.neo4j.driver.v1.Config.EncryptionLevel.NONE; -import static org.neo4j.driver.v1.Config.EncryptionLevel.REQUIRED; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; public class EncryptionIT { @@ -34,51 +43,89 @@ public class EncryptionIT public TestNeo4j neo4j = new TestNeo4j(); @Test - public void shouldOperateWithNoEncryption() throws Exception + public void shouldOperateWithNoEncryptionWhenItIsOptionalInTheDatabase() { - // Given - Driver driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), - Config.build().withoutEncryption().toConfig() ); + testMatchingEncryption( BoltTlsLevel.OPTIONAL, false ); + } - // Then - assertThat( driver.isEncrypted(), equalTo( false ) ); + @Test + public void shouldOperateWithEncryptionWhenItIsOptionalInTheDatabase() + { + testMatchingEncryption( BoltTlsLevel.OPTIONAL, true ); + } - // When - Session session = driver.session(); - StatementResult result = session.run( "RETURN 1" ); + @Test + public void shouldFailWithoutEncryptionWhenItIsRequiredInTheDatabase() + { + testMismatchingEncryption( BoltTlsLevel.REQUIRED, false ); + } - // Then - Record record = result.next(); - int value = record.get( 0 ).asInt(); - assertThat( value, equalTo( 1 ) ); + @Test + public void shouldOperateWithEncryptionWhenItIsAlsoRequiredInTheDatabase() + { + testMatchingEncryption( BoltTlsLevel.REQUIRED, true ); + } - // Finally - session.close(); - driver.close(); + @Test + public void shouldFailWithEncryptionWhenItIsDisabledInTheDatabase() + { + testMismatchingEncryption( BoltTlsLevel.DISABLED, true ); } @Test - public void shouldOperateWithRequiredEncryption() throws Exception + public void shouldOperateWithoutEncryptionWhenItIsAlsoDisabledInTheDatabase() { - // Given - Driver driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), - Config.build().withEncryption().toConfig() ); + testMatchingEncryption( BoltTlsLevel.DISABLED, false ); + } - // Then - assertThat( driver.isEncrypted(), equalTo( true ) ); + private void testMatchingEncryption( BoltTlsLevel tlsLevel, boolean driverEncrypted ) + { + neo4j.restartDb( Neo4jSettings.TEST_SETTINGS.updateWith( Neo4jSettings.BOLT_TLS_LEVEL, tlsLevel.toString() ) ); + Config config = newConfig( driverEncrypted ); - // When - Session session = driver.session(); - StatementResult result = session.run( "RETURN 1" ); + try ( Driver driver = GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), config ) ) + { + assertThat( driver.isEncrypted(), equalTo( driverEncrypted ) ); - // Then - Record record = result.next(); - int value = record.get( 0 ).asInt(); - assertThat( value, equalTo( 1 ) ); + try ( Session session = driver.session() ) + { + StatementResult result = session.run( "RETURN 1" ); - // Finally - session.close(); - driver.close(); + Record record = result.next(); + 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 ); + + try + { + GraphDatabase.driver( neo4j.uri(), neo4j.authToken(), config ).close(); + fail( "Exception expected" ); + } + catch ( ServiceUnavailableException e ) + { + assertThat( e.getMessage(), startsWith( "Connection to the database terminated" ) ); + } + } + + private static Config newConfig( boolean withEncryption ) + { + return withEncryption ? configWithEncryption() : configWithoutEncryption(); + } + + private static Config configWithEncryption() + { + return Config.build().withEncryption().toConfig(); + } + + private static Config configWithoutEncryption() + { + return Config.build().withoutEncryption().toConfig(); + } } diff --git a/driver/src/test/java/org/neo4j/driver/v1/util/BytePrinterTest.java b/driver/src/test/java/org/neo4j/driver/v1/util/BytePrinterTest.java deleted file mode 100644 index b37ae36ab2..0000000000 --- a/driver/src/test/java/org/neo4j/driver/v1/util/BytePrinterTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2002-2017 "Neo Technology," - * Network Engine for Objects in Lund AB [http://neotechnology.com] - * - * This file is part of Neo4j. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.neo4j.driver.v1.util; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - -import org.junit.Assert; -import org.junit.Test; - -import org.neo4j.driver.internal.util.BytePrinter; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -public class BytePrinterTest -{ - private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - @Test - public void shouldPrintBytes() throws Throwable - { - Assert.assertEquals( "01", BytePrinter.hex( (byte) 1 ) ); - assertEquals( "01 02 03 ", BytePrinter.hex( new byte[]{1, 2, 3} ) ); - assertEquals( "hello ", BytePrinter.ljust( "hello", 10 ) ); - assertEquals( " hello", BytePrinter.rjust( "hello", 10 ) ); - - BytePrinter.print( (byte) 1, new PrintStream( baos ) ); - assertEquals( "01", new String( baos.toByteArray(), StandardCharsets.UTF_8 ) ); - - baos.reset(); - BytePrinter.print( new byte[]{1, 2, 3}, new PrintStream( baos ) ); - assertEquals( "01 02 03 ", new String( baos.toByteArray(), StandardCharsets.UTF_8 ) ); - - baos.reset(); - BytePrinter.print( ByteBuffer.wrap( new byte[]{1, 2, 3} ), new PrintStream( baos ) ); - assertEquals( "01 02 03 ", new String( baos.toByteArray(), StandardCharsets.UTF_8 ) ); - } - - @Test - public void shouldRevertHexStringToBytes() - { - byte[] bytes = BytePrinter.hexStringToBytes( "01 02 03 04\n05\n" ); - assertArrayEquals( new byte[]{1, 2, 3, 4, 5}, bytes ); - } -} diff --git a/driver/src/test/java/org/neo4j/driver/v1/util/Neo4jRunner.java b/driver/src/test/java/org/neo4j/driver/v1/util/Neo4jRunner.java index edfa3ab279..11413b5478 100644 --- a/driver/src/test/java/org/neo4j/driver/v1/util/Neo4jRunner.java +++ b/driver/src/test/java/org/neo4j/driver/v1/util/Neo4jRunner.java @@ -27,7 +27,7 @@ import java.util.List; import java.util.Map; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.v1.AuthToken; import org.neo4j.driver.v1.Driver; import org.neo4j.driver.v1.GraphDatabase; diff --git a/driver/src/test/java/org/neo4j/driver/v1/util/Neo4jSettings.java b/driver/src/test/java/org/neo4j/driver/v1/util/Neo4jSettings.java index a025b08bf1..5f9ed23cb3 100644 --- a/driver/src/test/java/org/neo4j/driver/v1/util/Neo4jSettings.java +++ b/driver/src/test/java/org/neo4j/driver/v1/util/Neo4jSettings.java @@ -35,12 +35,14 @@ public class Neo4jSettings public static final String LISTEN_ADDR = "dbms.connectors.default_listen_address"; // only valid for 3.1+ public static final String IPV6_ENABLED_ADDR = "::"; public static final String PAGE_CACHE_SIZE = "dbms.memory.pagecache.size"; + public static final String BOLT_TLS_LEVEL = "dbms.connector.bolt.tls_level"; private static final String DEFAULT_IMPORT_DIR = "import"; private static final String DEFAULT_CERT_DIR = "certificates"; public static final String DEFAULT_TLS_CERT_PATH = DEFAULT_CERT_DIR + "/neo4j.cert"; public static final String DEFAULT_TLS_KEY_PATH = DEFAULT_CERT_DIR + "/neo4j.key"; public static final String DEFAULT_PAGE_CACHE_SIZE = "512m"; + public static final String DEFAULT_BOLT_TLS_LEVEL = BoltTlsLevel.OPTIONAL.toString(); public static final String DEFAULT_DATA_DIR = "data"; @@ -54,8 +56,16 @@ public class Neo4jSettings IMPORT_DIR, DEFAULT_IMPORT_DIR, AUTH_ENABLED, "true", PAGE_CACHE_SIZE, DEFAULT_PAGE_CACHE_SIZE, + 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 ) { this.settings = settings; diff --git a/driver/src/test/java/org/neo4j/driver/v1/util/TestNeo4j.java b/driver/src/test/java/org/neo4j/driver/v1/util/TestNeo4j.java index f5e2159b63..30661ed4ca 100644 --- a/driver/src/test/java/org/neo4j/driver/v1/util/TestNeo4j.java +++ b/driver/src/test/java/org/neo4j/driver/v1/util/TestNeo4j.java @@ -28,7 +28,7 @@ import java.net.URI; import java.net.URL; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.v1.AuthToken; import org.neo4j.driver.v1.Driver; diff --git a/driver/src/test/java/org/neo4j/driver/v1/util/cc/Cluster.java b/driver/src/test/java/org/neo4j/driver/v1/util/cc/Cluster.java index 9a0f23faee..88d13b8b79 100644 --- a/driver/src/test/java/org/neo4j/driver/v1/util/cc/Cluster.java +++ b/driver/src/test/java/org/neo4j/driver/v1/util/cc/Cluster.java @@ -28,7 +28,7 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.internal.util.DriverFactoryWithOneEventLoopThread; import org.neo4j.driver.v1.AccessMode; import org.neo4j.driver.v1.AuthTokens; diff --git a/driver/src/test/java/org/neo4j/driver/v1/util/cc/ClusterMember.java b/driver/src/test/java/org/neo4j/driver/v1/util/cc/ClusterMember.java index c68004b916..e5df9989e5 100644 --- a/driver/src/test/java/org/neo4j/driver/v1/util/cc/ClusterMember.java +++ b/driver/src/test/java/org/neo4j/driver/v1/util/cc/ClusterMember.java @@ -22,7 +22,7 @@ import java.net.UnknownHostException; import java.nio.file.Path; -import org.neo4j.driver.internal.async.BoltServerAddress; +import org.neo4j.driver.internal.BoltServerAddress; import static java.util.Objects.requireNonNull;