Skip to content

Commit b2237b8

Browse files
authored
Include bookmarks in the ROUTE message. (#861)
Adding bookmarks to ROUTE message The new format is: `ROUTE {routingContext} [listOfBookmarks] dbname` where (in order of occurrence): - `routingContext` provided by the driver. - A list of bookmarks. If none are provided then an empty list should be supplied. - the `dbname` of the database for which a new routing table is being requested. This is a string value and can be replaced with `null` to return the default database's routing table.
1 parent 30060f0 commit b2237b8

File tree

6 files changed

+50
-15
lines changed

6 files changed

+50
-15
lines changed

driver/src/main/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public CompletionStage<RoutingProcedureResponse> run( Connection connection, Dat
7171
CompletableFuture<Map<String,Value>> completableFuture = createCompletableFuture.get();
7272

7373
DirectConnection directConnection = toDirectConnection( connection, databaseName );
74-
directConnection.writeAndFlush( new RouteMessage( routingContext, databaseName.databaseName().orElse( null ) ),
74+
directConnection.writeAndFlush( new RouteMessage( routingContext, bookmark, databaseName.databaseName().orElse( null ) ),
7575
new RouteMessageResponseHandler( completableFuture ) );
7676
return completableFuture
7777
.thenApply( routingTable -> new RoutingProcedureResponse( getQuery( databaseName ), singletonList( toRecord( routingTable ) ) ) )

driver/src/main/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
package org.neo4j.driver.internal.messaging.encode;
2020

2121
import java.io.IOException;
22+
import java.util.Collections;
2223

2324
import org.neo4j.driver.internal.messaging.Message;
2425
import org.neo4j.driver.internal.messaging.MessageEncoder;
2526
import org.neo4j.driver.internal.messaging.ValuePacker;
2627
import org.neo4j.driver.internal.messaging.request.RouteMessage;
2728

29+
import static org.neo4j.driver.Values.value;
2830
import static org.neo4j.driver.internal.util.Preconditions.checkArgument;
2931

3032
/**
@@ -37,8 +39,9 @@ public void encode( Message message, ValuePacker packer ) throws IOException
3739
{
3840
checkArgument( message, RouteMessage.class );
3941
RouteMessage routeMessage = (RouteMessage) message;
40-
packer.packStructHeader( 2, message.signature() );
42+
packer.packStructHeader( 3, message.signature() );
4143
packer.pack( routeMessage.getRoutingContext() );
44+
packer.pack( routeMessage.getBookmark().isPresent() ? value( routeMessage.getBookmark().get().values() ) : value( Collections.emptyList() ) );
4245
packer.pack( routeMessage.getDatabaseName() );
4346
}
4447
}

driver/src/main/java/org/neo4j/driver/internal/messaging/request/RouteMessage.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020

2121
import java.util.Map;
2222
import java.util.Objects;
23+
import java.util.Optional;
2324

25+
import org.neo4j.driver.Bookmark;
2426
import org.neo4j.driver.Value;
2527
import org.neo4j.driver.internal.messaging.Message;
2628

@@ -36,17 +38,20 @@ public class RouteMessage implements Message
3638
{
3739
public final static byte SIGNATURE = 0x66;
3840
private final Map<String,Value> routingContext;
41+
private final Bookmark bookmark;
3942
private final String databaseName;
4043

4144
/**
4245
* Constructor
4346
*
4447
* @param routingContext The routing context used to define the routing table. Multi-datacenter deployments is one of its use cases.
48+
* @param bookmark The bookmark used when getting the routing table.
4549
* @param databaseName The name of the database to get the routing table for.
4650
*/
47-
public RouteMessage( Map<String,Value> routingContext, String databaseName )
51+
public RouteMessage( Map<String,Value> routingContext, Bookmark bookmark, String databaseName )
4852
{
4953
this.routingContext = unmodifiableMap( routingContext );
54+
this.bookmark = bookmark;
5055
this.databaseName = databaseName;
5156
}
5257

@@ -55,6 +60,11 @@ public Map<String,Value> getRoutingContext()
5560
return routingContext;
5661
}
5762

63+
public Optional<Bookmark> getBookmark()
64+
{
65+
return Optional.ofNullable( bookmark );
66+
}
67+
5868
public String getDatabaseName()
5969
{
6070
return databaseName;
@@ -69,7 +79,7 @@ public byte signature()
6979
@Override
7080
public String toString()
7181
{
72-
return String.format( "ROUTE %s %s", routingContext, databaseName );
82+
return String.format( "ROUTE %s %s %s", routingContext, bookmark, databaseName );
7383
}
7484

7585
@Override

driver/src/test/java/org/neo4j/driver/internal/cluster/RouteMessageRoutingProcedureRunnerTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.stream.Collectors;
3333
import java.util.stream.Stream;
3434

35+
import org.neo4j.driver.Bookmark;
3536
import org.neo4j.driver.Record;
3637
import org.neo4j.driver.Value;
3738
import org.neo4j.driver.Values;
@@ -90,7 +91,7 @@ void shouldRequestRoutingTableForAllValidInputScenarios( RoutingContext routingC
9091
assertEquals( routingTable.get( "ttl" ), record.get( "ttl" ) );
9192
assertEquals( routingTable.get( "servers" ), record.get( "servers" ) );
9293

93-
verifyMessageWasWrittenAndFlushed( connection, completableFuture, routingContext, databaseName );
94+
verifyMessageWasWrittenAndFlushed( connection, completableFuture, routingContext, null, databaseName );
9495
verify( connection ).release();
9596
}
9697

@@ -113,19 +114,19 @@ void shouldReturnFailureWhenSomethingHappensGettingTheRoutingTable()
113114
assertEquals( reason, response.error() );
114115
assertThrows( IllegalStateException.class, () -> response.records().size() );
115116

116-
verifyMessageWasWrittenAndFlushed( connection, completableFuture, RoutingContext.EMPTY, DatabaseNameUtil.defaultDatabase() );
117+
verifyMessageWasWrittenAndFlushed( connection, completableFuture, RoutingContext.EMPTY, null, DatabaseNameUtil.defaultDatabase() );
117118
verify( connection ).release();
118119
}
119120

120121
private void verifyMessageWasWrittenAndFlushed( Connection connection, CompletableFuture<Map<String,Value>> completableFuture,
121-
RoutingContext routingContext, DatabaseName databaseName )
122+
RoutingContext routingContext, Bookmark bookmark, DatabaseName databaseName )
122123
{
123124
Map<String,Value> context = routingContext.toMap()
124125
.entrySet()
125126
.stream()
126127
.collect( Collectors.toMap( Map.Entry::getKey, entry -> Values.value( entry.getValue() ) ) );
127128

128-
verify( connection ).writeAndFlush( eq( new RouteMessage( context, databaseName.databaseName().orElse( null ) ) ),
129+
verify( connection ).writeAndFlush( eq( new RouteMessage( context, bookmark, databaseName.databaseName().orElse( null ) ) ),
129130
eq( new RouteMessageResponseHandler( completableFuture ) ) );
130131
}
131132

driver/src/test/java/org/neo4j/driver/internal/messaging/encode/RouteMessageEncoderTest.java

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,18 @@
2828
import java.util.HashMap;
2929
import java.util.Map;
3030

31+
import org.neo4j.driver.Bookmark;
3132
import org.neo4j.driver.Value;
32-
import org.neo4j.driver.Values;
33+
import org.neo4j.driver.internal.InternalBookmark;
3334
import org.neo4j.driver.internal.messaging.Message;
3435
import org.neo4j.driver.internal.messaging.ValuePacker;
3536
import org.neo4j.driver.internal.messaging.request.RouteMessage;
3637

38+
import static java.util.Collections.emptyList;
3739
import static org.junit.jupiter.api.Assertions.assertThrows;
3840
import static org.mockito.Mockito.inOrder;
3941
import static org.mockito.Mockito.mock;
42+
import static org.neo4j.driver.Values.value;
4043

4144
class RouteMessageEncoderTest
4245
{
@@ -51,12 +54,31 @@ void shouldEncodeRouteMessage(String databaseName) throws IOException
5154
{
5255
Map<String, Value> routingContext = getRoutingContext();
5356

54-
encoder.encode( new RouteMessage( getRoutingContext(), databaseName ), packer );
57+
encoder.encode( new RouteMessage( getRoutingContext(), null, databaseName ), packer );
5558

5659
InOrder inOrder = inOrder( packer );
5760

58-
inOrder.verify( packer ).packStructHeader( 2, (byte) 0x66 );
61+
inOrder.verify( packer ).packStructHeader( 3, (byte) 0x66 );
5962
inOrder.verify( packer ).pack( routingContext );
63+
inOrder.verify( packer ).pack( value( emptyList() ) );
64+
inOrder.verify( packer ).pack( databaseName );
65+
}
66+
67+
@ParameterizedTest
68+
@ValueSource(strings = { "neo4j"})
69+
@NullSource
70+
void shouldEncodeRouteMessageWithBookmark(String databaseName) throws IOException
71+
{
72+
Map<String, Value> routingContext = getRoutingContext();
73+
Bookmark bookmark = InternalBookmark.parse( "somebookmark" );
74+
75+
encoder.encode( new RouteMessage( getRoutingContext(), bookmark, databaseName ), packer );
76+
77+
InOrder inOrder = inOrder( packer );
78+
79+
inOrder.verify( packer ).packStructHeader( 3, (byte) 0x66 );
80+
inOrder.verify( packer ).pack( routingContext );
81+
inOrder.verify( packer ).pack( value( bookmark.values() ) );
6082
inOrder.verify( packer ).pack( databaseName );
6183
}
6284

@@ -70,8 +92,7 @@ void shouldThrowIllegalArgumentIfMessageIsNotRouteMessage()
7092

7193
private Map<String,Value> getRoutingContext() {
7294
Map<String, Value> routingContext = new HashMap<>();
73-
routingContext.put( "ip", Values.value( "127.0.0.1" ) );
95+
routingContext.put( "ip", value( "127.0.0.1" ) );
7496
return routingContext;
7597
}
76-
77-
}
98+
}

driver/src/test/java/org/neo4j/driver/internal/messaging/v43/MessageWriterV43Test.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,6 @@ private RouteMessage routeMessage()
147147
{
148148
Map<String,Value> routeContext = new HashMap<>();
149149
routeContext.put( "someContext", Values.value( 124 ) );
150-
return new RouteMessage( routeContext, "dbName" );
150+
return new RouteMessage( routeContext, InternalBookmark.empty(), "dbName" );
151151
}
152152
}

0 commit comments

Comments
 (0)