29
29
import org .neo4j .driver .v1 .Logger ;
30
30
import org .neo4j .driver .v1 .Record ;
31
31
import org .neo4j .driver .v1 .Statement ;
32
- import org .neo4j .driver .v1 .StatementResult ;
33
32
import 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 ;
35
35
import org .neo4j .driver .v1 .exceptions .value .ValueException ;
36
36
import org .neo4j .driver .v1 .util .Function ;
37
37
38
+ import static java .lang .String .format ;
39
+ import static org .neo4j .driver .internal .cluster .ClusterComposition .Provider .PROTOCOL_ERROR_MESSAGE ;
40
+
38
41
final class ClusterComposition
39
42
{
40
43
interface Provider
41
44
{
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
+ }
43
58
44
- ClusterComposition getClusterComposition ( Connection connection ) throws ServiceUnavailableException ;
59
+ ProcedureNotFoundException ( String message , Throwable e )
60
+ {
61
+ super ( message , e );
62
+ }
63
+ }
45
64
46
65
final class Default implements Provider
47
66
{
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 );
49
68
private final Clock clock ;
50
69
private final Logger log ;
51
70
@@ -56,30 +75,40 @@ final class Default implements Provider
56
75
}
57
76
58
77
@ Override
59
- public ClusterComposition getClusterComposition ( Connection connection ) throws ServiceUnavailableException
78
+ public ClusterComposition getClusterComposition ( Connection connection )
79
+ throws ProtocolException , ProcedureNotFoundException
60
80
{
61
- StatementResult cursor = getServers ( connection );
62
- List <Record > records = cursor .list ();
81
+ List <Record > records = getServers ( connection );
63
82
log .info ( "Got getServers response: %s" , records );
64
83
long now = clock .millis ();
65
- try
84
+
85
+ if ( records .size () != 1 )
66
86
{
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 () ) );
73
90
}
74
- finally
91
+ ClusterComposition cluster = read ( records .get ( 0 ), now );
92
+ if ( cluster .isIllegalResponse () )
75
93
{
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 ) );
77
96
}
97
+ return cluster ;
78
98
}
79
99
80
- private StatementResult getServers ( Connection connection )
100
+ private List < Record > getServers ( Connection connection ) throws ProcedureNotFoundException
81
101
{
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
+ }
83
112
}
84
113
}
85
114
}
@@ -120,7 +149,11 @@ private ClusterComposition( long expirationTimestamp )
120
149
121
150
public boolean isValid ()
122
151
{
123
- return !routers .isEmpty () && !writers .isEmpty ();
152
+ return !writers .isEmpty ();
153
+ }
154
+ public boolean isIllegalResponse ()
155
+ {
156
+ return routers .isEmpty () || readers .isEmpty ();
124
157
}
125
158
126
159
public Set <BoltServerAddress > readers ()
@@ -173,7 +206,7 @@ public Void apply( Value value )
173
206
}
174
207
catch ( ValueException e )
175
208
{
176
- return null ;
209
+ throw new ProtocolException ( format ( "%s%nUnparsable record received." , PROTOCOL_ERROR_MESSAGE ), e ) ;
177
210
}
178
211
}
179
212
0 commit comments