Skip to content

Commit 53fa23f

Browse files
authored
Adding bolt v4.2 handshake. (#762)
1 parent 16bdde3 commit 53fa23f

File tree

11 files changed

+133
-52
lines changed

11 files changed

+133
-52
lines changed

driver/src/main/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtil.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@
2121
import io.netty.buffer.ByteBuf;
2222

2323
import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
24-
import org.neo4j.driver.internal.messaging.v1.BoltProtocolV1;
25-
import org.neo4j.driver.internal.messaging.v2.BoltProtocolV2;
2624
import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3;
2725
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
2826
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
27+
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
2928

3029
import static io.netty.buffer.Unpooled.copyInt;
3130
import static io.netty.buffer.Unpooled.unreleasableBuffer;
@@ -42,10 +41,10 @@ public final class BoltProtocolUtil
4241

4342
private static final ByteBuf HANDSHAKE_BUF = unreleasableBuffer( copyInt(
4443
BOLT_MAGIC_PREAMBLE,
44+
BoltProtocolV42.VERSION.toInt(),
4545
BoltProtocolV41.VERSION.toInt(),
4646
BoltProtocolV4.VERSION.toInt(),
47-
BoltProtocolV3.VERSION.toInt(),
48-
0 ) ).asReadOnly();
47+
BoltProtocolV3.VERSION.toInt() ) ).asReadOnly();
4948

5049
private static final String HANDSHAKE_STRING = createHandshakeString();
5150

driver/src/main/java/org/neo4j/driver/internal/messaging/BoltProtocol.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import io.netty.channel.Channel;
2222
import io.netty.channel.ChannelPromise;
2323

24-
import java.util.Map;
2524
import java.util.concurrent.CompletionStage;
2625

2726
import org.neo4j.driver.AuthToken;
@@ -30,7 +29,6 @@
3029
import org.neo4j.driver.Session;
3130
import org.neo4j.driver.Transaction;
3231
import org.neo4j.driver.TransactionConfig;
33-
import org.neo4j.driver.Value;
3432
import org.neo4j.driver.exceptions.ClientException;
3533
import org.neo4j.driver.internal.BookmarkHolder;
3634
import org.neo4j.driver.internal.InternalBookmark;
@@ -42,6 +40,7 @@
4240
import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3;
4341
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
4442
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
43+
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
4544
import org.neo4j.driver.internal.spi.Connection;
4645

4746
import static org.neo4j.driver.internal.async.connection.ChannelAttributes.protocolVersion;
@@ -173,6 +172,9 @@ else if ( BoltProtocolV4.VERSION.equals( version ) )
173172
} else if ( BoltProtocolV41.VERSION.equals( version ) )
174173
{
175174
return BoltProtocolV41.INSTANCE;
175+
} else if ( BoltProtocolV42.VERSION.equals( version ) )
176+
{
177+
return BoltProtocolV42.INSTANCE;
176178
}
177179
throw new ClientException( "Unknown protocol version: " + version );
178180
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2002-2020 "Neo4j,"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal.messaging.v42;
20+
21+
import org.neo4j.driver.internal.messaging.BoltProtocol;
22+
import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
23+
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
24+
25+
/**
26+
* Bolt V4.2 is identical to V4.1
27+
*/
28+
public class BoltProtocolV42 extends BoltProtocolV41
29+
{
30+
public static final BoltProtocolVersion VERSION = new BoltProtocolVersion( 4, 2 );
31+
public static final BoltProtocol INSTANCE = new BoltProtocolV42();
32+
33+
@Override
34+
public BoltProtocolVersion version()
35+
{
36+
return VERSION;
37+
}
38+
}

driver/src/main/java/org/neo4j/driver/internal/util/ServerVersion.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@
2727
import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
2828
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
2929
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
30+
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
3031

3132
import static java.lang.Integer.compare;
3233

