Skip to content

Commit f32ab91

Browse files
committed
Add support for Bolt 5
1 parent 1ed07b8 commit f32ab91

37 files changed

+1505
-119
lines changed

driver/clirr-ignored-differences.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,22 @@
8686
<to>org.neo4j.driver.Config$TrustStrategy trustCustomCertificateSignedBy(java.io.File[])</to>
8787
</difference>
8888

89+
<difference>
90+
<className>org/neo4j/driver/types/Entity</className>
91+
<differenceType>7012</differenceType>
92+
<method>java.lang.String elementId()</method>
93+
</difference>
94+
95+
<difference>
96+
<className>org/neo4j/driver/types/Relationship</className>
97+
<differenceType>7012</differenceType>
98+
<method>java.lang.String endNodeElementId()</method>
99+
</difference>
100+
101+
<difference>
102+
<className>org/neo4j/driver/types/Relationship</className>
103+
<differenceType>7012</differenceType>
104+
<method>java.lang.String startNodeElementId()</method>
105+
</difference>
106+
89107
</differences>

driver/src/main/java/org/neo4j/driver/internal/InternalEntity.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,27 @@
1919
package org.neo4j.driver.internal;
2020

2121
import java.util.Map;
22+
import java.util.function.Function;
2223

24+
import org.neo4j.driver.Value;
25+
import org.neo4j.driver.Values;
2326
import org.neo4j.driver.internal.util.Extract;
2427
import org.neo4j.driver.internal.util.Iterables;
2528
import org.neo4j.driver.internal.value.MapValue;
26-
import org.neo4j.driver.Value;
27-
import org.neo4j.driver.Values;
2829
import org.neo4j.driver.types.Entity;
29-
import java.util.function.Function;
3030

3131
import static org.neo4j.driver.Values.ofObject;
3232

3333
public abstract class InternalEntity implements Entity, AsValue
3434
{
3535
private final long id;
36+
private final String elementId;
3637
private final Map<String,Value> properties;
3738

38-
public InternalEntity( long id, Map<String, Value> properties )
39+
public InternalEntity( long id, String elementId, Map<String,Value> properties )
3940
{
4041
this.id = id;
42+
this.elementId = elementId;
4143
this.properties = properties;
4244
}
4345

@@ -47,6 +49,12 @@ public long id()
4749
return id;
4850
}
4951

52+
@Override
53+
public String elementId()
54+
{
55+
return elementId;
56+
}
57+
5058
@Override
5159
public int size()
5260
{

driver/src/main/java/org/neo4j/driver/internal/InternalNode.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
import java.util.Collections;
2323
import java.util.Map;
2424

25+
import org.neo4j.driver.Value;
2526
import org.neo4j.driver.internal.value.NodeValue;
2627
import org.neo4j.driver.types.Node;
27-
import org.neo4j.driver.Value;
2828

2929
/**
3030
* {@link Node} implementation that directly contains labels and properties.
@@ -35,12 +35,12 @@ public class InternalNode extends InternalEntity implements Node
3535

3636
public InternalNode( long id )
3737
{
38-
this( id, Collections.<String>emptyList(), Collections.<String,Value>emptyMap() );
38+
this( id, String.valueOf( id ), Collections.emptyList(), Collections.emptyMap() );
3939
}
4040

41-
public InternalNode( long id, Collection<String> labels, Map<String, Value> properties )
41+
public InternalNode( long id, String elementId, Collection<String> labels, Map<String,Value> properties )
4242
{
43-
super( id, properties );
43+
super( id, elementId, properties );
4444
this.labels = labels;
4545
}
4646

driver/src/main/java/org/neo4j/driver/internal/InternalRelationship.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,34 @@
2121
import java.util.Collections;
2222
import java.util.Map;
2323

24+
import org.neo4j.driver.Value;
2425
import org.neo4j.driver.internal.value.RelationshipValue;
2526
import org.neo4j.driver.types.Relationship;
26-
import org.neo4j.driver.Value;
2727

2828
/**
2929
* {@link Relationship} implementation that directly contains type and properties.
3030
*/
3131
public class InternalRelationship extends InternalEntity implements Relationship
3232
{
3333
private long start;
34+
private String startElementId;
3435
private long end;
36+
private String endElementId;
3537
private final String type;
3638

37-
public InternalRelationship( long id, long start, long end, String type )
39+
public InternalRelationship( long id, String elementId, long start, String startElementId, long end, String endElementId, String type )
3840
{
39-
this( id, start, end, type, Collections.<String,Value>emptyMap() );
41+
this( id, elementId, start, startElementId, end, endElementId, type, Collections.emptyMap() );
4042
}
4143

42-
public InternalRelationship( long id, long start, long end, String type,
43-
Map<String, Value> properties )
44+
public InternalRelationship( long id, String elementId, long start, String startElementId, long end, String endElementId, String type,
45+
Map<String,Value> properties )
4446
{
45-
super( id, properties );
47+
super( id, elementId, properties );
4648
this.start = start;
49+
this.startElementId = startElementId;
4750
this.end = end;
51+
this.endElementId = endElementId;
4852
this.type = type;
4953
}
5054

@@ -54,11 +58,15 @@ public boolean hasType( String relationshipType )
5458
return type().equals( relationshipType );
5559
}
5660

57-
/** Modify the start/end identities of this relationship */
58-
public void setStartAndEnd( long start, long end )
61+
/**
62+
* Modify the start/end identities of this relationship
63+
*/
64+
public void setStartAndEnd( long start, String startElementId, long end, String endElementId )
5965
{
6066
this.start = start;
67+
this.startElementId = startElementId;
6168
this.end = end;
69+
this.endElementId = endElementId;
6270
}
6371

6472
@Override
@@ -67,12 +75,24 @@ public long startNodeId()
6775
return start;
6876
}
6977

