Skip to content

Commit

Permalink
Address review comments and report errors during type unpacking
Browse files Browse the repository at this point in the history
  • Loading branch information
ali-ince committed Apr 3, 2018
1 parent 3e1aac5 commit 347540f
Show file tree
Hide file tree
Showing 7 changed files with 336 additions and 68 deletions.
Expand Up @@ -22,30 +22,30 @@
import java.util.HashMap;
import java.util.Map;

import org.neo4j.bolt.v1.messaging.Neo4jPackV1;
import org.neo4j.bolt.v2.messaging.Neo4jPackV2;

import static java.util.Collections.unmodifiableMap;

public enum KnownType
{
NODE( 'N', "Node" ),
RELATIONSHIP( 'R', "Relationship" ),
UNBOUND_RELATIONSHIP( 'r', "Relationship" ),
PATH( 'P', "Path" ),
POINT_2D( 'X', "Point" ),
POINT_3D( 'Y', "Point" ),
DATE( 'D', "LocalDate" ),
TIME( 'T', "OffsetTime" ),
LOCAL_TIME( 't', "LocalTime" ),
LOCAL_DATE_TIME( 'd', "LocalDateTime" ),
DATE_TIME_WITH_ZONE_OFFSET( 'F', "OffsetDateTime" ),
DATE_TIME_WITH_ZONE_NAME( 'f', "ZonedDateTime" ),
DURATION( 'E', "Duration" );
NODE( Neo4jPackV1.NODE, "Node" ),
RELATIONSHIP( Neo4jPackV1.RELATIONSHIP, "Relationship" ),
UNBOUND_RELATIONSHIP( Neo4jPackV1.UNBOUND_RELATIONSHIP, "Relationship" ),
PATH( Neo4jPackV1.PATH, "Path" ),
POINT_2D( Neo4jPackV2.POINT_2D, "Point" ),
POINT_3D( Neo4jPackV2.POINT_3D, "Point" ),
DATE( Neo4jPackV2.DATE, "LocalDate" ),
TIME( Neo4jPackV2.TIME, "OffsetTime" ),
LOCAL_TIME( Neo4jPackV2.LOCAL_TIME, "LocalTime" ),
LOCAL_DATE_TIME( Neo4jPackV2.LOCAL_DATE_TIME, "LocalDateTime" ),
DATE_TIME_WITH_ZONE_OFFSET( Neo4jPackV2.DATE_TIME_WITH_ZONE_OFFSET, "OffsetDateTime" ),
DATE_TIME_WITH_ZONE_NAME( Neo4jPackV2.DATE_TIME_WITH_ZONE_NAME, "ZonedDateTime" ),
DURATION( Neo4jPackV2.DURATION, "Duration" );

private final byte signature;
private final String description;

KnownType( char signature, String description )
{
this( (byte)signature, description );
}

KnownType( byte signature, String description )
{
this.signature = signature;
Expand All @@ -62,22 +62,26 @@ public String description()
return description;
}

private static Map<Byte, KnownType> byteToKnownTypeMap = new HashMap<>();
static
{
for ( KnownType type : KnownType.values() )
{
byteToKnownTypeMap.put( type.signature, type );
}
}
private static Map<Byte, KnownType> knownTypesBySignature = knownTypesBySignature();

public static KnownType valueOf( byte signature )
{
return byteToKnownTypeMap.get( signature );
return knownTypesBySignature.get( signature );
}

public static KnownType valueOf( char signature )
{
return KnownType.valueOf( (byte)signature );
return knownTypesBySignature.get( (byte)signature );
}

private static Map<Byte,KnownType> knownTypesBySignature()
{
KnownType[] types = KnownType.values();
Map<Byte,KnownType> result = new HashMap<>( types.length * 2 );
for ( KnownType type : types )
{
result.put( type.signature, type );
}
return unmodifiableMap( result );
}
}
Expand Up @@ -56,7 +56,7 @@ protected void channelRead0( ChannelHandlerContext channelHandlerContext, ByteBu
}
catch ( BoltIOException ex )
{
if ( ex.causesFailure() )
if ( ex.causesFailureMessage() )
{
messageHandler.onExternalError( Neo4jError.from( ex ) );
}
Expand Down
Expand Up @@ -44,7 +44,7 @@ public Status status()
return status;
}

