2929import org .neo4j .driver .v1 .Logger ;
3030import org .neo4j .driver .v1 .Record ;
3131import org .neo4j .driver .v1 .Statement ;
32- import org .neo4j .driver .v1 .StatementResult ;
3332import org .neo4j .driver .v1 .Value ;
34- import org .neo4j .driver .v1 .exceptions .ServiceUnavailableException ;
33+ import org .neo4j .driver .v1 .exceptions .ClientException ;
34+ import org .neo4j .driver .v1 .exceptions .ProtocolException ;
3535import org .neo4j .driver .v1 .exceptions .value .ValueException ;
3636import org .neo4j .driver .v1 .util .Function ;
3737
38+ import static java .lang .String .format ;
39+ import static org .neo4j .driver .internal .cluster .ClusterComposition .Provider .PROTOCOL_ERROR_MESSAGE ;
40+
3841final class ClusterComposition
3942{
4043 interface Provider
4144 {
42- String GET_SERVERS = "CALL dbms.cluster.routing.getServers" ;
45+ String GET_SERVERS = "dbms.cluster.routing.getServers" ;
46+ String CALL_GET_SERVERS = "CALL " + GET_SERVERS ;
47+ String PROTOCOL_ERROR_MESSAGE = "Failed to parse '" + GET_SERVERS + "' result received from server." ;
48+
49+ ClusterComposition getClusterComposition ( Connection connection )
50+ throws ProtocolException , ProcedureNotFoundException ;
51+
52+ class ProcedureNotFoundException extends Exception
53+ {
54+ ProcedureNotFoundException ( String message )
55+ {
56+ super ( message );
57+ }
4358
44- ClusterComposition getClusterComposition ( Connection connection ) throws ServiceUnavailableException ;
59+ ProcedureNotFoundException ( String message , Throwable e )
60+ {
61+ super ( message , e );
62+ }
63+ }
4564
4665 final class Default implements Provider
4766 {
48- private static final Statement GET_SERVER = new Statement ( Provider .GET_SERVERS );
67+ private static final Statement CALL_GET_SERVER = new Statement ( Provider .CALL_GET_SERVERS );
4968 private final Clock clock ;
5069 private final Logger log ;
5170
@@ -56,30 +75,40 @@ final class Default implements Provider
5675 }
5776
5877 @ Override
59- public ClusterComposition getClusterComposition ( Connection connection ) throws ServiceUnavailableException
78+ public ClusterComposition getClusterComposition ( Connection connection )
79+ throws ProtocolException , ProcedureNotFoundException
6080 {
61- StatementResult cursor = getServers ( connection );
62- List <Record > records = cursor .list ();
81+ List <Record > records = getServers ( connection );
6382 log .info ( "Got getServers response: %s" , records );
6483 long now = clock .millis ();
65- try
84+
85+ if ( records .size () != 1 )
6686 {
67- if ( records .size () != 1 )
68- {
69- // server returned too few or too many rows, this is a contract violation, treat as incapable
70- return null ;
71- }
72- return read ( records .get ( 0 ), now );
87+ throw new ProtocolException ( format (
88+ "%s%nRecords received '%s' is too few or too many." , PROTOCOL_ERROR_MESSAGE ,
89+ records .size () ) );
7390 }
74- finally
91+ ClusterComposition cluster = read ( records .get ( 0 ), now );
92+ if ( cluster .isIllegalResponse () )
7593 {
76- cursor .consume (); // make sure we exhaust the results
94+ throw new ProtocolException ( format ( "%s%nNo router or reader found in response." ,
95+ PROTOCOL_ERROR_MESSAGE ) );
7796 }
97+ return cluster ;
7898 }
7999
80- private StatementResult getServers ( Connection connection )
100+ private List < Record > getServers ( Connection connection ) throws ProcedureNotFoundException
81101 {
82- return NetworkSession .run ( connection , GET_SERVER );
102+ try
103+ {
104+ return NetworkSession .run ( connection , CALL_GET_SERVER ).list ();
105+ }
106+ catch ( ClientException e )
107+ {
108+ throw new ProcedureNotFoundException ( format ("Failed to call '%s' procedure on server. " +
109+ "Please make sure that there is a Neo4j 3.1+ causal cluster up running." ,
110+ GET_SERVERS ), e );
111+ }
83112 }
84113 }
85114 }
@@ -120,7 +149,11 @@ private ClusterComposition( long expirationTimestamp )
120149
121150 public boolean isValid ()
122151 {
123- return !routers .isEmpty () && !writers .isEmpty ();
152+ return !writers .isEmpty ();
153+ }
154+ public boolean isIllegalResponse ()
155+ {
156+ return routers .isEmpty () || readers .isEmpty ();
124157 }
125158
126159 public Set <BoltServerAddress > readers ()
@@ -173,7 +206,7 @@ public Void apply( Value value )
173206 }
174207 catch ( ValueException e )
175208 {
176- return null ;
209+ throw new ProtocolException ( format ( "%s%nUnparsable record received." , PROTOCOL_ERROR_MESSAGE ), e ) ;
177210 }
178211 }
179212
0 commit comments