78+
@Override
79+
public String startNodeElementId()
80+
{
81+
return startElementId;
82+
}
83+
7084
@Override
7185
public long endNodeId()
7286
{
7387
return end;
7488
}
7589

90+
@Override
91+
public String endNodeElementId()
92+
{
93+
return endElementId;
94+
}
95+
7696
@Override
7797
public String type()
7898
{

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222

2323
import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
2424
import org.neo4j.driver.internal.messaging.v3.BoltProtocolV3;
25-
import org.neo4j.driver.internal.messaging.v4.BoltProtocolV4;
2625
import org.neo4j.driver.internal.messaging.v41.BoltProtocolV41;
2726
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
2827
import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44;
28+
import org.neo4j.driver.internal.messaging.v5.BoltProtocolV5;
2929

3030
import static io.netty.buffer.Unpooled.copyInt;
3131
import static io.netty.buffer.Unpooled.unreleasableBuffer;
@@ -42,9 +42,9 @@ public final class BoltProtocolUtil
4242

4343
private static final ByteBuf HANDSHAKE_BUF = unreleasableBuffer( copyInt(
4444
BOLT_MAGIC_PREAMBLE,
45+
BoltProtocolV5.VERSION.toInt(),
4546
BoltProtocolV44.VERSION.toIntRange( BoltProtocolV42.VERSION ),
4647
BoltProtocolV41.VERSION.toInt(),
47-
BoltProtocolV4.VERSION.toInt(),
4848
BoltProtocolV3.VERSION.toInt() ) ).asReadOnly();
4949

5050
private static final String HANDSHAKE_STRING = createHandshakeString();

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.neo4j.driver.internal.messaging.v42.BoltProtocolV42;
4242
import org.neo4j.driver.internal.messaging.v43.BoltProtocolV43;
4343
import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44;
44+
import org.neo4j.driver.internal.messaging.v5.BoltProtocolV5;
4445
import org.neo4j.driver.internal.spi.Connection;
4546

4647
import static org.neo4j.driver.internal.async.connection.ChannelAttributes.protocolVersion;
@@ -171,6 +172,10 @@ else if ( BoltProtocolV44.VERSION.equals( version ) )
171172
{
172173
return BoltProtocolV44.INSTANCE;
173174
}
175+
else if ( BoltProtocolV5.VERSION.equals( version ) )
176+
{
177+
return BoltProtocolV5.INSTANCE;
178+
}
174179
throw new ClientException( "Unknown protocol version: " + version );
175180
}
176181
}

driver/src/main/java/org/neo4j/driver/internal/messaging/common/CommonValueUnpacker.java

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public Value[] unpackArray() throws IOException
141141
return values;
142142
}
143143

144-
private Value unpack() throws IOException
144+
protected Value unpack() throws IOException
145145
{
146146
PackType type = unpacker.peekNextType();
147147
switch ( type )
@@ -182,7 +182,7 @@ private Value unpack() throws IOException
182182
throw new IOException( "Unknown value type: " + type );
183183
}
184184

185-
protected Value unpackStruct( long size, byte type ) throws IOException
185+
private Value unpackStruct( long size, byte type ) throws IOException
186186
{
187187
switch ( type )
188188
{
@@ -214,11 +214,11 @@ protected Value unpackStruct( long size, byte type ) throws IOException
214214
ensureCorrectStructSize( TypeConstructor.POINT, POINT_3D_STRUCT_SIZE, size );
215215
return unpackPoint3D();
216216
case NODE:
217-
ensureCorrectStructSize( TypeConstructor.NODE, NODE_FIELDS, size );
217+
ensureCorrectStructSize( TypeConstructor.NODE, getNodeFields(), size );
218218
InternalNode adapted = unpackNode();
219219
return new NodeValue( adapted );
220220
case RELATIONSHIP:
221-
ensureCorrectStructSize( TypeConstructor.RELATIONSHIP, 5, size );
221+
ensureCorrectStructSize( TypeConstructor.RELATIONSHIP, getRelationshipFields(), size );
222222
return unpackRelationship();
223223
case PATH:
224224
ensureCorrectStructSize( TypeConstructor.PATH, 3, size );
@@ -228,19 +228,20 @@ protected Value unpackStruct( long size, byte type ) throws IOException
228228
}
229229
}
230230