3334
public class ServerVersion
3435
{
3536
public static final String NEO4J_PRODUCT = "Neo4j";
3637

38+
public static final ServerVersion v4_2_0 = new ServerVersion( NEO4J_PRODUCT, 4, 2, 0 );
3739
public static final ServerVersion v4_1_0 = new ServerVersion( NEO4J_PRODUCT, 4, 1, 0 );
3840
public static final ServerVersion v4_0_0 = new ServerVersion( NEO4J_PRODUCT, 4, 0, 0 );
3941
public static final ServerVersion v3_5_0 = new ServerVersion( NEO4J_PRODUCT, 3, 5, 0 );
@@ -188,6 +190,9 @@ public static ServerVersion fromBoltProtocolVersion( BoltProtocolVersion protoco
188190
else if ( BoltProtocolV41.VERSION.equals( protocolVersion ) )
189191
{
190192
return ServerVersion.v4_1_0;
193+
} else if ( BoltProtocolV42.VERSION.equals( protocolVersion ) )
194+
{
195+
return ServerVersion.v4_2_0;
191196
}
192197

193198
return ServerVersion.vInDev;

driver/src/test/java/org/neo4j/driver/internal/async/connection/BoltProtocolUtilTest.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@
2222
import io.netty.buffer.Unpooled;
2323
import org.junit.jupiter.api.Test;
2424

25-
import org.neo4j.driver.internal.messaging.v1.BoltProtocolV1;
26-
import org.neo4j.driver.internal.messaging.v2.BoltProtocolV2;
2725
import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3;
2826
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
2927
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
28+
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
3029

3130
import static org.junit.jupiter.api.Assertions.assertEquals;
3231
import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.BOLT_MAGIC_PREAMBLE;
@@ -44,15 +43,15 @@ void shouldReturnHandshakeBuf()
4443
{
4544
assertByteBufContains(
4645
handshakeBuf(),
47-
BOLT_MAGIC_PREAMBLE, BoltProtocolV41.VERSION.toInt(), BoltProtocolV4.VERSION.toInt(),
48-
BoltProtocolV3.VERSION.toInt(), 0
46+
BOLT_MAGIC_PREAMBLE, BoltProtocolV42.VERSION.toInt(), BoltProtocolV41.VERSION.toInt(),
47+
BoltProtocolV4.VERSION.toInt(), BoltProtocolV3.VERSION.toInt()
4948
);
5049
}
5150

5251
@Test
5352
void shouldReturnHandshakeString()
5453
{
55-
assertEquals( "[0x6060b017, 260, 4, 3, 0]", handshakeString() );
54+
assertEquals( "[0x6060b017, 516, 260, 4, 3]", handshakeString() );
5655
}
5756

5857
@Test

driver/src/test/java/org/neo4j/driver/internal/async/connection/HandshakeHandlerTest.java

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@
2525
import org.junit.jupiter.api.AfterEach;
2626
import org.junit.jupiter.api.BeforeEach;
2727
import org.junit.jupiter.api.Test;
28+
import org.junit.jupiter.params.ParameterizedTest;
29+
import org.junit.jupiter.params.provider.Arguments;
30+
import org.junit.jupiter.params.provider.MethodSource;
2831

2932
import java.io.IOException;
33+
import java.util.stream.Stream;
3034
import javax.net.ssl.SSLHandshakeException;
3135

3236
import org.neo4j.driver.Logging;
@@ -40,10 +44,12 @@
4044
import org.neo4j.driver.internal.async.outbound.OutboundMessageHandler;
4145
import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
4246
import org.neo4j.driver.internal.messaging.MessageFormat;
43-
import org.neo4j.driver.internal.messaging.v1.BoltProtocolV1;
44-
import org.neo4j.driver.internal.messaging.v1.MessageFormatV1;
45-
import org.neo4j.driver.internal.messaging.v2.BoltProtocolV2;
46-
import org.neo4j.driver.internal.messaging.v2.MessageFormatV2;
47+
import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3;
48+
import org.neo4j.driver.internal.messaging.v3.MessageFormatV3;
49+
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
50+
import org.neo4j.driver.internal.messaging.v4.MessageFormatV4;
51+
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
52+
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
4753
import org.neo4j.driver.internal.util.ErrorUtil;
4854

4955
import static io.netty.buffer.Unpooled.copyInt;
@@ -54,6 +60,7 @@
5460
import static org.junit.jupiter.api.Assertions.assertNotNull;
5561
import static org.junit.jupiter.api.Assertions.assertNull;
5662
import static org.junit.jupiter.api.Assertions.assertThrows;
63+
import static org.junit.jupiter.params.provider.Arguments.arguments;
5764
import static org.neo4j.driver.internal.async.connection.BoltProtocolUtil.NO_PROTOCOL_VERSION;
5865
import static org.neo4j.driver.internal.async.connection.ChannelAttributes.setMessageDispatcher;
5966
import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING;
@@ -187,16 +194,33 @@ void shouldTranslateSSLHandshakeException()
187194
assertNull( await( channel.closeFuture() ) );
188195
}
189196

190-
@Test
191-
void shouldSelectProtocolV1WhenServerSuggests()
197+
@ParameterizedTest
198+
@MethodSource( "protocolVersions" )
199+
public void testProtocolSelection( BoltProtocolVersion protocolVersion, Class<? extends MessageFormat> expectedMessageFormatClass )
192200
{
193-
testProtocolSelection( BoltProtocolV1.VERSION, MessageFormatV1.class );
194-
}
201+
ChannelPromise handshakeCompletedPromise = channel.newPromise();
202+
MemorizingChannelPipelineBuilder pipelineBuilder = new MemorizingChannelPipelineBuilder();
203+
HandshakeHandler handler = newHandler( pipelineBuilder, handshakeCompletedPromise );
204+
channel.pipeline().addLast( handler );
195205

196-
@Test
197-
void shouldSelectProtocolV2WhenServerSuggests()
198-
{
199-
testProtocolSelection( BoltProtocolV2.VERSION, MessageFormatV2.class );
206+
channel.pipeline().fireChannelRead( copyInt( protocolVersion.toInt() ) );
207+
208+
// expected message format should've been used
209+
assertThat( pipelineBuilder.usedMessageFormat, instanceOf( expectedMessageFormatClass ) );
210+
211+
// handshake handler itself should be removed
212+
assertNull( channel.pipeline().get( HandshakeHandler.class ) );
213+
214+
// all inbound handlers should be set
215+
assertNotNull( channel.pipeline().get( ChunkDecoder.class ) );
216+
assertNotNull( channel.pipeline().get( MessageDecoder.class ) );
217+
assertNotNull( channel.pipeline().get( InboundMessageHandler.class ) );
218+
219+
// all outbound handlers should be set
220+
assertNotNull( channel.pipeline().get( OutboundMessageHandler.class ) );
221+
222+
// promise should be successful
223+
assertNull( await( handshakeCompletedPromise ) );
200224
}
201225

202226
@Test
@@ -254,31 +278,12 @@ private void testFailure( BoltProtocolVersion serverSuggestedVersion, String exp
254278
assertNull( await( channel.closeFuture() ) );
255279
}
256280

257-
private void testProtocolSelection( BoltProtocolVersion protocolVersion, Class<? extends MessageFormat> expectedMessageFormatClass )
281+
private static Stream<Arguments> protocolVersions()
258282
{
259-
ChannelPromise handshakeCompletedPromise = channel.newPromise();
260-
MemorizingChannelPipelineBuilder pipelineBuilder = new MemorizingChannelPipelineBuilder();
261-
HandshakeHandler handler = newHandler( pipelineBuilder, handshakeCompletedPromise );
262-
channel.pipeline().addLast( handler );
263-
264-
channel.pipeline().fireChannelRead( copyInt( protocolVersion.toInt() ) );
265-
266-
// expected message format should've been used
267-
assertThat( pipelineBuilder.usedMessageFormat, instanceOf( expectedMessageFormatClass ) );
268-
269-
// handshake handler itself should be removed
270-
assertNull( channel.pipeline().get( HandshakeHandler.class ) );
271-
272-
// all inbound handlers should be set
273-
assertNotNull( channel.pipeline().get( ChunkDecoder.class ) );
274-
assertNotNull( channel.pipeline().get( MessageDecoder.class ) );
275-
assertNotNull( channel.pipeline().get( InboundMessageHandler.class ) );
276-
277-
// all outbound handlers should be set
278-
assertNotNull( channel.pipeline().get( OutboundMessageHandler.class ) );
279-
280-
// promise should be successful
281-
assertNull( await( handshakeCompletedPromise ) );
283+
return Stream.of( arguments( BoltProtocolV3.VERSION, MessageFormatV3.class ),
284+
arguments( BoltProtocolV4.VERSION, MessageFormatV4.class ),
285+
arguments( BoltProtocolV41.VERSION, MessageFormatV4.class ),
286+
arguments( BoltProtocolV42.VERSION, MessageFormatV4.class ) );
282287
}
283288

284289
private static HandshakeHandler newHandler( ChannelPromise handshakeCompletedPromise )

driver/src/test/java/org/neo4j/driver/internal/cluster/loadbalancing/LoadBalancerTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@
4747
import org.neo4j.driver.internal.cluster.RoutingTableHandler;
4848
import org.neo4j.driver.internal.cluster.RoutingTableRegistry;
4949
import org.neo4j.driver.internal.messaging.BoltProtocol;
50-
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
51-
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
50+
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
5251
import org.neo4j.driver.internal.spi.Connection;
5352
import org.neo4j.driver.internal.spi.ConnectionPool;
5453
import org.neo4j.driver.internal.util.FakeClock;
@@ -395,7 +394,7 @@ private static Connection newBoltV4Connection( BoltServerAddress address )
395394
{
396395
Connection connection = mock( Connection.class );
397396
when( connection.serverAddress() ).thenReturn( address );
398-
when( connection.protocol() ).thenReturn( BoltProtocol.forVersion( BoltProtocolV41.VERSION ) );
397+
when( connection.protocol() ).thenReturn( BoltProtocol.forVersion( BoltProtocolV42.VERSION ) );
399398
when( connection.serverVersion() ).thenReturn( ServerVersion.v4_1_0 );
400399
when( connection.release() ).thenReturn( completedWithNull() );
401400
return connection;

driver/src/test/java/org/neo4j/driver/internal/messaging/BoltProtocolVersionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class BoltProtocolVersionTest
2828
{
2929

3030
@ParameterizedTest( name = "V{0}.{1}" )
31-
@CsvSource( {"3, 0", "4, 0", "4, 1", "100, 100", "255, 255", "0, 0"} )
31+
@CsvSource( {"3, 0", "4, 0", "4, 1", "4, 2", "100, 100", "255, 255", "0, 0"} )
3232
void shouldParseVersion( int major, int minor )
3333
{
3434
BoltProtocolVersion protocolVersion = new BoltProtocolVersion( major, minor );
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2002-2020 "Neo4j,"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal.messaging.v42;
20+
21+
import org.neo4j.driver.internal.messaging.BoltProtocol;
22+
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41Test;
23+
24+
public class BoltProtocolV42Test extends BoltProtocolV41Test
25+
{
26+
@Override
27+
protected BoltProtocol createProtocol()
28+
{
29+
return BoltProtocolV42.INSTANCE;
30+
}
31+
}

driver/src/test/java/org/neo4j/driver/internal/util/ServerVersionTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
2424
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
2525
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
26+
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
2627

2728
import static java.lang.Integer.MAX_VALUE;
2829
import static org.hamcrest.MatcherAssert.assertThat;
@@ -71,6 +72,7 @@ void shouldReturnCorrectServerVersionFromBoltProtocolVersion()
7172
{
7273
assertEquals( ServerVersion.v4_0_0, ServerVersion.fromBoltProtocolVersion( BoltProtocolV4.VERSION ) );
7374
assertEquals( ServerVersion.v4_1_0, ServerVersion.fromBoltProtocolVersion( BoltProtocolV41.VERSION ) );
75+
assertEquals( ServerVersion.v4_2_0, ServerVersion.fromBoltProtocolVersion( BoltProtocolV42.VERSION ) );
7476
assertEquals( ServerVersion.vInDev, ServerVersion.fromBoltProtocolVersion( new BoltProtocolVersion( MAX_VALUE, MAX_VALUE ) ) );
7577
}
7678
}

driver/src/test/java/org/neo4j/driver/util/TestUtil.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3;
7272
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
7373
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
74+
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
7475
import org.neo4j.driver.internal.retry.RetryLogic;
7576
import org.neo4j.driver.internal.spi.Connection;
7677
import org.neo4j.driver.internal.spi.ConnectionProvider;
@@ -532,7 +533,7 @@ public static Connection connectionMock( String databaseName, AccessMode mode, B
532533
setupSuccessfulPullAll( connection, "BEGIN" );
533534
}
534535
else if ( version.equals( BoltProtocolV3.VERSION ) || version.equals( BoltProtocolV4.VERSION ) ||
535-
version.equals( BoltProtocolV41.VERSION ))
536+
version.equals( BoltProtocolV41.VERSION ) || version.equals( BoltProtocolV42.VERSION ))
536537
{
537538
setupSuccessResponse( connection, CommitMessage.class );
538539
setupSuccessResponse( connection, RollbackMessage.class );

0 commit comments

Comments
 (0)