public boolean causesFailure()
public boolean causesFailureMessage()
{
return status != Status.Request.InvalidFormat;
}
Expand Down
Expand Up @@ -61,9 +61,16 @@ public class Neo4jPackV1 implements Neo4jPack
public static final long VERSION = 1;

public static final byte NODE = 'N';
public static final int NODE_SIZE = 3;

public static final byte RELATIONSHIP = 'R';
public static final int RELATIONSHIP_SIZE = 5;

public static final byte UNBOUND_RELATIONSHIP = 'r';
public static final int UNBOUND_RELATIONSHIP_SIZE = 3;

public static final byte PATH = 'P';
public static final int PATH_SIZE = 3;

@Override
public Neo4jPack.Packer newPacker( PackOutput output )
Expand Down Expand Up @@ -118,7 +125,7 @@ public void writeNodeReference( long nodeId )
@Override
public void writeNode( long nodeId, TextArray labels, MapValue properties ) throws IOException
{
packStructHeader( 3, NODE );
packStructHeader( NODE_SIZE, NODE );
pack( nodeId );
packListHeader( labels.length() );
for ( int i = 0; i < labels.length(); i++ )
Expand All @@ -138,7 +145,7 @@ public void writeRelationshipReference( long relationshipId )
public void writeRelationship( long relationshipId, long startNodeId, long endNodeId, TextValue type, MapValue properties )
throws IOException
{
packStructHeader( 5, RELATIONSHIP );
packStructHeader( RELATIONSHIP_SIZE, RELATIONSHIP );
pack( relationshipId );
pack( startNodeId );
pack( endNodeId );
Expand Down Expand Up @@ -194,7 +201,7 @@ public void writePath( NodeValue[] nodes, RelationshipValue[] relationships ) th
// the offset
// into the
// node list (zero indexed) and so on.
packStructHeader( 3, PATH );
packStructHeader( PATH_SIZE, PATH );

writeNodesForPath( nodes );
writeRelationshipsForPath( relationships );
Expand Down Expand Up @@ -282,7 +289,7 @@ private void writeRelationshipsForPath( RelationshipValue[] relationships ) thro
//Note that we are not doing relationship.writeTo(this) here since the serialization protocol
//requires these to be _unbound relationships_, thus relationships without any start node nor
// end node.
packStructHeader( 3, UNBOUND_RELATIONSHIP );
packStructHeader( UNBOUND_RELATIONSHIP_SIZE, UNBOUND_RELATIONSHIP );
pack( edge.id() );
edge.type().writeTo( this );
edge.properties().writeTo( this );
Expand Down Expand Up @@ -463,9 +470,9 @@ public AnyValue unpack() throws IOException
}
case STRUCT:
{
unpackStructHeader();
long size = unpackStructHeader();
char signature = unpackStructSignature();
return unpackStruct( signature );
return unpackStruct( signature, size );
}
case END_OF_STREAM:
{
Expand Down Expand Up @@ -514,7 +521,7 @@ else if ( size == UNKNOWN_SIZE )
}
}

protected AnyValue unpackStruct( char signature ) throws IOException
protected AnyValue unpackStruct( char signature, long size ) throws IOException
{
KnownType knownType = KnownType.valueOf( signature );
if ( knownType == null )
Expand Down
Expand Up @@ -23,6 +23,7 @@
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

import org.neo4j.bolt.messaging.KnownType;
import org.neo4j.bolt.v1.packstream.utf8.UTF8Encoder;

/**
Expand Down Expand Up @@ -764,6 +765,16 @@ public PackType peekNextType() throws IOException
final byte markerByte = in.peekByte();
return type( markerByte );
}

public static void ensureCorrectStructSize( KnownType knownType, int expected, long actual ) throws IOException
{
if ( expected != actual )
{
throw new PackStreamException(
String.format( "Invalid message received, serialized %s structures should have %d fields, " + "received %s structure has %d fields.",
knownType.description(), expected, knownType.description(), actual ) );
}
}
}

public static class PackStreamException extends IOException
Expand Down

0 comments on commit 347540f

Please sign in to comment.