231-
private Value unpackRelationship() throws IOException
231+
protected Value unpackRelationship() throws IOException
232232
{
233233
long urn = unpacker.unpackLong();
234234
long startUrn = unpacker.unpackLong();
235235
long endUrn = unpacker.unpackLong();
236236
String relType = unpacker.unpackString();
237237
Map<String,Value> props = unpackMap();
238238

239-
InternalRelationship adapted = new InternalRelationship( urn, startUrn, endUrn, relType, props );
239+
InternalRelationship adapted =
240+
new InternalRelationship( urn, String.valueOf( urn ), startUrn, String.valueOf( startUrn ), endUrn, String.valueOf( endUrn ), relType, props );
240241
return new RelationshipValue( adapted );
241242
}
242243

243-
private InternalNode unpackNode() throws IOException
244+
protected InternalNode unpackNode() throws IOException
244245
{
245246
long urn = unpacker.unpackLong();
246247

@@ -258,16 +259,16 @@ private InternalNode unpackNode() throws IOException
258259
props.put( key, unpack() );
259260
}
260261

261-
return new InternalNode( urn, labels, props );
262+
return new InternalNode( urn, String.valueOf( urn ), labels, props );
262263
}
263264

264-
private Value unpackPath() throws IOException
265+
protected Value unpackPath() throws IOException
265266
{
266267
// List of unique nodes
267268
Node[] uniqNodes = new Node[(int) unpacker.unpackListHeader()];
268269
for ( int i = 0; i < uniqNodes.length; i++ )
269270
{
270-
ensureCorrectStructSize( TypeConstructor.NODE, NODE_FIELDS, unpacker.unpackStructHeader() );
271+
ensureCorrectStructSize( TypeConstructor.NODE, getNodeFields(), unpacker.unpackStructHeader() );
271272
ensureCorrectStructSignature( "NODE", NODE, unpacker.unpackStructSignature() );
272273
uniqNodes[i] = unpackNode();
273274
}
@@ -281,7 +282,7 @@ private Value unpackPath() throws IOException
281282
long id = unpacker.unpackLong();
282283
String relType = unpacker.unpackString();
283284
Map<String,Value> props = unpackMap();
284-
uniqRels[i] = new InternalRelationship( id, -1, -1, relType, props );
285+
uniqRels[i] = new InternalRelationship( id, String.valueOf( id ), -1, String.valueOf( -1 ), -1, String.valueOf( -1 ), relType, props );
285286
}
286287

287288
// Path sequence
@@ -303,12 +304,12 @@ private Value unpackPath() throws IOException
303304
if ( relIdx < 0 )
304305
{
305306
rel = uniqRels[(-relIdx) - 1]; // -1 because rel idx are 1-indexed
306-
rel.setStartAndEnd( nextNode.id(), prevNode.id() );
307+
rel.setStartAndEnd( nextNode.id(), String.valueOf( nextNode.id() ), prevNode.id(), String.valueOf( prevNode.id() ) );
307308
}
308309
else
309310
{
310311
rel = uniqRels[relIdx - 1];
311-
rel.setStartAndEnd( prevNode.id(), nextNode.id() );
312+
rel.setStartAndEnd( prevNode.id(), String.valueOf( prevNode.id() ), nextNode.id(), String.valueOf( nextNode.id() ) );
312313
}
313314

314315
nodes[i + 1] = nextNode;
@@ -330,7 +331,7 @@ protected final void ensureCorrectStructSize( TypeConstructor typeConstructor, i
330331
}
331332
}
332333

333-
private void ensureCorrectStructSignature( String structName, byte expected, byte actual )
334+
protected void ensureCorrectStructSignature( String structName, byte expected, byte actual )
334335
{
335336
if ( expected != actual )
336337
{
@@ -417,6 +418,14 @@ private static ZonedDateTime newZonedDateTime( long epochSecondLocal, long nano,
417418
LocalDateTime localDateTime = LocalDateTime.ofInstant( instant, UTC );
418419
return ZonedDateTime.of( localDateTime, zoneId );
419420
}
420-
}
421421

422+
protected int getNodeFields()
423+
{
424+
return NODE_FIELDS;
425+
}
422426

427+
protected int getRelationshipFields()
428+
{
429+
return 5;
430+
}
431+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) "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.v5;
20+
21+
import org.neo4j.driver.internal.messaging.BoltProtocol;
22+
import org.neo4j.driver.internal.messaging.BoltProtocolVersion;
23+
import org.neo4j.driver.internal.messaging.MessageFormat;
24+
import org.neo4j.driver.internal.messaging.v44.BoltProtocolV44;
25+
26+
public class BoltProtocolV5 extends BoltProtocolV44
27+
{
28+
public static final BoltProtocolVersion VERSION = new BoltProtocolVersion( 5, 0 );
29+
public static final BoltProtocol INSTANCE = new BoltProtocolV5();
30+
31+
@Override
32+
public MessageFormat createMessageFormat()
33+
{
34+
return new MessageFormatV5();
35+
}
36+
37+
@Override
38+
public BoltProtocolVersion version()
39+
{
40+
return VERSION;
41+
}
42+
}

0 commit comments

Comments
 (0)