From dc11f57e8bb06603c6bdd4d5c722969a92e6aee3 Mon Sep 17 00:00:00 2001 From: lutovich Date: Thu, 18 Jan 2018 14:46:52 +0100 Subject: [PATCH] Bolt V2 with point type support Introduced an extension of Bolt V1 with one additional type - point. New protocol version is exactly the same as the previous one but is able to serialize/deserialize points. Arbitrary dimensional points are supported. Serialization format is generic and allows `double[]` array as point coordinate. Made protocol test utilities able to work with different protocol versions. --- .../DefaultBoltProtocolHandlerFactory.java | 19 +- .../neo4j/bolt/v1/messaging/Neo4jPackV1.java | 63 ++++--- .../BoltMessagingProtocolV1Handler.java | 11 +- .../neo4j/bolt/v2/messaging/Neo4jPackV2.java | 99 ++++++++++ .../BoltMessagingProtocolV2Handler.java | 44 +++++ ...DefaultBoltProtocolHandlerFactoryTest.java | 52 +++-- .../v1/messaging/BoltRequestMessageTest.java | 12 +- .../v1/messaging/BoltResponseMessageTest.java | 12 +- .../v1/messaging/util/MessageMatchers.java | 14 +- .../v1/runtime/integration/BoltConfigIT.java | 9 +- .../BoltMessagingProtocolV1HandlerTest.java | 19 +- .../v1/transport/BoltV1DechunkerTest.java | 6 +- .../integration/AuthenticationIT.java | 168 +++++++++-------- .../integration/ConcurrentAccessIT.java | 21 +-- .../RejectTransportEncryptionIT.java | 5 +- .../RequiredTransportEncryptionIT.java | 5 +- .../integration/TransportErrorIT.java | 23 +-- .../integration/TransportSessionIT.java | 94 ++++----- .../integration/TransportTestUtil.java | 73 +++---- .../socket/FragmentedMessageDeliveryTest.java | 2 +- .../socket/SocketTransportHandlerTest.java | 3 +- .../bolt/v2/messaging/Neo4jPackV2Test.java | 83 ++++++++ .../BoltMessagingProtocolV2HandlerTest.java | 45 +++++ .../integration/BoltV2TransportIT.java | 178 ++++++++++++++++++ .../transport/integration/CertificatesIT.java | 6 +- .../java/org/neo4j/metrics/BoltMetricsIT.java | 10 +- .../enterprise/auth/BoltInteraction.java | 30 +-- .../auth/ProcedureInteractionTestBase.java | 13 +- .../bolt/ActiveDirectoryAuthenticationIT.java | 33 ++-- .../bolt/BoltConnectionManagementIT.java | 60 +++--- .../EnterpriseAuthenticationTestBase.java | 57 +++--- .../auth/integration/bolt/LdapAuthIT.java | 55 +++--- .../bolt/PluginAuthenticationIT.java | 18 +- 33 files changed, 934 insertions(+), 408 deletions(-) create mode 100644 community/bolt/src/main/java/org/neo4j/bolt/v2/messaging/Neo4jPackV2.java create mode 100644 community/bolt/src/main/java/org/neo4j/bolt/v2/transport/BoltMessagingProtocolV2Handler.java create mode 100644 community/bolt/src/test/java/org/neo4j/bolt/v2/messaging/Neo4jPackV2Test.java create mode 100644 community/bolt/src/test/java/org/neo4j/bolt/v2/transport/BoltMessagingProtocolV2HandlerTest.java create mode 100644 community/bolt/src/test/java/org/neo4j/bolt/v2/transport/integration/BoltV2TransportIT.java diff --git a/community/bolt/src/main/java/org/neo4j/bolt/transport/DefaultBoltProtocolHandlerFactory.java b/community/bolt/src/main/java/org/neo4j/bolt/transport/DefaultBoltProtocolHandlerFactory.java index d9328105bbab..d1b74f02fefd 100644 --- a/community/bolt/src/main/java/org/neo4j/bolt/transport/DefaultBoltProtocolHandlerFactory.java +++ b/community/bolt/src/main/java/org/neo4j/bolt/transport/DefaultBoltProtocolHandlerFactory.java @@ -20,12 +20,13 @@ package org.neo4j.bolt.transport; import org.neo4j.bolt.BoltChannel; -import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.runtime.BoltChannelAutoReadLimiter; import org.neo4j.bolt.v1.runtime.BoltWorker; import org.neo4j.bolt.v1.runtime.WorkerFactory; import org.neo4j.bolt.v1.transport.BoltMessagingProtocolV1Handler; +import org.neo4j.bolt.v2.transport.BoltMessagingProtocolV2Handler; import org.neo4j.kernel.impl.logging.LogService; +import org.neo4j.logging.Log; public class DefaultBoltProtocolHandlerFactory implements BoltProtocolHandlerFactory { @@ -46,14 +47,22 @@ public BoltMessagingProtocolHandler create( long protocolVersion, BoltChannel ch { if ( protocolVersion == BoltMessagingProtocolV1Handler.VERSION_NUMBER ) { - BoltChannelAutoReadLimiter limiter = - new BoltChannelAutoReadLimiter( channel.rawChannel(), logService.getInternalLog( BoltChannelAutoReadLimiter.class ) ); - BoltWorker worker = workerFactory.newWorker( channel, limiter ); - return new BoltMessagingProtocolV1Handler( channel, new Neo4jPackV1(), worker, throttleGroup, logService ); + return new BoltMessagingProtocolV1Handler( channel, newBoltWorker( channel ), throttleGroup, logService ); + } + else if ( protocolVersion == BoltMessagingProtocolV2Handler.VERSION ) + { + return new BoltMessagingProtocolV2Handler( channel, newBoltWorker( channel ), throttleGroup, logService ); } else { return null; } } + + private BoltWorker newBoltWorker( BoltChannel channel ) + { + Log log = logService.getInternalLog( BoltChannelAutoReadLimiter.class ); + BoltChannelAutoReadLimiter limiter = new BoltChannelAutoReadLimiter( channel.rawChannel(), log ); + return workerFactory.newWorker( channel, limiter ); + } } diff --git a/community/bolt/src/main/java/org/neo4j/bolt/v1/messaging/Neo4jPackV1.java b/community/bolt/src/main/java/org/neo4j/bolt/v1/messaging/Neo4jPackV1.java index 391cb4434a65..f5d31c046942 100644 --- a/community/bolt/src/main/java/org/neo4j/bolt/v1/messaging/Neo4jPackV1.java +++ b/community/bolt/src/main/java/org/neo4j/bolt/v1/messaging/Neo4jPackV1.java @@ -61,16 +61,16 @@ public class Neo4jPackV1 implements Neo4jPack @Override public Neo4jPack.Packer newPacker( PackOutput output ) { - return new Packer( output ); + return new PackerV1( output ); } @Override public Neo4jPack.Unpacker newUnpacker( PackInput input ) { - return new Unpacker( input ); + return new UnpackerV1( input ); } - private static class Packer extends PackStream.Packer implements AnyValueWriter, Neo4jPack.Packer + protected static class PackerV1 extends PackStream.Packer implements AnyValueWriter, Neo4jPack.Packer { private Error error; private static final int INITIAL_PATH_CAPACITY = 500; @@ -80,7 +80,7 @@ private static class Packer extends PackStream.Packer implements AnyValueWriter< private final PrimitiveLongIntKeyValueArray relationshipIndexes = new PrimitiveLongIntKeyValueArray( INITIAL_PATH_CAPACITY ); - Packer( PackOutput output ) + protected PackerV1( PackOutput output ) { super( output ); } @@ -442,11 +442,11 @@ public void writeByteArray( byte[] value ) throws IOException } } - private static class Unpacker extends PackStream.Unpacker implements Neo4jPack.Unpacker + protected static class UnpackerV1 extends PackStream.Unpacker implements Neo4jPack.Unpacker { - private List errors = new ArrayList<>( 2 ); + private final List errors = new ArrayList<>( 2 ); - Unpacker( PackInput input ) + protected UnpackerV1( PackInput input ) { super( input ); } @@ -483,28 +483,7 @@ public AnyValue unpack() throws IOException { unpackStructHeader(); char signature = unpackStructSignature(); - switch ( signature ) - { - case NODE: - { - throw new BoltIOException( Status.Request.Invalid, "Nodes cannot be unpacked." ); - } - case RELATIONSHIP: - { - throw new BoltIOException( Status.Request.Invalid, "Relationships cannot be unpacked." ); - } - case UNBOUND_RELATIONSHIP: - { - throw new BoltIOException( Status.Request.Invalid, "Relationships cannot be unpacked." ); - } - case PATH: - { - throw new BoltIOException( Status.Request.Invalid, "Paths cannot be unpacked." ); - } - default: - throw new BoltIOException( Status.Request.InvalidFormat, - "Unknown struct type: " + Integer.toHexString( signature ) ); - } + return unpackStruct( signature ); } case END_OF_STREAM: { @@ -554,6 +533,32 @@ else if ( size == UNKNOWN_SIZE ) } } + protected AnyValue unpackStruct( char signature ) throws IOException + { + switch ( signature ) + { + case NODE: + { + throw new BoltIOException( Status.Request.Invalid, "Nodes cannot be unpacked." ); + } + case RELATIONSHIP: + { + throw new BoltIOException( Status.Request.Invalid, "Relationships cannot be unpacked." ); + } + case UNBOUND_RELATIONSHIP: + { + throw new BoltIOException( Status.Request.Invalid, "Relationships cannot be unpacked." ); + } + case PATH: + { + throw new BoltIOException( Status.Request.Invalid, "Paths cannot be unpacked." ); + } + default: + throw new BoltIOException( Status.Request.InvalidFormat, + "Unknown struct type: " + Integer.toHexString( signature ) ); + } + } + @Override public MapValue unpackMap() throws IOException { diff --git a/community/bolt/src/main/java/org/neo4j/bolt/v1/transport/BoltMessagingProtocolV1Handler.java b/community/bolt/src/main/java/org/neo4j/bolt/v1/transport/BoltMessagingProtocolV1Handler.java index c512262add21..8596aeebd563 100644 --- a/community/bolt/src/main/java/org/neo4j/bolt/v1/transport/BoltMessagingProtocolV1Handler.java +++ b/community/bolt/src/main/java/org/neo4j/bolt/v1/transport/BoltMessagingProtocolV1Handler.java @@ -26,11 +26,12 @@ import java.util.concurrent.atomic.AtomicInteger; import org.neo4j.bolt.BoltChannel; +import org.neo4j.bolt.v1.messaging.Neo4jPack; import org.neo4j.bolt.transport.BoltMessagingProtocolHandler; import org.neo4j.bolt.transport.TransportThrottleGroup; import org.neo4j.bolt.v1.messaging.BoltMessageRouter; import org.neo4j.bolt.v1.messaging.BoltResponseMessageWriter; -import org.neo4j.bolt.v1.messaging.Neo4jPack; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.runtime.BoltWorker; import org.neo4j.kernel.impl.logging.LogService; import org.neo4j.logging.Log; @@ -57,7 +58,13 @@ public class BoltMessagingProtocolV1Handler implements BoltMessagingProtocolHand private final Log internalLog; - public BoltMessagingProtocolV1Handler( BoltChannel boltChannel, Neo4jPack neo4jPack, BoltWorker worker, + public BoltMessagingProtocolV1Handler( BoltChannel boltChannel, BoltWorker worker, + TransportThrottleGroup throttleGroup, LogService logging ) + { + this( boltChannel, worker, new Neo4jPackV1(), throttleGroup, logging ); + } + + protected BoltMessagingProtocolV1Handler( BoltChannel boltChannel, BoltWorker worker, Neo4jPack neo4jPack, TransportThrottleGroup throttleGroup, LogService logging ) { this.chunkedOutput = new ChunkedOutput( boltChannel.rawChannel(), DEFAULT_OUTPUT_BUFFER_SIZE, throttleGroup ); diff --git a/community/bolt/src/main/java/org/neo4j/bolt/v2/messaging/Neo4jPackV2.java b/community/bolt/src/main/java/org/neo4j/bolt/v2/messaging/Neo4jPackV2.java new file mode 100644 index 000000000000..46f4843e3c7a --- /dev/null +++ b/community/bolt/src/main/java/org/neo4j/bolt/v2/messaging/Neo4jPackV2.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.bolt.v2.messaging; + +import java.io.IOException; + +import org.neo4j.bolt.v1.messaging.Neo4jPack; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; +import org.neo4j.bolt.v1.packstream.PackInput; +import org.neo4j.bolt.v1.packstream.PackOutput; +import org.neo4j.values.AnyValue; +import org.neo4j.values.storable.CoordinateReferenceSystem; +import org.neo4j.values.storable.PointValue; + +import static org.neo4j.values.storable.Values.doubleArray; +import static org.neo4j.values.storable.Values.pointValue; + +public class Neo4jPackV2 extends Neo4jPackV1 +{ + public static final byte POINT = 'X'; + + @Override + public Neo4jPack.Packer newPacker( PackOutput output ) + { + return new PackerV2( output ); + } + + @Override + public Neo4jPack.Unpacker newUnpacker( PackInput input ) + { + return new UnpackerV2( input ); + } + + private static class PackerV2 extends Neo4jPackV1.PackerV1 + { + PackerV2( PackOutput output ) + { + super( output ); + } + + @Override + public void writePoint( CoordinateReferenceSystem crs, double[] coordinate ) throws IOException + { + packStructHeader( 3, POINT ); + pack( crs.getTable().getTableId() ); + pack( crs.getCode() ); + pack( doubleArray( coordinate ) ); + } + } + + private static class UnpackerV2 extends Neo4jPackV1.UnpackerV1 + { + UnpackerV2( PackInput input ) + { + super( input ); + } + + @Override + protected AnyValue unpackStruct( char signature ) throws IOException + { + if ( signature == POINT ) + { + return unpackPoint(); + } + return super.unpackStruct( signature ); + } + + private PointValue unpackPoint() throws IOException + { + int tableId = unpackInteger(); + int code = unpackInteger(); + CoordinateReferenceSystem crs = CoordinateReferenceSystem.get( tableId, code ); + int length = (int) unpackListHeader(); + double[] coordinates = new double[length]; + for ( int i = 0; i < length; i++ ) + { + coordinates[i] = unpackDouble(); + } + return pointValue( crs, coordinates ); + } + } +} diff --git a/community/bolt/src/main/java/org/neo4j/bolt/v2/transport/BoltMessagingProtocolV2Handler.java b/community/bolt/src/main/java/org/neo4j/bolt/v2/transport/BoltMessagingProtocolV2Handler.java new file mode 100644 index 000000000000..ab297a03278a --- /dev/null +++ b/community/bolt/src/main/java/org/neo4j/bolt/v2/transport/BoltMessagingProtocolV2Handler.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.bolt.v2.transport; + +import org.neo4j.bolt.BoltChannel; +import org.neo4j.bolt.transport.TransportThrottleGroup; +import org.neo4j.bolt.v1.runtime.BoltWorker; +import org.neo4j.bolt.v1.transport.BoltMessagingProtocolV1Handler; +import org.neo4j.bolt.v2.messaging.Neo4jPackV2; +import org.neo4j.kernel.impl.logging.LogService; + +public class BoltMessagingProtocolV2Handler extends BoltMessagingProtocolV1Handler +{ + public static final int VERSION = 2; + + public BoltMessagingProtocolV2Handler( BoltChannel boltChannel, BoltWorker worker, + TransportThrottleGroup throttleGroup, LogService logging ) + { + super( boltChannel, worker, new Neo4jPackV2(), throttleGroup, logging ); + } + + @Override + public int version() + { + return VERSION; + } +} diff --git a/community/bolt/src/test/java/org/neo4j/bolt/transport/DefaultBoltProtocolHandlerFactoryTest.java b/community/bolt/src/test/java/org/neo4j/bolt/transport/DefaultBoltProtocolHandlerFactoryTest.java index 5fccd5285d3e..d8f68d019b3c 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/transport/DefaultBoltProtocolHandlerFactoryTest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/transport/DefaultBoltProtocolHandlerFactoryTest.java @@ -27,10 +27,14 @@ import org.neo4j.bolt.logging.NullBoltMessageLogger; import org.neo4j.bolt.v1.runtime.BoltWorker; import org.neo4j.bolt.v1.runtime.WorkerFactory; +import org.neo4j.bolt.v1.transport.BoltMessagingProtocolV1Handler; +import org.neo4j.bolt.v2.transport.BoltMessagingProtocolV2Handler; import org.neo4j.kernel.impl.logging.NullLogService; -import static org.junit.Assert.assertNotNull; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.RETURNS_MOCKS; @@ -44,7 +48,32 @@ public class DefaultBoltProtocolHandlerFactoryTest @Test public void shouldCreateV1Handler() { - int protocolVersion = 1; + testHandlerCreation( BoltMessagingProtocolV1Handler.VERSION, BoltMessagingProtocolV1Handler.class ); + } + + @Test + public void shouldCreateV2Handler() + { + testHandlerCreation( BoltMessagingProtocolV2Handler.VERSION, BoltMessagingProtocolV2Handler.class ); + } + + @Test + public void shouldCreateNothingForUnknownProtocolVersion() + { + int protocolVersion = 42; + BoltChannel channel = mock( BoltChannel.class ); + BoltProtocolHandlerFactory factory = new DefaultBoltProtocolHandlerFactory( mock( WorkerFactory.class ), + TransportThrottleGroup.NO_THROTTLE, NullLogService.getInstance() ); + + BoltMessagingProtocolHandler handler = factory.create( protocolVersion, channel ); + + // handler is not created + assertNull( handler ); + } + + private static void testHandlerCreation( int protocolVersion, + Class expectedHandlerClass ) + { BoltChannel boltChannel = BoltChannel.open( newChannelCtxMock(), NullBoltMessageLogger.getInstance() ); WorkerFactory workerFactory = mock( WorkerFactory.class ); @@ -56,8 +85,9 @@ public void shouldCreateV1Handler() BoltMessagingProtocolHandler handler = factory.create( protocolVersion, boltChannel ); - // handler is actually created - assertNotNull( handler ); + // correct handler handler is created + assertThat( handler, instanceOf( expectedHandlerClass ) ); + assertEquals( protocolVersion, handler.version() ); // it uses the expected worker verify( workerFactory ).newWorker( same( boltChannel ), any() ); @@ -67,20 +97,6 @@ public void shouldCreateV1Handler() verify( worker ).halt(); } - @Test - public void shouldCreateNothingForUnknownProtocolVersion() - { - int protocolVersion = 42; - BoltChannel channel = mock( BoltChannel.class ); - BoltProtocolHandlerFactory factory = new DefaultBoltProtocolHandlerFactory( mock( WorkerFactory.class ), - TransportThrottleGroup.NO_THROTTLE, NullLogService.getInstance() ); - - BoltMessagingProtocolHandler handler = factory.create( protocolVersion, channel ); - - // handler is not created - assertNull( handler ); - } - private static ChannelHandlerContext newChannelCtxMock() { ChannelHandlerContext ctx = mock( ChannelHandlerContext.class ); diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/BoltRequestMessageTest.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/BoltRequestMessageTest.java index fed06a4bed53..9b022ace7600 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/BoltRequestMessageTest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/BoltRequestMessageTest.java @@ -33,9 +33,9 @@ import org.neo4j.kernel.impl.util.HexPrinter; import org.neo4j.kernel.impl.util.ValueUtils; import org.neo4j.values.AnyValue; -import org.neo4j.values.virtual.RelationshipValue; import org.neo4j.values.virtual.MapValue; import org.neo4j.values.virtual.NodeValue; +import org.neo4j.values.virtual.RelationshipValue; import org.neo4j.values.virtual.VirtualValues; import static java.lang.System.lineSeparator; @@ -54,15 +54,17 @@ import static org.neo4j.values.storable.Values.intValue; import static org.neo4j.values.storable.Values.stringArray; import static org.neo4j.values.storable.Values.stringValue; -import static org.neo4j.values.virtual.VirtualValues.relationshipValue; import static org.neo4j.values.virtual.VirtualValues.map; import static org.neo4j.values.virtual.VirtualValues.nodeValue; +import static org.neo4j.values.virtual.VirtualValues.relationshipValue; public class BoltRequestMessageTest { @Rule public ExpectedException exception = ExpectedException.none(); + private final Neo4jPack neo4jPack = new Neo4jPackV1(); + @Test public void shouldHandleCommonMessages() throws Throwable { @@ -116,9 +118,8 @@ public void shouldSerializeRelationship() throws Throwable private String serialized( AnyValue object ) throws IOException { - RecordMessage message = - new RecordMessage( record( object ) ); - return HexPrinter.hex( serialize( message ), 4, " " ); + RecordMessage message = new RecordMessage( record( object ) ); + return HexPrinter.hex( serialize( neo4jPack, message ), 4, " " ); } private void assertSerializes( RequestMessage msg ) throws IOException @@ -129,7 +130,6 @@ private void assertSerializes( RequestMessage msg ) throws IOException private T serializeAndDeserialize( T msg ) throws IOException { RecordingByteChannel channel = new RecordingByteChannel(); - Neo4jPack neo4jPack = new Neo4jPackV1(); BoltRequestMessageReader reader = new BoltRequestMessageReader( neo4jPack.newUnpacker( new BufferedChannelInput( 16 ).reset( channel ) ) ); BoltRequestMessageWriter writer = new BoltRequestMessageWriter( diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/BoltResponseMessageTest.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/BoltResponseMessageTest.java index 7ec1a0c5c1b8..fe81169051e6 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/BoltResponseMessageTest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/BoltResponseMessageTest.java @@ -38,8 +38,8 @@ import org.neo4j.kernel.impl.util.HexPrinter; import org.neo4j.kernel.impl.util.ValueUtils; import org.neo4j.values.AnyValue; -import org.neo4j.values.virtual.RelationshipValue; import org.neo4j.values.virtual.NodeValue; +import org.neo4j.values.virtual.RelationshipValue; import org.neo4j.values.virtual.VirtualValues; import static java.lang.System.lineSeparator; @@ -62,14 +62,16 @@ import static org.neo4j.values.storable.Values.longValue; import static org.neo4j.values.storable.Values.stringArray; import static org.neo4j.values.storable.Values.stringValue; -import static org.neo4j.values.virtual.VirtualValues.relationshipValue; import static org.neo4j.values.virtual.VirtualValues.nodeValue; +import static org.neo4j.values.virtual.VirtualValues.relationshipValue; public class BoltResponseMessageTest { @Rule public ExpectedException exception = ExpectedException.none(); + private final Neo4jPack neo4jPack = new Neo4jPackV1(); + @Test public void shouldHandleCommonMessages() throws Throwable { @@ -213,9 +215,8 @@ public void shouldSerializePaths() throws Throwable private String serialized( AnyValue object ) throws IOException { - RecordMessage message = - new RecordMessage( record( object ) ); - return HexPrinter.hex( serialize( message ), 4, " " ); + RecordMessage message = new RecordMessage( record( object ) ); + return HexPrinter.hex( serialize( neo4jPack, message ), 4, " " ); } private void assertSerializes( ResponseMessage msg ) throws IOException @@ -226,7 +227,6 @@ private void assertSerializes( ResponseMessage msg ) throws IOException private T serializeAndDeserialize( T msg ) throws IOException { RecordingByteChannel channel = new RecordingByteChannel(); - Neo4jPack neo4jPack = new Neo4jPackV1(); BoltResponseMessageReader reader = new BoltResponseMessageReader( neo4jPack.newUnpacker( new BufferedChannelInput( 16 ).reset( channel ) ) ); BoltResponseMessageWriter writer = new BoltResponseMessageWriter( diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/util/MessageMatchers.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/util/MessageMatchers.java index d3c905a85daa..d96728427b34 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/util/MessageMatchers.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/messaging/util/MessageMatchers.java @@ -38,7 +38,6 @@ import org.neo4j.bolt.v1.messaging.BoltResponseMessageRecorder; import org.neo4j.bolt.v1.messaging.BoltResponseMessageWriter; import org.neo4j.bolt.v1.messaging.Neo4jPack; -import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.RecordingByteChannel; import org.neo4j.bolt.v1.messaging.message.FailureMessage; import org.neo4j.bolt.v1.messaging.message.IgnoredMessage; @@ -292,10 +291,9 @@ public void describeTo( Description description ) }; } - public static byte[] serialize( RequestMessage... messages ) throws IOException + public static byte[] serialize( Neo4jPack neo4jPack, RequestMessage... messages ) throws IOException { RecordingByteChannel rawData = new RecordingByteChannel(); - Neo4jPack neo4jPack = new Neo4jPackV1(); Neo4jPack.Packer packer = neo4jPack.newPacker( new BufferedChannelOutput( rawData ) ); BoltRequestMessageWriter writer = new BoltRequestMessageWriter( packer, NO_BOUNDARY_HOOK ); @@ -308,10 +306,9 @@ public static byte[] serialize( RequestMessage... messages ) throws IOException return rawData.getBytes(); } - public static byte[] serialize( ResponseMessage... messages ) throws IOException + public static byte[] serialize( Neo4jPack neo4jPack, ResponseMessage... messages ) throws IOException { RecordingByteChannel rawData = new RecordingByteChannel(); - Neo4jPack neo4jPack = new Neo4jPackV1(); Neo4jPack.Packer packer = neo4jPack.newPacker( new BufferedChannelOutput( rawData ) ); BoltResponseMessageWriter writer = new BoltResponseMessageWriter( packer, NO_BOUNDARY_HOOK, NullBoltMessageLogger.getInstance() ); @@ -325,9 +322,9 @@ public static byte[] serialize( ResponseMessage... messages ) throws IOException return rawData.getBytes(); } - public static ResponseMessage responseMessage( byte[] bytes ) throws IOException + public static ResponseMessage responseMessage( Neo4jPack neo4jPack, byte[] bytes ) throws IOException { - BoltResponseMessageReader unpacker = responseReader( bytes ); + BoltResponseMessageReader unpacker = responseReader( neo4jPack, bytes ); BoltResponseMessageRecorder consumer = new BoltResponseMessageRecorder(); try @@ -342,11 +339,10 @@ public static ResponseMessage responseMessage( byte[] bytes ) throws IOException } } - private static BoltResponseMessageReader responseReader( byte[] bytes ) + private static BoltResponseMessageReader responseReader( Neo4jPack neo4jPack, byte[] bytes ) { BufferedChannelInput input = new BufferedChannelInput( 128 ); input.reset( new ArrayByteChannel( bytes ) ); - Neo4jPack neo4jPack = new Neo4jPackV1(); return new BoltResponseMessageReader( neo4jPack.newUnpacker( input ) ); } diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/integration/BoltConfigIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/integration/BoltConfigIT.java index 5db304f3d594..fcb4538ef804 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/integration/BoltConfigIT.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/integration/BoltConfigIT.java @@ -22,6 +22,7 @@ import org.junit.Rule; import org.junit.Test; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.message.InitMessage; import org.neo4j.bolt.v1.transport.integration.Neo4jWithSocket; import org.neo4j.bolt.v1.transport.integration.TransportTestUtil; @@ -60,6 +61,8 @@ public class BoltConfigIT @Rule public SuppressOutput suppressOutput = SuppressOutput.suppressAll(); + private final TransportTestUtil util = new TransportTestUtil( new Neo4jPackV1() ); + @Test public void shouldSupportMultipleConnectors() throws Throwable { @@ -84,7 +87,7 @@ public void shouldSupportMultipleConnectors() throws Throwable private void assertConnectionRejected( HostnamePort address, TransportConnection client ) throws Exception { client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ); assertThat( client, eventuallyDisconnects() ); } @@ -92,8 +95,8 @@ private void assertConnectionRejected( HostnamePort address, TransportConnection private void assertConnectionAccepted( HostnamePort address, TransportConnection client ) throws Exception { client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( InitMessage.init( "TestClient/1.1", emptyMap() ) ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", emptyMap() ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); } } diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/BoltMessagingProtocolV1HandlerTest.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/BoltMessagingProtocolV1HandlerTest.java index b60fd3c2c624..c4ef3a516900 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/BoltMessagingProtocolV1HandlerTest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/BoltMessagingProtocolV1HandlerTest.java @@ -29,8 +29,8 @@ import java.util.Objects; import org.neo4j.bolt.BoltChannel; +import org.neo4j.bolt.transport.BoltMessagingProtocolHandler; import org.neo4j.bolt.transport.TransportThrottleGroup; -import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.runtime.BoltStateMachine; import org.neo4j.bolt.v1.runtime.BoltWorker; import org.neo4j.bolt.v1.runtime.SynchronousBoltWorker; @@ -40,6 +40,7 @@ import org.neo4j.logging.NullLogProvider; import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.RETURNS_MOCKS; import static org.mockito.Mockito.doReturn; @@ -61,7 +62,7 @@ public void shouldNotTalkToChannelDirectlyOnFatalError() when( boltChannel.rawChannel() ).thenReturn( outputChannel ); BoltStateMachine machine = mock( BoltStateMachine.class ); - BoltMessagingProtocolV1Handler protocol = new BoltMessagingProtocolV1Handler( boltChannel, new Neo4jPackV1(), + BoltMessagingProtocolV1Handler protocol = new BoltMessagingProtocolV1Handler( boltChannel, new SynchronousBoltWorker( machine ), TransportThrottleGroup.NO_THROTTLE, NullLogService.getInstance() ); verify( outputChannel ).alloc(); @@ -95,7 +96,7 @@ public void closesInputAndOutput() BoltChannel boltChannel = mock( BoltChannel.class ); when( boltChannel.rawChannel() ).thenReturn( outputChannel ); - BoltMessagingProtocolV1Handler protocol = new BoltMessagingProtocolV1Handler( boltChannel, new Neo4jPackV1(), + BoltMessagingProtocolV1Handler protocol = new BoltMessagingProtocolV1Handler( boltChannel, new SynchronousBoltWorker( machine ), TransportThrottleGroup.NO_THROTTLE, NullLogService.getInstance() ); protocol.close(); @@ -117,7 +118,7 @@ public void messageProcessingErrorIsLogged() BoltChannel boltChannel = mock( BoltChannel.class ); when( boltChannel.rawChannel() ).thenReturn( outputChannel ); - BoltMessagingProtocolV1Handler protocol = new BoltMessagingProtocolV1Handler( boltChannel, new Neo4jPackV1(), + BoltMessagingProtocolV1Handler protocol = new BoltMessagingProtocolV1Handler( boltChannel, mock( BoltWorker.class ), TransportThrottleGroup.NO_THROTTLE, logService ); protocol.handle( mock( ChannelHandlerContext.class ), data ); @@ -128,6 +129,16 @@ public void messageProcessingErrorIsLogged() equalTo( error ) ) ); } + @Test + public void shouldHaveCorrectVersion() + { + BoltMessagingProtocolHandler handler = new BoltMessagingProtocolV1Handler( + mock( BoltChannel.class, RETURNS_MOCKS ), mock( BoltWorker.class ), TransportThrottleGroup.NO_THROTTLE, + NullLogService.getInstance() ); + + assertEquals( 1, handler.version() ); + } + private static ByteBuf newThrowingByteBuf( RuntimeException exceptionToThrow ) { Objects.requireNonNull( exceptionToThrow ); diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/BoltV1DechunkerTest.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/BoltV1DechunkerTest.java index 7afb602584e0..edac34048de2 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/BoltV1DechunkerTest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/BoltV1DechunkerTest.java @@ -25,6 +25,7 @@ import java.util.concurrent.ThreadLocalRandom; import org.neo4j.bolt.v1.messaging.BoltRequestMessageRecorder; +import org.neo4j.bolt.v1.messaging.Neo4jPack; import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.message.RunMessage; import org.neo4j.bolt.v1.messaging.util.MessageMatchers; @@ -39,6 +40,7 @@ public class BoltV1DechunkerTest @Test public void shouldReadMessageWhenTheHeaderIsSplitAcrossChunks() throws Exception { + Neo4jPack neo4jPack = new Neo4jPackV1(); Random random = ThreadLocalRandom.current(); for ( int len = 1; len <= 0x8000; len = len << 1 ) { @@ -49,7 +51,7 @@ public void shouldReadMessageWhenTheHeaderIsSplitAcrossChunks() throws Exception content.appendCodePoint( 'a' + random.nextInt( 'z' - 'a' ) ); } RunMessage run = run( content.toString() ); - byte[] message = MessageMatchers.serialize( run ); + byte[] message = MessageMatchers.serialize( neo4jPack, run ); byte head1 = (byte) (message.length >> 8); byte head2 = (byte) (message.length & 0xFF); byte[] chunk2 = new byte[message.length + 3]; @@ -57,7 +59,7 @@ public void shouldReadMessageWhenTheHeaderIsSplitAcrossChunks() throws Exception System.arraycopy( message, 0, chunk2, 1, message.length ); BoltRequestMessageRecorder messages = new BoltRequestMessageRecorder(); - BoltV1Dechunker dechunker = new BoltV1Dechunker( new Neo4jPackV1(), messages, () -> + BoltV1Dechunker dechunker = new BoltV1Dechunker( neo4jPack, messages, () -> { } ); diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/AuthenticationIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/AuthenticationIT.java index 66cffa5ca8e8..e9e18adb5513 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/AuthenticationIT.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/AuthenticationIT.java @@ -36,6 +36,7 @@ import java.util.Map; import java.util.function.Consumer; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.message.AckFailureMessage; import org.neo4j.bolt.v1.messaging.message.FailureMessage; import org.neo4j.bolt.v1.messaging.message.InitMessage; @@ -98,6 +99,7 @@ protected Consumer> getSettingsFunction() private HostnamePort address; private TransportConnection client; private final String version = "Neo4j/" + Version.getNeo4jVersion(); + private final TransportTestUtil util = new TransportTestUtil( new Neo4jPackV1() ); @Parameterized.Parameters public static Collection> transports() @@ -127,22 +129,22 @@ public void shouldRespondWithCredentialsExpiredOnFirstUse() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); + assertThat( client, util.eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); verifyConnectionOpen(); } private void verifyConnectionOpen() throws IOException { - client.send( TransportTestUtil.chunk( ResetMessage.reset() ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + client.send( util.chunk( ResetMessage.reset() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } @Test @@ -150,14 +152,14 @@ public void shouldFailIfWrongCredentials() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "wrong", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "The client is unauthorized due to authentication failure." ) ) ); assertThat( client, eventuallyDisconnects() ); @@ -168,37 +170,37 @@ public void shouldFailIfWrongCredentialsFollowingSuccessfulLogin() throws Throwa { // When change password client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "new_credentials", "secret", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); // When login again with the new password reconnect(); client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "secret", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); // When login again with the wrong password reconnect(); client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "wrong", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "The client is unauthorized due to authentication failure." ) ) ); assertThat( client, eventuallyDisconnects() ); @@ -209,15 +211,15 @@ public void shouldFailIfMalformedAuthTokenWrongType() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", singletonList( "neo4j" ), "credentials", "neo4j", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "Unsupported authentication token, the value associated with the key `principal` " + "must be a String but was: ArrayList" ) ) ); @@ -229,15 +231,15 @@ public void shouldFailIfMalformedAuthTokenMissingKey() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "this-should-have-been-credentials", "neo4j", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "Unsupported authentication token, missing key `credentials`" ) ) ); assertThat( client, eventuallyDisconnects() ); @@ -248,14 +250,14 @@ public void shouldFailIfMalformedAuthTokenMissingScheme() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "Unsupported authentication token, missing key `scheme`" ) ) ); assertThat( client, eventuallyDisconnects() ); @@ -266,15 +268,15 @@ public void shouldFailIfMalformedAuthTokenUnknownScheme() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "unknown" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "Unsupported authentication token, scheme 'unknown' is not supported." ) ) ); assertThat( client, eventuallyDisconnects() ); @@ -292,14 +294,14 @@ public void shouldFailDifferentlyIfTooManyFailedAuthAttempts() throws Exception { // Done in a loop because we're racing with the clock to get enough failed requests in 5 seconds client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "WHAT_WAS_THE_PASSWORD_AGAIN", "scheme", "basic" ) ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( failureMatcher ) ); + assertThat( client, util.eventuallyReceives( failureMatcher ) ); assertThat( client, eventuallyDisconnects() ); reconnect(); @@ -316,35 +318,35 @@ public void shouldBeAbleToUpdateCredentials() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "new_credentials", "secret", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); // If I reconnect I cannot use the old password reconnect(); client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "basic" ) ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "The client is unauthorized due to authentication failure." ) ) ); // But the new password works fine reconnect(); client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "secret", "scheme", "basic" ) ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } @Test @@ -352,22 +354,22 @@ public void shouldBeAuthenticatedAfterUpdatingCredentials() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "new_credentials", "secret", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( RunMessage.run( "MATCH (n) RETURN n" ), PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } @Test @@ -375,43 +377,43 @@ public void shouldBeAbleToChangePasswordUsingBuiltInProcedure() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); + assertThat( client, util.eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( RunMessage.run( "CALL dbms.security.changePassword", singletonMap( "password", "secret" ) ), PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); // If I reconnect I cannot use the old password reconnect(); client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "basic" ) ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "The client is unauthorized due to authentication failure." ) ) ); // But the new password works fine reconnect(); client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "secret", "scheme", "basic" ) ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } @Test @@ -419,30 +421,30 @@ public void shouldBeAuthenticatedAfterChangePasswordUsingBuiltInProcedure() thro { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); + assertThat( client, util.eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( RunMessage.run( "CALL dbms.security.changePassword", singletonMap( "password", "secret" ) ), PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( RunMessage.run( "MATCH (n) RETURN n" ), PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } @Test @@ -450,30 +452,30 @@ public void shouldFailWhenReusingTheSamePassword() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); + assertThat( client, util.eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( RunMessage.run( "CALL dbms.security.changePassword", singletonMap( "password", "neo4j" ) ), PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgFailure( Status.General.InvalidArguments, + assertThat( client, util.eventuallyReceives( msgFailure( Status.General.InvalidArguments, "Old password and new password cannot be the same." ) ) ); // However you should also be able to recover - client.send( TransportTestUtil.chunk( + client.send( util.chunk( AckFailureMessage.ackFailure(), RunMessage.run( "CALL dbms.security.changePassword", singletonMap( "password", "abc" ) ), PullAllMessage.pullAll() ) ); - assertThat( client, eventuallyReceives( msgIgnored(), msgSuccess(), msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgIgnored(), msgSuccess(), msgSuccess(), msgSuccess() ) ); } @Test @@ -481,30 +483,30 @@ public void shouldFailWhenSubmittingEmptyPassword() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); + assertThat( client, util.eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( RunMessage.run( "CALL dbms.security.changePassword", singletonMap( "password", "" ) ), PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgFailure( Status.General.InvalidArguments, + assertThat( client, util.eventuallyReceives( msgFailure( Status.General.InvalidArguments, "A password cannot be empty." ) ) ); // However you should also be able to recover - client.send( TransportTestUtil.chunk( + client.send( util.chunk( AckFailureMessage.ackFailure(), RunMessage.run( "CALL dbms.security.changePassword", singletonMap( "password", "abc" ) ), PullAllMessage.pullAll() ) ); - assertThat( client, eventuallyReceives( msgIgnored(), msgSuccess(), msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgIgnored(), msgSuccess(), msgSuccess(), msgSuccess() ) ); } @Test @@ -512,22 +514,22 @@ public void shouldNotBeAbleToReadWhenPasswordChangeRequired() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( "principal", "neo4j", "credentials", "neo4j", "scheme", "basic" ) ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); + assertThat( client, util.eventuallyReceives( msgSuccess( map( "credentials_expired", true, "server", version ) ) ) ); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( RunMessage.run( "MATCH (n) RETURN n" ), PullAllMessage.pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgFailure( Status.Security.CredentialsExpired, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.CredentialsExpired, "The credentials you provided were valid, but must be changed before you can use this instance." ) ) ); assertThat( client, eventuallyDisconnects() ); diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/ConcurrentAccessIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/ConcurrentAccessIT.java index 6cc846d15f29..32a1590d44f2 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/ConcurrentAccessIT.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/ConcurrentAccessIT.java @@ -34,6 +34,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.message.InitMessage; import org.neo4j.bolt.v1.transport.socket.client.SecureSocketConnection; import org.neo4j.bolt.v1.transport.socket.client.SecureWebSocketConnection; @@ -55,8 +56,6 @@ import static org.neo4j.bolt.v1.messaging.message.PullAllMessage.pullAll; import static org.neo4j.bolt.v1.messaging.message.RunMessage.run; import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgSuccess; -import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.acceptedVersions; -import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.chunk; import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyReceives; /** @@ -73,6 +72,8 @@ public class ConcurrentAccessIT @Parameterized.Parameter public Factory cf; + private final TransportTestUtil util = new TransportTestUtil( new Neo4jPackV1() ); + @Parameterized.Parameters public static Collection> transports() { @@ -119,13 +120,13 @@ private Callable newWorker( final int iterationsToRun ) throws Exception { return new Callable() { - private final byte[] init = chunk( InitMessage.init( "TestClient", emptyMap() ) ); - private final byte[] createAndRollback = chunk( + private final byte[] init = util.chunk( InitMessage.init( "TestClient", emptyMap() ) ); + private final byte[] createAndRollback = util.chunk( run( "BEGIN" ), pullAll(), run( "CREATE (n)" ), pullAll(), run( "ROLLBACK" ), pullAll() ); - private final byte[] matchAll = chunk( + private final byte[] matchAll = util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ); @Override @@ -133,7 +134,7 @@ public Void call() throws Exception { // Connect TransportConnection client = cf.newInstance(); - client.connect( server.lookupDefaultConnector() ).send( acceptedVersions( 1, 0, 0, 0 ) ); + client.connect( server.lookupDefaultConnector() ).send( util.acceptedVersions( 1, 0, 0, 0 ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); init( client ); @@ -149,15 +150,13 @@ public Void call() throws Exception private void init( TransportConnection client ) throws Exception { client.send( init ); - assertThat( client, eventuallyReceives( - msgSuccess() - ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } private void createAndRollback( TransportConnection client ) throws Exception { client.send( createAndRollback ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess( CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( emptyList() ) ), hasKey( "result_available_after" ) ) ), msgSuccess(), @@ -170,7 +169,7 @@ private void createAndRollback( TransportConnection client ) throws Exception // Verify no visible data client.send( matchAll ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( singletonList( "n" ) ) ), hasKey( "result_available_after" ) ) ), msgSuccess() ) ); diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/RejectTransportEncryptionIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/RejectTransportEncryptionIT.java index 77ff93eaebd3..091877daceb5 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/RejectTransportEncryptionIT.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/RejectTransportEncryptionIT.java @@ -31,6 +31,7 @@ import java.io.IOException; import java.util.Collection; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.transport.socket.client.SecureSocketConnection; import org.neo4j.bolt.v1.transport.socket.client.SecureWebSocketConnection; import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; @@ -61,6 +62,7 @@ public class RejectTransportEncryptionIT public Exception expected; private TransportConnection client; + private TransportTestUtil util; @Parameterized.Parameters public static Collection transports() @@ -82,6 +84,7 @@ public static Collection transports() public void setup() { this.client = cf.newInstance(); + this.util = new TransportTestUtil( new Neo4jPackV1() ); } @After @@ -98,6 +101,6 @@ public void shouldRejectConnectionAfterHandshake() throws Throwable { exception.expect( expected.getClass() ); exception.expectMessage( expected.getMessage() ); - client.connect( server.lookupDefaultConnector() ).send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ); + client.connect( server.lookupDefaultConnector() ).send( util.acceptedVersions( 1, 0, 0, 0 ) ); } } diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/RequiredTransportEncryptionIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/RequiredTransportEncryptionIT.java index e509e144e73f..25b5f12605c4 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/RequiredTransportEncryptionIT.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/RequiredTransportEncryptionIT.java @@ -28,6 +28,7 @@ import java.util.Collection; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.transport.socket.client.SocketConnection; import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; import org.neo4j.bolt.v1.transport.socket.client.WebSocketConnection; @@ -58,6 +59,7 @@ public class RequiredTransportEncryptionIT private HostnamePort address; private TransportConnection client; + private TransportTestUtil util; @Parameterized.Parameters public static Collection> transports() @@ -70,6 +72,7 @@ public void setup() { this.client = cf.newInstance(); this.address = server.lookupDefaultConnector(); + this.util = new TransportTestUtil( new Neo4jPackV1() ); } @After @@ -86,7 +89,7 @@ public void shouldCloseUnencryptedConnectionOnHandshakeWhenEncryptionIsRequired( { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ); assertThat( client, TransportTestUtil.eventuallyDisconnects() ); } diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportErrorIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportErrorIT.java index 42ca5b0553b5..6c466f8a2cc1 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportErrorIT.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportErrorIT.java @@ -29,6 +29,7 @@ import java.util.Arrays; import java.util.Collection; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.RecordingByteChannel; import org.neo4j.bolt.v1.packstream.BufferedChannelOutput; import org.neo4j.bolt.v1.packstream.PackStream; @@ -45,8 +46,6 @@ import static org.neo4j.bolt.v1.messaging.BoltRequestMessage.RUN; import static org.neo4j.bolt.v1.messaging.message.RunMessage.run; import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.serialize; -import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.acceptedVersions; -import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.chunk; import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyDisconnects; import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyReceives; @@ -61,6 +60,7 @@ public class TransportErrorIT private HostnamePort address; private TransportConnection client; + private TransportTestUtil util; @Parameterized.Parameters public static Collection> transports() @@ -74,6 +74,7 @@ public void setup() { this.client = cf.newInstance(); this.address = server.lookupDefaultConnector(); + this.util = new TransportTestUtil( new Neo4jPackV1() ); } @After @@ -89,13 +90,13 @@ public void tearDown() throws Exception public void shouldHandleIncorrectFraming() throws Throwable { // Given I have a message that gets truncated in the chunking, so part of it is missing - byte[] truncated = serialize( run( "UNWIND [1,2,3] AS a RETURN a, a * a AS a_squared" ) ); + byte[] truncated = serialize( util.getNeo4jPack(), run( "UNWIND [1,2,3] AS a RETURN a, a * a AS a_squared" ) ); truncated = Arrays.copyOf(truncated, truncated.length - 12); // When client.connect( address ) - .send( acceptedVersions( 1, 0, 0, 0 ) ) - .send( chunk( 32, truncated ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( 32, truncated ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); @@ -118,8 +119,8 @@ public void shouldHandleMessagesWithIncorrectFields() throws Throwable // When client.connect( address ) - .send( acceptedVersions( 1, 0, 0, 0 ) ) - .send( chunk( 32, invalidMessage ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( 32, invalidMessage ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); @@ -141,8 +142,8 @@ public void shouldHandleUnknownMessages() throws Throwable // When client.connect( address ) - .send( acceptedVersions( 1, 0, 0, 0 ) ) - .send( chunk( 32, invalidMessage ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( 32, invalidMessage ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); @@ -165,8 +166,8 @@ public void shouldHandleUnknownMarkerBytes() throws Throwable // When client.connect( address ) - .send( acceptedVersions( 1, 0, 0, 0 ) ) - .send( chunk( 32, invalidMessage ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( 32, invalidMessage ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportSessionIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportSessionIT.java index d137a7e700a2..5b0e44831ecf 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportSessionIT.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportSessionIT.java @@ -31,6 +31,7 @@ import java.util.Collection; import java.util.HashMap; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.transport.socket.client.SecureSocketConnection; import org.neo4j.bolt.v1.transport.socket.client.SecureWebSocketConnection; import org.neo4j.bolt.v1.transport.socket.client.SocketConnection; @@ -80,8 +81,8 @@ public class TransportSessionIT public Factory cf; private HostnamePort address; - private TransportConnection client; + private TransportTestUtil util; @Parameterized.Parameters public static Collection> transports() @@ -95,6 +96,7 @@ public void setup() { this.client = cf.newInstance(); this.address = server.lookupDefaultConnector(); + this.util = new TransportTestUtil( new Neo4jPackV1() ); } @After @@ -111,7 +113,7 @@ public void shouldNegotiateProtocolVersion() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); @@ -122,7 +124,7 @@ public void shouldReturnNilOnNoApplicableVersion() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1337, 0, 0, 0 ) ); + .send( util.acceptedVersions( 1337, 0, 0, 0 ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 0} ) ); @@ -133,15 +135,15 @@ public void shouldRunSimpleStatement() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "UNWIND [1,2,3] AS a RETURN a, a * a AS a_squared" ), pullAll() ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess( CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( asList( "a", "a_squared" ) ) ), hasKey( "result_available_after" ) ) ), @@ -157,15 +159,15 @@ public void shouldRespondWithMetadataToDiscardAll() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "UNWIND [1,2,3] AS a RETURN a, a * a AS a_squared" ), discardAll() ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess( CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( asList( "a", "a_squared" ) ) ), @@ -179,14 +181,14 @@ public void shouldBeAbleToRunQueryAfterAckFailure() throws Throwable { // Given client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "QINVALID" ), pullAll() ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgFailure( Status.Statement.SyntaxError, String.format( "Invalid input 'Q': expected (line 1, column 1 (offset: 0))%n" + @@ -194,10 +196,10 @@ public void shouldBeAbleToRunQueryAfterAckFailure() throws Throwable " ^" ) ), msgIgnored() ) ); // When - client.send( TransportTestUtil.chunk( ackFailure(), run( "RETURN 1" ), pullAll() ) ); + client.send( util.chunk( ackFailure(), run( "RETURN 1" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess(), msgRecord( eqRecord( equalTo( longValue( 1L ) ) ) ), @@ -209,14 +211,14 @@ public void shouldRunProcedure() throws Throwable { // Given client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "CREATE (n:Test {age: 2}) RETURN n.age AS age" ), pullAll() ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess( CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( singletonList( "age" ) ) ), hasKey( "result_available_after" ) ) ), @@ -224,12 +226,12 @@ public void shouldRunProcedure() throws Throwable msgSuccess() ) ); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CALL db.labels() YIELD label" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess( CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( singletonList( "label" ) ) ), hasKey( "result_available_after" ) ) ), msgRecord( eqRecord( Matchers.equalTo( stringValue( "Test" ) ) ) ), @@ -242,15 +244,15 @@ public void shouldHandleDeletedNodes() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "CREATE (n:Test) DELETE n RETURN n" ), pullAll() ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess( CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( singletonList( "n" ) ) ), hasKey( "result_available_after" ) ) ) ) ); @@ -265,7 +267,7 @@ public void shouldHandleDeletedNodes() throws Throwable assertThat( client, eventuallyReceives( bytes( 0x00, 0x08, 0xB1, 0x71, 0x91, 0xB3, 0x4E, 0x00, 0x90, 0xA0, 0x00, 0x00 ) ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } @Test @@ -273,15 +275,15 @@ public void shouldHandleDeletedRelationships() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "CREATE ()-[r:T {prop: 42}]->() DELETE r RETURN r" ), pullAll() ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess( CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( singletonList( "r" ) ) ), hasKey( "result_available_after" ) ) ) ) ); @@ -298,7 +300,7 @@ public void shouldHandleDeletedRelationships() throws Throwable assertThat( client, eventuallyReceives( bytes( 0x00, 0x0B, 0xB1, 0x71, 0x91, 0xB5, 0x52, 0x00, 0x00, 0x01, 0x81, 0x54, 0xA0, 0x00, 0x00 ) ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } @Test @@ -306,25 +308,25 @@ public void shouldNotLeakStatsToNextStatement() throws Throwable { // Given client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "CREATE (n)" ), pullAll() ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess(), msgSuccess() ) ); // When client.send( - TransportTestUtil.chunk( + util.chunk( run( "RETURN 1" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgRecord( eqRecord( equalTo( longValue( 1L ) ) ) ), msgSuccess( CoreMatchers.allOf( hasEntry( is( "type" ), equalTo( "r" ) ), @@ -336,15 +338,15 @@ public void shouldSendNotifications() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "EXPLAIN MATCH (a:THIS_IS_NOT_A_LABEL) RETURN count(*)" ), pullAll() ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess(), hasNotification( @@ -363,15 +365,15 @@ public void shouldFailNicelyOnPoints() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "RETURN point({x:13, y:37, crs:'cartesian'}) as p" ), pullAll() ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess( CoreMatchers.allOf( hasEntry( is( "fields" ), equalTo( singletonList( "p" ) ) ), hasKey( "result_available_after" ) ) ), @@ -401,24 +403,24 @@ public void shouldFailNicelyOnNullKeysInMap() throws Throwable // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "RETURN {p}", ValueUtils.asMapValue( params ) ), pullAll() ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgFailure( Status.Request.Invalid, "Value `null` is not supported as key in maps, must be a non-nullable string." ), msgIgnored() ) ); - client.send( TransportTestUtil.chunk( ackFailure(), run( "RETURN 1" ), pullAll() ) ); + client.send( util.chunk( ackFailure(), run( "RETURN 1" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess(), msgRecord( eqRecord( equalTo( longValue( 1L ) ) ) ), @@ -430,15 +432,15 @@ public void shouldFailNicelyWhenDroppingUnknownIndex() throws Throwable { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", emptyMap() ), run( "DROP INDEX on :Movie12345(id)" ), pullAll() ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgFailure( Status.Schema.IndexDropFailed, "Unable to drop index on :Movie12345(id): No such INDEX ON :Movie12345(id)." ), diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportTestUtil.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportTestUtil.java index f2f24549947e..e4d683dad73b 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportTestUtil.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/integration/TransportTestUtil.java @@ -26,11 +26,11 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.util.Arrays; import java.util.concurrent.TimeUnit; import java.util.function.BooleanSupplier; +import org.neo4j.bolt.v1.messaging.Neo4jPack; import org.neo4j.bolt.v1.messaging.message.RequestMessage; import org.neo4j.bolt.v1.messaging.message.ResponseMessage; import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; @@ -41,65 +41,53 @@ import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.responseMessage; import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.serialize; -@SuppressWarnings( "unchecked" ) public class TransportTestUtil { - private TransportTestUtil() + private final Neo4jPack neo4jPack; + + public TransportTestUtil( Neo4jPack neo4jPack ) { + this.neo4jPack = neo4jPack; } - public static byte[] dechunk( byte[] chunked ) throws IOException + public Neo4jPack getNeo4jPack() { - ByteBuffer in = ByteBuffer.wrap( chunked ); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - while ( in.hasRemaining() ) - { - int chunkSize = in.getShort(); - if ( chunkSize == 0 ) - { - continue; - } - - byte[] chunk = new byte[chunkSize]; - in.get( chunk ); - out.write( chunk ); - } - return out.toByteArray(); + return neo4jPack; } - public static byte[] chunk( RequestMessage... messages ) throws IOException + public byte[] chunk( RequestMessage... messages ) throws IOException { return chunk( 32, messages ); } - public static byte[] chunk( ResponseMessage... messages ) throws IOException + public byte[] chunk( ResponseMessage... messages ) throws IOException { return chunk( 32, messages ); } - public static byte[] chunk( int chunkSize, RequestMessage... messages ) throws IOException + public byte[] chunk( int chunkSize, RequestMessage... messages ) throws IOException { byte[][] serializedMessages = new byte[messages.length][]; for ( int i = 0; i < messages.length; i++ ) { - serializedMessages[i] = serialize( messages[i] ); + serializedMessages[i] = serialize( neo4jPack, messages[i] ); } return chunk( chunkSize, serializedMessages ); } - public static byte[] chunk( int chunkSize, ResponseMessage... messages ) throws IOException + public byte[] chunk( int chunkSize, ResponseMessage... messages ) throws IOException { byte[][] serializedMessages = new byte[messages.length][]; for ( int i = 0; i < messages.length; i++ ) { - serializedMessages[i] = serialize( messages[i] ); + serializedMessages[i] = serialize( neo4jPack, messages[i] ); } return chunk( chunkSize, serializedMessages ); } - public static byte[] chunk( int chunkSize, byte[] ... messages ) + public byte[] chunk( int chunkSize, byte[]... messages ) { - ByteBuffer output = ByteBuffer.allocate( 10000 ).order( ByteOrder.BIG_ENDIAN ); + ByteBuffer output = ByteBuffer.allocate( 10000 ).order( BIG_ENDIAN ); for ( byte[] wholeMessage : messages ) { @@ -124,7 +112,7 @@ public static byte[] chunk( int chunkSize, byte[] ... messages ) return arrayOutput; } - public static byte[] acceptedVersions( long option1, long option2, long option3, long option4 ) + public byte[] acceptedVersions( long option1, long option2, long option3, long option4 ) { ByteBuffer bb = ByteBuffer.allocate( 5 * Integer.BYTES ).order( BIG_ENDIAN ); bb.putInt( 0x6060B017 ); @@ -135,7 +123,8 @@ public static byte[] acceptedVersions( long option1, long option2, long option3, return bb.array(); } - public static Matcher eventuallyReceives( final Matcher... messages ) + @SafeVarargs + public final Matcher eventuallyReceives( final Matcher... messages ) { return new TypeSafeMatcher() { @@ -165,7 +154,7 @@ public void describeTo( Description description ) }; } - public static ResponseMessage receiveOneResponseMessage( TransportConnection conn ) throws IOException, + public ResponseMessage receiveOneResponseMessage( TransportConnection conn ) throws IOException, InterruptedException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); @@ -180,12 +169,12 @@ public static ResponseMessage receiveOneResponseMessage( TransportConnection con } else { - return responseMessage( bytes.toByteArray() ); + return responseMessage( neo4jPack, bytes.toByteArray() ); } } } - public static int receiveChunkHeader( TransportConnection conn ) throws IOException, InterruptedException + public int receiveChunkHeader( TransportConnection conn ) throws IOException, InterruptedException { byte[] raw = conn.recv( 2 ); return ((raw[0] & 0xff) << 8 | (raw[1] & 0xff)) & 0xffff; @@ -195,12 +184,15 @@ public static Matcher eventuallyReceives( final byte[] expe { return new TypeSafeMatcher() { + byte[] received; + @Override protected boolean matchesSafely( TransportConnection item ) { try { - return Arrays.equals( item.recv( expected.length ), expected ); + received = item.recv( expected.length ); + return Arrays.equals( received, expected ); } catch ( Exception e ) { @@ -211,7 +203,20 @@ protected boolean matchesSafely( TransportConnection item ) @Override public void describeTo( Description description ) { - description.appendValueList( "RawBytes[", ",", "]", expected ); + description.appendText( "to receive " ); + appendBytes( description, expected ); + } + + @Override + protected void describeMismatchSafely( TransportConnection item, Description mismatchDescription ) + { + mismatchDescription.appendText( "received " ); + appendBytes( mismatchDescription, received ); + } + + void appendBytes( Description description, byte[] bytes ) + { + description.appendValueList( "RawBytes[", ",", "]", bytes ); } }; } diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/socket/FragmentedMessageDeliveryTest.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/socket/FragmentedMessageDeliveryTest.java index a7e42f9547db..1d17bb89f6c3 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/socket/FragmentedMessageDeliveryTest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/socket/FragmentedMessageDeliveryTest.java @@ -124,7 +124,7 @@ private void testPermutation( byte[] unfragmented, ByteBuf[] fragments ) throws when( boltChannel.rawChannel() ).thenReturn( ch ); when( boltChannel.log() ).thenReturn( NullBoltMessageLogger.getInstance() ); - BoltMessagingProtocolV1Handler protocol = new BoltMessagingProtocolV1Handler( boltChannel, new Neo4jPackV1(), + BoltMessagingProtocolV1Handler protocol = new BoltMessagingProtocolV1Handler( boltChannel, new SynchronousBoltWorker( machine ), TransportThrottleGroup.NO_THROTTLE, NullLogService.getInstance() ); diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/socket/SocketTransportHandlerTest.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/socket/SocketTransportHandlerTest.java index 8f635dd7882c..f3cca61846a6 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/socket/SocketTransportHandlerTest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/transport/socket/SocketTransportHandlerTest.java @@ -31,7 +31,6 @@ import org.neo4j.bolt.transport.BoltProtocolHandlerFactory; import org.neo4j.bolt.transport.SocketTransportHandler; import org.neo4j.bolt.transport.TransportThrottleGroup; -import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.runtime.BoltStateMachine; import org.neo4j.bolt.v1.runtime.SynchronousBoltWorker; import org.neo4j.bolt.v1.transport.BoltMessagingProtocolV1Handler; @@ -204,7 +203,7 @@ private static BoltHandshakeProtocolHandler newHandshakeHandler( BoltStateMachin BoltProtocolHandlerFactory handlerFactory = ( version, channel ) -> { assertEquals( 1, version ); - return new BoltMessagingProtocolV1Handler( channel, new Neo4jPackV1(), new SynchronousBoltWorker( machine ), + return new BoltMessagingProtocolV1Handler( channel, new SynchronousBoltWorker( machine ), TransportThrottleGroup.NO_THROTTLE, NullLogService.getInstance() ); }; diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v2/messaging/Neo4jPackV2Test.java b/community/bolt/src/test/java/org/neo4j/bolt/v2/messaging/Neo4jPackV2Test.java new file mode 100644 index 000000000000..f48609ecbabf --- /dev/null +++ b/community/bolt/src/test/java/org/neo4j/bolt/v2/messaging/Neo4jPackV2Test.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.bolt.v2.messaging; + +import org.junit.Test; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; + +import org.neo4j.bolt.v1.messaging.Neo4jPack; +import org.neo4j.bolt.v1.packstream.PackedInputArray; +import org.neo4j.bolt.v1.packstream.PackedOutputArray; +import org.neo4j.values.AnyValue; +import org.neo4j.values.storable.PointValue; + +import static java.util.stream.Collectors.toList; +import static org.junit.Assert.assertEquals; +import static org.neo4j.values.storable.CoordinateReferenceSystem.Cartesian; +import static org.neo4j.values.storable.CoordinateReferenceSystem.WGS84; +import static org.neo4j.values.storable.Values.pointValue; + +public class Neo4jPackV2Test +{ + @Test + public void shouldPackAndUnpackPoints() throws IOException + { + testPackingAndUnpackingOfPoints( 2 ); + testPackingAndUnpackingOfPoints( 3 ); + testPackingAndUnpackingOfPoints( 10 ); + } + + private static void testPackingAndUnpackingOfPoints( int dimension ) throws IOException + { + List points = IntStream.range( 0, 1000 ) + .mapToObj( index -> index % 2 == 0 ? WGS84 : Cartesian ) + .map( crs -> pointValue( crs, ThreadLocalRandom.current().doubles( dimension ).toArray() ) ) + .collect( toList() ); + + for ( PointValue original : points ) + { + PointValue unpacked = packAndUnpack( original ); + + String message = "Failed on " + original; + assertEquals( message, original.getCoordinateReferenceSystem(), unpacked.getCoordinateReferenceSystem() ); + assertEquals( message, original.getCoordinate(), unpacked.getCoordinate() ); + } + } + + @SuppressWarnings( "unchecked" ) + private static T packAndUnpack( T value ) throws IOException + { + Neo4jPackV2 neo4jPack = new Neo4jPackV2(); + + PackedOutputArray output = new PackedOutputArray(); + Neo4jPack.Packer packer = neo4jPack.newPacker( output ); + + packer.pack( value ); + + PackedInputArray input = new PackedInputArray( output.bytes() ); + Neo4jPack.Unpacker unpacker = neo4jPack.newUnpacker( input ); + + return (T) unpacker.unpack(); + } +} diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v2/transport/BoltMessagingProtocolV2HandlerTest.java b/community/bolt/src/test/java/org/neo4j/bolt/v2/transport/BoltMessagingProtocolV2HandlerTest.java new file mode 100644 index 000000000000..0c069ee75fa2 --- /dev/null +++ b/community/bolt/src/test/java/org/neo4j/bolt/v2/transport/BoltMessagingProtocolV2HandlerTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.bolt.v2.transport; + +import org.junit.Test; + +import org.neo4j.bolt.BoltChannel; +import org.neo4j.bolt.transport.BoltMessagingProtocolHandler; +import org.neo4j.bolt.transport.TransportThrottleGroup; +import org.neo4j.bolt.v1.runtime.BoltWorker; +import org.neo4j.kernel.impl.logging.NullLogService; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.RETURNS_MOCKS; +import static org.mockito.Mockito.mock; + +public class BoltMessagingProtocolV2HandlerTest +{ + @Test + public void shouldHaveCorrectVersion() + { + BoltMessagingProtocolHandler handler = new BoltMessagingProtocolV2Handler( + mock( BoltChannel.class, RETURNS_MOCKS ), mock( BoltWorker.class ), TransportThrottleGroup.NO_THROTTLE, + NullLogService.getInstance() ); + + assertEquals( 2, handler.version() ); + } +} diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v2/transport/integration/BoltV2TransportIT.java b/community/bolt/src/test/java/org/neo4j/bolt/v2/transport/integration/BoltV2TransportIT.java new file mode 100644 index 000000000000..dcacd02f7b89 --- /dev/null +++ b/community/bolt/src/test/java/org/neo4j/bolt/v2/transport/integration/BoltV2TransportIT.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.bolt.v2.transport.integration; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; + +import java.util.List; + +import org.neo4j.bolt.v1.transport.integration.Neo4jWithSocket; +import org.neo4j.bolt.v1.transport.integration.TransportTestUtil; +import org.neo4j.bolt.v1.transport.socket.client.SecureSocketConnection; +import org.neo4j.bolt.v1.transport.socket.client.SecureWebSocketConnection; +import org.neo4j.bolt.v1.transport.socket.client.SocketConnection; +import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; +import org.neo4j.bolt.v1.transport.socket.client.WebSocketConnection; +import org.neo4j.bolt.v2.messaging.Neo4jPackV2; +import org.neo4j.helpers.HostnamePort; +import org.neo4j.values.storable.PointValue; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.runners.Parameterized.Parameters; +import static org.neo4j.bolt.v1.messaging.message.InitMessage.init; +import static org.neo4j.bolt.v1.messaging.message.PullAllMessage.pullAll; +import static org.neo4j.bolt.v1.messaging.message.RunMessage.run; +import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgRecord; +import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgSuccess; +import static org.neo4j.bolt.v1.runtime.spi.StreamMatchers.eqRecord; +import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyReceives; +import static org.neo4j.graphdb.factory.GraphDatabaseSettings.auth_enabled; +import static org.neo4j.values.storable.CoordinateReferenceSystem.Cartesian; +import static org.neo4j.values.storable.CoordinateReferenceSystem.WGS84; +import static org.neo4j.values.storable.Values.longValue; +import static org.neo4j.values.storable.Values.pointValue; +import static org.neo4j.values.virtual.VirtualValues.map; + +@RunWith( Parameterized.class ) +public class BoltV2TransportIT +{ + private static final String USER_AGENT = "TestClient/2.0"; + + @Rule + public Neo4jWithSocket server = new Neo4jWithSocket( getClass(), settings -> settings.put( auth_enabled.name(), "false" ) ); + + @Parameter + public Class connectionClass; + + private HostnamePort address; + private TransportConnection connection; + private TransportTestUtil util; + + @Parameters( name = "{0}" ) + public static List> transports() + { + return asList( SocketConnection.class, WebSocketConnection.class, SecureSocketConnection.class, SecureWebSocketConnection.class ); + } + + @Before + public void setUp() throws Exception + { + address = server.lookupDefaultConnector(); + connection = connectionClass.newInstance(); + util = new TransportTestUtil( new Neo4jPackV2() ); + } + + @After + public void tearDown() throws Exception + { + if ( connection != null ) + { + connection.disconnect(); + } + } + + @Test + public void shouldNegotiateProtocolV2() throws Exception + { + connection.connect( address ) + .send( util.acceptedVersions( 2, 0, 0, 0 ) ) + .send( util.chunk( init( USER_AGENT, emptyMap() ) ) ); + + assertThat( connection, eventuallyReceives( new byte[]{0, 0, 0, 2} ) ); + } + + @Test + public void shouldNegotiateProtocolV2WhenClientSupportsBothV1AndV2() throws Exception + { + connection.connect( address ) + .send( util.acceptedVersions( 2, 1, 0, 0 ) ) + .send( util.chunk( init( USER_AGENT, emptyMap() ) ) ); + + assertThat( connection, eventuallyReceives( new byte[]{0, 0, 0, 2} ) ); + } + + @Test + public void shouldSendPoints() throws Exception + { + PointValue point = pointValue( WGS84, 39.111748, -76.775635 ); + + negotiateBoltV2(); + connection.send( util.chunk( + run( "CREATE (n: Object {location: $location}) RETURN 42", map( singletonMap( "location", point ) ) ), + pullAll() ) ); + + assertThat( connection, util.eventuallyReceives( + msgSuccess(), + msgSuccess(), + msgRecord( eqRecord( equalTo( longValue( 42 ) ) ) ), + msgSuccess() ) ); + } + + @Test + public void shouldReceivePoints() throws Exception + { + negotiateBoltV2(); + connection.send( util.chunk( + run( "RETURN point({x: 40.7624, y: 73.9738})" ), + pullAll() ) ); + + assertThat( connection, util.eventuallyReceives( + msgSuccess(), + msgSuccess(), + msgRecord( eqRecord( equalTo( pointValue( Cartesian, 40.7624, 73.9738 ) ) ) ), + msgSuccess() ) ); + } + + @Test + public void shouldSendAndReceivePoints() throws Throwable + { + PointValue point = pointValue( WGS84, 38.8719, 77.0563 ); + + negotiateBoltV2(); + connection.send( util.chunk( + run( "RETURN $point", map( singletonMap( "point", point ) ) ), + pullAll() ) ); + + assertThat( connection, util.eventuallyReceives( + msgSuccess(), + msgSuccess(), + msgRecord( eqRecord( equalTo( point ) ) ), + msgSuccess() ) ); + } + + private void negotiateBoltV2() throws Exception + { + connection.connect( address ) + .send( util.acceptedVersions( 2, 0, 0, 0 ) ) + .send( util.chunk( init( USER_AGENT, emptyMap() ) ) ); + + assertThat( connection, eventuallyReceives( new byte[]{0, 0, 0, 2} ) ); + } +} diff --git a/community/server/src/test/java/org/neo4j/bolt/v1/transport/integration/CertificatesIT.java b/community/server/src/test/java/org/neo4j/bolt/v1/transport/integration/CertificatesIT.java index 8c26ace2c7ef..67c1c505a3da 100644 --- a/community/server/src/test/java/org/neo4j/bolt/v1/transport/integration/CertificatesIT.java +++ b/community/server/src/test/java/org/neo4j/bolt/v1/transport/integration/CertificatesIT.java @@ -32,6 +32,7 @@ import java.security.cert.X509Certificate; import java.util.Set; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.transport.socket.client.SecureSocketConnection; import org.neo4j.kernel.configuration.BoltConnector; import org.neo4j.ssl.PkiUtils; @@ -48,6 +49,7 @@ public class CertificatesIT private static File keyFile; private static File certFile; private static PkiUtils certFactory; + private static TransportTestUtil util; @Rule public Neo4jWithSocket server = new Neo4jWithSocket( getClass(), settings -> @@ -68,7 +70,7 @@ public void shouldUseConfiguredCertificate() throws Exception { // WHEN connection.connect( server.lookupConnector( DEFAULT_CONNECTOR_KEY ) ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ); // THEN Set certificatesSeen = connection.getServerCertificatesSeen(); @@ -102,6 +104,8 @@ public static void setUp() throws IOException, GeneralSecurityException, Operato certFile.delete(); certFactory.createSelfSignedCertificate( certFile, keyFile, "my.domain" ); + + util = new TransportTestUtil( new Neo4jPackV1() ); } } diff --git a/enterprise/metrics/src/test/java/org/neo4j/metrics/BoltMetricsIT.java b/enterprise/metrics/src/test/java/org/neo4j/metrics/BoltMetricsIT.java index 58729428f442..6ac3cfdcc1e9 100644 --- a/enterprise/metrics/src/test/java/org/neo4j/metrics/BoltMetricsIT.java +++ b/enterprise/metrics/src/test/java/org/neo4j/metrics/BoltMetricsIT.java @@ -25,7 +25,9 @@ import java.io.File; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.message.InitMessage; +import org.neo4j.bolt.v1.transport.integration.TransportTestUtil; import org.neo4j.bolt.v1.transport.socket.client.SocketConnection; import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; import org.neo4j.graphdb.factory.GraphDatabaseSettings; @@ -41,8 +43,6 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.acceptedVersions; -import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.chunk; import static org.neo4j.helpers.collection.MapUtil.map; import static org.neo4j.metrics.MetricsTestHelper.metricsCsv; import static org.neo4j.metrics.MetricsTestHelper.readLongValue; @@ -62,6 +62,8 @@ public class BoltMetricsIT private GraphDatabaseAPI db; private TransportConnection conn; + private final TransportTestUtil util = new TransportTestUtil( new Neo4jPackV1() ); + @Test public void shouldMonitorBolt() throws Throwable { @@ -86,8 +88,8 @@ public void shouldMonitorBolt() throws Throwable // When conn = new SocketConnection() .connect( new HostnamePort( "localhost", port ) ) - .send( acceptedVersions( 1, 0, 0, 0 ) ) - .send( chunk( InitMessage.init( "TestClient", + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient", map("scheme", "basic", "principal", "neo4j", "credentials", "neo4j") ) ) ); // Then diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/BoltInteraction.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/BoltInteraction.java index 32c370bc358a..a09345802b78 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/BoltInteraction.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/BoltInteraction.java @@ -28,6 +28,7 @@ import java.util.function.Supplier; import org.neo4j.bolt.security.auth.AuthenticationException; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.message.FailureMessage; import org.neo4j.bolt.v1.messaging.message.InitMessage; import org.neo4j.bolt.v1.messaging.message.PullAllMessage; @@ -75,6 +76,7 @@ class BoltInteraction implements NeoInteractionLevel { + private final TransportTestUtil util = new TransportTestUtil( new Neo4jPackV1() ); private final Factory connectionFactory = SocketConnection::new; private final Neo4jWithSocket server; private Map subjects = new HashMap<>(); @@ -145,7 +147,7 @@ public String executeQuery( BoltSubject subject, String call, Map } try { - subject.client.send( TransportTestUtil.chunk( RunMessage.run( call, ValueUtils.asMapValue( params ) ), PullAllMessage.pullAll() ) ); + subject.client.send( util.chunk( RunMessage.run( call, ValueUtils.asMapValue( params ) ), PullAllMessage.pullAll() ) ); resultConsumer.accept( collectResults( subject.client ) ); return ""; } @@ -170,12 +172,12 @@ public BoltSubject login( String username, String password ) throws Exception subject.client = connectionFactory.newInstance(); } subject.client.connect( server.lookupDefaultConnector() ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( InitMessage.init( "TestClient/1.1", + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( InitMessage.init( "TestClient/1.1", map( REALM_KEY, NATIVE_REALM, PRINCIPAL, username, CREDENTIALS, password, SCHEME_KEY, BASIC_SCHEME ) ) ) ); - assertThat( subject.client, TransportTestUtil.eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - subject.setLoginResult( TransportTestUtil.receiveOneResponseMessage( subject.client ) ); + assertThat( subject.client, util.eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); + subject.setLoginResult( util.receiveOneResponseMessage( subject.client ) ); return subject; } @@ -231,7 +233,7 @@ public void assertInitFailed( BoltSubject subject ) @Override public void assertSessionKilled( BoltSubject subject ) { - assertThat( subject.client, TransportTestUtil.eventuallyDisconnects() ); + assertThat( subject.client, util.eventuallyDisconnects() ); } @Override @@ -246,9 +248,9 @@ public HostnamePort lookupConnector( String connectorKey ) return server.lookupConnector( connectorKey ); } - private static BoltResult collectResults( TransportConnection client ) throws Exception + private BoltResult collectResults( TransportConnection client ) throws Exception { - ResponseMessage message = TransportTestUtil.receiveOneResponseMessage( client ); + ResponseMessage message = util.receiveOneResponseMessage( client ); List fieldNames = new ArrayList<>(); List> result = new ArrayList<>(); @@ -265,15 +267,15 @@ else if ( message instanceof FailureMessage ) { FailureMessage failMessage = (FailureMessage) message; // drain ignoredMessage, ack failure, get successMessage - TransportTestUtil.receiveOneResponseMessage( client ); - client.send( TransportTestUtil.chunk( reset() ) ); - TransportTestUtil.receiveOneResponseMessage( client ); + util.receiveOneResponseMessage( client ); + client.send( util.chunk( reset() ) ); + util.receiveOneResponseMessage( client ); throw new AuthenticationException( failMessage.status(), failMessage.message() ); } do { - message = TransportTestUtil.receiveOneResponseMessage( client ); + message = util.receiveOneResponseMessage( client ); if ( message instanceof RecordMessage ) { Object[] row = ((RecordMessage) message).record().fields(); @@ -291,8 +293,8 @@ else if ( message instanceof FailureMessage ) { FailureMessage failMessage = (FailureMessage) message; // ack failure, get successMessage - client.send( TransportTestUtil.chunk( reset() ) ); - TransportTestUtil.receiveOneResponseMessage( client ); + client.send( util.chunk( reset() ) ); + util.receiveOneResponseMessage( client ); throw new AuthenticationException( failMessage.status(), failMessage.message() ); } diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ProcedureInteractionTestBase.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ProcedureInteractionTestBase.java index 2f2118974dd2..58f62639fb3c 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ProcedureInteractionTestBase.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ProcedureInteractionTestBase.java @@ -40,10 +40,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.transport.integration.TransportTestUtil; import org.neo4j.bolt.v1.transport.socket.client.SocketConnection; import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; -import org.neo4j.kernel.impl.util.BaseToObjectValueWriter; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; @@ -62,6 +62,7 @@ import org.neo4j.kernel.api.exceptions.InvalidArgumentsException; import org.neo4j.kernel.enterprise.builtinprocs.EnterpriseBuiltInDbmsProcedures; import org.neo4j.kernel.impl.proc.Procedures; +import org.neo4j.kernel.impl.util.BaseToObjectValueWriter; import org.neo4j.logging.Log; import org.neo4j.procedure.Context; import org.neo4j.procedure.Mode; @@ -73,8 +74,8 @@ import org.neo4j.test.DoubleLatch; import org.neo4j.test.rule.concurrent.ThreadingRule; import org.neo4j.values.AnyValue; -import org.neo4j.values.storable.TextValue; import org.neo4j.values.storable.CoordinateReferenceSystem; +import org.neo4j.values.storable.TextValue; import org.neo4j.values.virtual.ListValue; import org.neo4j.values.virtual.MapValue; @@ -148,6 +149,7 @@ private ThreadingRule threading() EnterpriseUserManager userManager; protected NeoInteractionLevel neo; + protected TransportTestUtil util; File securityLog; Map defaultConfiguration() throws IOException @@ -164,6 +166,7 @@ Map defaultConfiguration() throws IOException public void setUp() throws Throwable { configuredSetup( defaultConfiguration() ); + util = new TransportTestUtil( new Neo4jPackV1() ); } void configuredSetup( Map config ) throws Throwable @@ -615,11 +618,11 @@ TransportConnection startBoltSession( String username, String password ) throws HostnamePort address = neo.lookupConnector( DEFAULT_CONNECTOR_KEY ); Map authToken = map( "principal", username, "credentials", password, "scheme", "basic" ); - connection.connect( address ).send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( init( "TestClient/1.1", authToken ) ) ); + connection.connect( address ).send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", authToken ) ) ); assertThat( connection, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( connection, eventuallyReceives( msgSuccess() ) ); + assertThat( connection, util.eventuallyReceives( msgSuccess() ) ); return connection; } diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/ActiveDirectoryAuthenticationIT.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/ActiveDirectoryAuthenticationIT.java index 24244b05475b..9828b3a8df94 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/ActiveDirectoryAuthenticationIT.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/ActiveDirectoryAuthenticationIT.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.function.Consumer; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.transport.integration.Neo4jWithSocket; import org.neo4j.bolt.v1.transport.integration.TransportTestUtil; import org.neo4j.bolt.v1.transport.socket.client.SecureSocketConnection; @@ -124,13 +125,15 @@ protected Consumer,String>> getSettingsFunction() public Factory cf = (Factory) SecureSocketConnection::new; private HostnamePort address; - protected TransportConnection client; + private TransportConnection client; + private TransportTestUtil util; @Before public void setup() { this.client = cf.newInstance(); this.address = server.lookupDefaultConnector(); + this.util = new TransportTestUtil( new Neo4jPackV1() ); } @After @@ -276,11 +279,11 @@ private void assertAuth( String username, String password ) throws Exception private void assertAuth( String username, String password, String realm ) throws Exception { client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( init( "TestClient/1.1", authToken( username, password, realm ) ) ) ); + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", authToken( username, password, realm ) ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } private Map authToken( String username, String password, String realm ) @@ -298,36 +301,36 @@ private Map authToken( String username, String password, String r private void assertAuthFail( String username, String password ) throws Exception { client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", map( "principal", username, "credentials", password, "scheme", "basic" ) ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "The client is unauthorized due to authentication failure." ) ) ); } protected void assertReadSucceeds() throws Exception { // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } protected void assertReadFails( String username ) throws Exception { // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Forbidden, String.format( "Read operations are not allowed for user %s.", username ) ) ) ); } @@ -335,23 +338,23 @@ protected void assertReadFails( String username ) throws Exception protected void assertWriteSucceeds() throws Exception { // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CREATE ()" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } protected void assertWriteFails( String username ) throws Exception { // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CREATE ()" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Forbidden, String.format( "Write operations are not allowed for user %s.", username ) ) ) ); } diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltConnectionManagementIT.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltConnectionManagementIT.java index d6652994bf3b..ccf7d9044359 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltConnectionManagementIT.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/BoltConnectionManagementIT.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.function.Consumer; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.messaging.message.ResetMessage; import org.neo4j.bolt.v1.runtime.spi.ImmutableRecord; import org.neo4j.bolt.v1.transport.integration.Neo4jWithSocket; @@ -77,6 +78,7 @@ public class BoltConnectionManagementIT protected TransportConnection admin; protected TransportConnection user; + protected TransportTestUtil util; @Parameterized.Parameter() public Factory cf; @@ -100,6 +102,7 @@ public void setup() throws Exception this.admin = cf.newInstance(); this.user = cf.newInstance(); this.address = server.lookupDefaultConnector(); + this.util = new TransportTestUtil( new Neo4jPackV1() ); authenticate( admin, "neo4j", "neo4j", "123" ); createNewUser( admin, "Igor", "123" ); @@ -139,7 +142,7 @@ protected Consumer> getSettingsFunction() public void shouldListOwnConnection() throws Throwable { // When - admin.send( TransportTestUtil.chunk( + admin.send( util.chunk( run( "CALL dbms.listConnections() YIELD username, connectionCount" ), pullAll() ) ); @@ -155,7 +158,7 @@ public void shouldListAllConnections() throws Throwable { // When authenticate( user, "Igor", "123", null ); - admin.send( TransportTestUtil.chunk( + admin.send( util.chunk( run( "CALL dbms.listConnections() YIELD username, connectionCount" ), pullAll() ) ); @@ -173,12 +176,12 @@ public void shouldNotListConnectionsIfNotAdmin() throws Throwable { // When authenticate( user, "Igor", "123", null ); - user.send( TransportTestUtil.chunk( + user.send( util.chunk( run( "CALL dbms.listConnections() YIELD username, connectionCount" ), pullAll() ) ); // Then - assertThat( user, eventuallyReceives( + assertThat( user, util.eventuallyReceives( msgFailure( Status.Security.Forbidden, PERMISSION_DENIED ) ) ); } @@ -189,7 +192,7 @@ public void shouldTerminateConnectionForUser() throws Throwable { // When authenticate( user, "Igor", "123", null ); - admin.send( TransportTestUtil.chunk( + admin.send( util.chunk( run( "CALL dbms.terminateConnectionsForUser( 'Igor' ) YIELD username, connectionCount" ), pullAll() ) ); @@ -198,7 +201,7 @@ public void shouldTerminateConnectionForUser() throws Throwable assertTrue( terminationResult.containsKey( "Igor" ) ); assertTrue( terminationResult.get( "Igor" ) == 1L ); - admin.send( TransportTestUtil.chunk( + admin.send( util.chunk( run( "CALL dbms.listConnections() YIELD username, connectionCount" ), pullAll() ) ); Map listResult = collectConnectionResult( admin, 1 ); @@ -212,7 +215,7 @@ public void shouldTerminateConnectionForUser() throws Throwable public void shouldNotFailWhenTerminatingConnectionsForUserWithNoConnections() throws Throwable { // When - admin.send( TransportTestUtil.chunk( + admin.send( util.chunk( run( "CALL dbms.terminateConnectionsForUser( 'Igor' ) YIELD username, connectionCount" ), pullAll() ) ); @@ -226,12 +229,12 @@ public void shouldNotFailWhenTerminatingConnectionsForUserWithNoConnections() th public void shouldFailWhenTerminatingConnectionsForNonExistentUser() throws Throwable { // When - admin.send( TransportTestUtil.chunk( + admin.send( util.chunk( run( "CALL dbms.terminateConnectionsForUser( 'NonExistentUser' ) YIELD username, connectionCount" ), pullAll() ) ); // Then - assertThat( admin, eventuallyReceives( msgFailure( Status.General.InvalidArguments, + assertThat( admin, util.eventuallyReceives( msgFailure( Status.General.InvalidArguments, "User 'NonExistentUser' does not exist." ) ) ); } @@ -292,10 +295,10 @@ private static void verifyConnectionHasTerminated( TransportConnection conn ) th } } - private static void assertTerminateOwnConnection( TransportConnection conn, String username ) throws Exception + private void assertTerminateOwnConnection( TransportConnection conn, String username ) throws Exception { // Given - conn.send( TransportTestUtil.chunk( + conn.send( util.chunk( run( "CALL dbms.terminateConnectionsForUser( '" + username + "' ) YIELD username, connectionCount" ), pullAll() ) ); @@ -303,10 +306,9 @@ private static void assertTerminateOwnConnection( TransportConnection conn, Stri verifyConnectionHasTerminated( conn ); } - private static void assertTerminateOwnConnections( TransportConnection conn1, TransportConnection conn2, String username ) throws - Exception + private void assertTerminateOwnConnections( TransportConnection conn1, TransportConnection conn2, String username ) throws Exception { - conn1.send( TransportTestUtil.chunk( + conn1.send( util.chunk( run( "CALL dbms.terminateConnectionsForUser( '" + username + "' ) YIELD username, connectionCount" ), pullAll() ) ); @@ -315,20 +317,20 @@ private static void assertTerminateOwnConnections( TransportConnection conn1, Tr verifyConnectionHasTerminated( conn2 ); } - private static void assertFailTerminateConnectionForUser( TransportConnection client, String username ) throws Exception + private void assertFailTerminateConnectionForUser( TransportConnection client, String username ) throws Exception { - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CALL dbms.terminateConnectionsForUser( '" + username + "' ) YIELD username, connectionCount" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Forbidden, PERMISSION_DENIED ), msgIgnored() ) ); - client.send( TransportTestUtil.chunk( ResetMessage.reset() ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + client.send( util.chunk( ResetMessage.reset() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } private void authenticate( TransportConnection client, String username, String password, String newPassword ) @@ -343,38 +345,38 @@ private void authenticate( TransportConnection client, String username, String p } client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", authToken ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } - private static void createNewUser( TransportConnection client, String username, String password ) throws Exception + private void createNewUser( TransportConnection client, String username, String password ) throws Exception { - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CALL dbms.security.createUser( '" + username + "', '" + password + "', false )" ), pullAll() ) ); - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } - private static Map collectConnectionResult( TransportConnection client, int n ) + private Map collectConnectionResult( TransportConnection client, int n ) { CollectingMatcher collector = new CollectingMatcher(); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess( CoreMatchers.allOf( hasEntry(is("fields"), equalTo(asList( "username", "connectionCount" ) )), hasKey( "result_available_after" ) ) ) ) ); for ( int i = 0; i < n; i++ ) { - assertThat( client, eventuallyReceives( msgRecord( collector ) ) ); + assertThat( client, util.eventuallyReceives( msgRecord( collector ) ) ); } - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); return collector.result(); diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/EnterpriseAuthenticationTestBase.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/EnterpriseAuthenticationTestBase.java index 4875decbff35..cf4e39c0f598 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/EnterpriseAuthenticationTestBase.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/EnterpriseAuthenticationTestBase.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.function.Consumer; +import org.neo4j.bolt.v1.messaging.Neo4jPackV1; import org.neo4j.bolt.v1.transport.integration.Neo4jWithSocket; import org.neo4j.bolt.v1.transport.integration.TransportTestUtil; import org.neo4j.bolt.v1.transport.socket.client.SecureSocketConnection; @@ -57,7 +58,6 @@ import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgSuccess; import static org.neo4j.bolt.v1.runtime.spi.StreamMatchers.eqRecord; import static org.neo4j.bolt.v1.runtime.spi.StreamMatchers.greaterThanOrEqualTo; -import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.chunk; import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyDisconnects; import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyReceives; import static org.neo4j.helpers.collection.MapUtil.map; @@ -106,12 +106,14 @@ protected Consumer,String>> getSettingsFunction() protected HostnamePort address; protected TransportConnection client; + protected TransportTestUtil util; @Before public void setup() { this.client = cf.newInstance(); lookupConnectorAddress(); + this.util = new TransportTestUtil( new Neo4jPackV1() ); } protected void lookupConnectorAddress() @@ -157,12 +159,12 @@ protected void testCreateReaderUser( String username ) throws Exception // NOTE: The default user 'neo4j' has password change required, so we have to first change it assertAuthAndChangePassword( "neo4j", "abc123", "123" ); - client.send( chunk( + client.send( util.chunk( run( "CALL dbms.security.createUser( '" + username + "', '" + createdUserPassword + "', false ) " + "CALL dbms.security.addRoleToUser( 'reader', '" + username + "' ) RETURN 0" ), pullAll() ) ); - assertThat( client, eventuallyReceives( msgSuccess(), msgRecord( eqRecord( equalTo( longValue( 0L ) ) ) ) ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgRecord( eqRecord( equalTo( longValue( 0L ) ) ) ) ) ); } protected void testAuthWithReaderUser( String username, String password, String realm ) throws Exception @@ -193,8 +195,8 @@ protected void assertAuthAndChangePassword( String username, String password, St { assertAuth( username, password ); String query = format( "CALL dbms.security.changeUserPassword('%s', '%s', false)", username, newPassword ); - client.send( chunk( run( query ), pullAll() ) ); - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + client.send( util.chunk( run( query ), pullAll() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } protected void assertAuth( String username, String password, String realm ) throws Exception @@ -209,10 +211,10 @@ protected void assertAuthFail( String username, String password ) throws Excepti protected void assertRoles( String... roles ) throws Exception { - client.send( TransportTestUtil.chunk( run( "CALL dbms.showCurrentUser" ), pullAll() ) ); + client.send( util.chunk( run( "CALL dbms.showCurrentUser" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgRecord( eqRecord( equalTo( stringValue( "tank" ) ), containsInAnyOrder( stream( roles ).map( Values::stringValue ).toArray() ), anything() ) ), @@ -223,13 +225,13 @@ protected void assertConnectionSucceeds( Map authToken ) throws E { // When client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", authToken ) ) ); // Then assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess() ) ); } protected void assertConnectionFails( Map authToken ) throws Exception @@ -241,12 +243,12 @@ protected void assertConnectionFails( Map authToken ) throws Exce try { client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", authToken ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.Unauthorized, + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Unauthorized, "The client is unauthorized due to authentication failure." ) ) ); assertThat( client, eventuallyDisconnects() ); return; @@ -268,11 +270,11 @@ protected void assertConnectionFails( Map authToken ) throws Exce protected void assertReadSucceeds() throws Exception { // When - client.send( TransportTestUtil.chunk( run( "MATCH (n) RETURN count(n)" ), + client.send( util.chunk( run( "MATCH (n) RETURN count(n)" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgRecord( eqRecord( greaterThanOrEqualTo( 0L ) ) ), msgSuccess() ) ); @@ -281,14 +283,14 @@ protected void assertReadSucceeds() throws Exception protected void assertReadFails( String username, String roles ) throws Exception { // When - client.send( chunk( + client.send( util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); String roleString = StringUtils.isEmpty( roles ) ? "no roles" : "roles [" + roles + "]"; // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Forbidden, format( "Read operations are not allowed for user '%s' with %s.", username, roleString ) ) ) ); } @@ -296,25 +298,25 @@ protected void assertReadFails( String username, String roles ) throws Exception protected void assertWriteSucceeds() throws Exception { // When - client.send( chunk( + client.send( util.chunk( run( "CREATE ()" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } protected void assertWriteFails( String username, String roles ) throws Exception { // When - client.send( chunk( + client.send( util.chunk( run( "CREATE ()" ), pullAll() ) ); String roleString = StringUtils.isEmpty( roles ) ? "no roles" : "roles [" + roles + "]"; // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.Forbidden, format( "Write operations are not allowed for user '%s' with %s.", username, roleString ) ) ) ); } @@ -322,34 +324,33 @@ protected void assertWriteFails( String username, String roles ) throws Exceptio protected void assertBeginTransactionSucceeds() throws Exception { // When - client.send( TransportTestUtil.chunk( run( "BEGIN" ), + client.send( util.chunk( run( "BEGIN" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( - msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } protected void assertCommitTransaction() throws Exception { // When - client.send( chunk( + client.send( util.chunk( run( "COMMIT" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } protected void assertQuerySucceeds( String query ) throws Exception { // When - client.send( chunk( + client.send( util.chunk( run( query ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } protected Map authToken( String username, String password, String realm ) diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/LdapAuthIT.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/LdapAuthIT.java index 95f2332e0389..2c46c5853593 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/LdapAuthIT.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/LdapAuthIT.java @@ -54,7 +54,6 @@ import javax.naming.directory.ModificationItem; import javax.naming.ldap.LdapContext; -import org.neo4j.bolt.v1.transport.integration.TransportTestUtil; import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; import org.neo4j.graphdb.config.Setting; import org.neo4j.internal.kernel.api.security.AuthSubject; @@ -283,13 +282,13 @@ public void shouldShowCurrentUser() throws Throwable { // When assertAuth( "smith", "abc123" ); - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CALL dbms.showCurrentUser()" ), pullAll() ) ); // Then // Assuming showCurrentUser has fields username, roles, flags - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgRecord( eqRecord( equalTo( stringValue( "smith" ) ), equalTo( EMPTY_LIST ), equalTo( EMPTY_LIST ) ) ) @@ -354,14 +353,14 @@ public void shouldFailIfAuthorizationExpiredWithUserLdapContext() throws Throwab assertReadSucceeds(); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CALL dbms.security.clearAuthCache()" ), pullAll() ) ); - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); // Then - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.AuthorizationExpired, "LDAP authorization info expired." ) ) ); assertThat( client, eventuallyDisconnects() ); @@ -375,11 +374,11 @@ public void shouldSucceedIfAuthorizationExpiredWithinTransactionWithUserLdapCont // Then assertAuth( "neo4j", "abc123" ); - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CALL dbms.security.clearAuthCache() MATCH (n) RETURN n" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } @Test @@ -652,10 +651,10 @@ public void shouldTimeoutIfLdapServerDoesNotRespondWithLdapUserContext() throws private void assertAllowedReadProcedure() throws IOException { - client.send( TransportTestUtil.chunk( run( "CALL test.allowedReadProcedure()" ), pullAll() ) ); + client.send( util.chunk( run( "CALL test.allowedReadProcedure()" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgSuccess(), msgRecord( eqRecord( equalTo( stringValue( "foo" ) ) ) ), msgSuccess() ) ); @@ -1197,24 +1196,24 @@ private void clearAuthCacheFromDifferentConnection() throws Exception // Login as admin Map authToken = authToken( "neo4j", "abc123", null ); adminClient.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", authToken ) ) ); assertThat( adminClient, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( adminClient, eventuallyReceives( msgSuccess() ) ); + assertThat( adminClient, util.eventuallyReceives( msgSuccess() ) ); // Clear auth cache - adminClient.send( TransportTestUtil.chunk( run( "CALL dbms.security.clearAuthCache()" ), pullAll() ) ); - assertThat( adminClient, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + adminClient.send( util.chunk( run( "CALL dbms.security.clearAuthCache()" ), pullAll() ) ); + assertThat( adminClient, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } private void assertLdapAuthorizationTimeout() throws IOException { // When - client.send( TransportTestUtil.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); + client.send( util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.AuthProviderTimeout, LDAP_READ_TIMEOUT_CLIENT_MESSAGE ) ) ); assertThat( client, eventuallyDisconnects() ); @@ -1223,10 +1222,10 @@ private void assertLdapAuthorizationTimeout() throws IOException private void assertLdapAuthorizationFailed() throws IOException { // When - client.send( TransportTestUtil.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); + client.send( util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.AuthProviderFailed, LDAP_AUTHORIZATION_FAILURE_CLIENT_MESSAGE ) ) ); assertThat( client, eventuallyDisconnects() ); @@ -1235,12 +1234,12 @@ private void assertLdapAuthorizationFailed() throws IOException private void assertConnectionTimeout( Map authToken, String message ) throws Exception { client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", authToken ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.AuthProviderTimeout, message ) ) ); + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.AuthProviderTimeout, message ) ) ); assertThat( client, eventuallyDisconnects() ); } @@ -1248,12 +1247,12 @@ private void assertConnectionTimeout( Map authToken, String messa private void assertConnectionRefused( Map authToken, String message ) throws Exception { client.connect( address ) - .send( TransportTestUtil.acceptedVersions( 1, 0, 0, 0 ) ) - .send( TransportTestUtil.chunk( + .send( util.acceptedVersions( 1, 0, 0, 0 ) ) + .send( util.chunk( init( "TestClient/1.1", authToken ) ) ); assertThat( client, eventuallyReceives( new byte[]{0, 0, 0, 1} ) ); - assertThat( client, eventuallyReceives( msgFailure( Status.Security.AuthProviderFailed, message ) ) ); + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.AuthProviderFailed, message ) ) ); assertThat( client, eventuallyDisconnects() ); } @@ -1262,9 +1261,9 @@ private void testClearAuthCache() throws Exception { assertAuth( "neo4j", "abc123" ); - client.send( TransportTestUtil.chunk( run( "CALL dbms.security.clearAuthCache()" ), pullAll() ) ); + client.send( util.chunk( run( "CALL dbms.security.clearAuthCache()" ), pullAll() ) ); - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } private void restartServerWithoutSystemAccount() diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/PluginAuthenticationIT.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/PluginAuthenticationIT.java index f4c097bdab1c..f8127eee7234 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/PluginAuthenticationIT.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/integration/bolt/PluginAuthenticationIT.java @@ -28,7 +28,6 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -import org.neo4j.bolt.v1.transport.integration.TransportTestUtil; import org.neo4j.graphdb.config.Setting; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.server.security.enterprise.auth.plugin.TestCacheableAuthPlugin; @@ -42,7 +41,6 @@ import static org.neo4j.bolt.v1.messaging.message.RunMessage.run; import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgFailure; import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgSuccess; -import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyReceives; import static org.neo4j.helpers.collection.MapUtil.map; public class PluginAuthenticationIT extends EnterpriseAuthenticationTestBase @@ -209,14 +207,14 @@ public void shouldFailIfAuthorizationExpiredWithAuthPlugin() throws Throwable assertReadSucceeds(); // When - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CALL dbms.security.clearAuthCache()" ), pullAll() ) ); - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); // Then - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.AuthorizationExpired, "Plugin 'plugin-TestCacheableAdminAuthPlugin' authorization info expired." ) ) ); } @@ -230,11 +228,11 @@ public void shouldSucceedIfAuthorizationExpiredWithinTransactionWithAuthPlugin() // Then assertConnectionSucceeds( authToken( "neo4j", "neo4j", "plugin-TestCacheableAdminAuthPlugin" ) ); - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "CALL dbms.security.clearAuthCache() MATCH (n) RETURN n" ), pullAll() ) ); // Then - assertThat( client, eventuallyReceives( msgSuccess(), msgSuccess() ) ); + assertThat( client, util.eventuallyReceives( msgSuccess(), msgSuccess() ) ); } @Test @@ -256,9 +254,9 @@ public void shouldPassOnAuthorizationExpiredException() throws Throwable assertConnectionSucceeds( authToken( "authorization_expired_user", "neo4j", null ) ); // Then - client.send( TransportTestUtil.chunk( + client.send( util.chunk( run( "MATCH (n) RETURN n" ), pullAll() ) ); - assertThat( client, eventuallyReceives( + assertThat( client, util.eventuallyReceives( msgFailure( Status.Security.AuthorizationExpired, "Plugin 'plugin-TestCombinedAuthPlugin' authorization info expired: " + "authorization_expired_user needs to re-authenticate." ) ) );