2525
2626import static org .assertj .core .api .Assertions .assertThat ;
2727import static org .mockito .BDDMockito .given ;
28+ import static org .mockito .Mockito .mock ;
2829import static org .mockito .Mockito .when ;
2930
3031import com .datastax .oss .driver .api .core .CqlIdentifier ;
32+ import com .datastax .oss .driver .api .core .DefaultConsistencyLevel ;
3133import com .datastax .oss .driver .api .core .RequestRoutingType ;
3234import com .datastax .oss .driver .api .core .config .DefaultDriverOption ;
3335import com .datastax .oss .driver .api .core .config .DriverExecutionProfile ;
36+ import com .datastax .oss .driver .api .core .cql .BoundStatement ;
37+ import com .datastax .oss .driver .api .core .cql .ColumnDefinitions ;
38+ import com .datastax .oss .driver .api .core .cql .PreparedStatement ;
39+ import com .datastax .oss .driver .api .core .cql .SimpleStatement ;
40+ import com .datastax .oss .driver .api .core .cql .Statement ;
3441import com .datastax .oss .driver .api .core .metadata .Metadata ;
3542import com .datastax .oss .driver .api .core .metadata .Node ;
3643import com .datastax .oss .driver .api .core .metadata .TokenMap ;
3744import com .datastax .oss .driver .api .core .metadata .token .Token ;
3845import com .datastax .oss .driver .api .core .session .Request ;
46+ import com .datastax .oss .driver .internal .core .cql .DefaultBoundStatement ;
3947import com .datastax .oss .driver .internal .core .loadbalancing .BasicLoadBalancingPolicy .RequestRoutingMethod ;
4048import com .datastax .oss .driver .internal .core .session .DefaultSession ;
4149import com .datastax .oss .driver .shaded .guava .common .collect .ImmutableList ;
4250import com .datastax .oss .driver .shaded .guava .common .collect .ImmutableMap ;
4351import com .datastax .oss .driver .shaded .guava .common .collect .ImmutableSet ;
4452import com .datastax .oss .protocol .internal .util .Bytes ;
4553import java .nio .ByteBuffer ;
54+ import java .util .Collections ;
4655import java .util .Optional ;
4756import java .util .Queue ;
4857import java .util .UUID ;
@@ -165,6 +174,135 @@ public void should_dispatch_to_regular_query_plan_when_request_is_regular() {
165174 assertThat (plan2 ).containsExactlyInAnyOrder (node1 , node2 , node3 );
166175 }
167176
177+ @ Test
178+ public void
179+ should_dispatch_to_preserve_query_plan_when_simple_local_serial_select_and_config_preserve () {
180+ // Given
181+ initPolicy ("PRESERVE_REPLICA_ORDER" );
182+ SimpleStatement statement =
183+ SimpleStatement .builder (
184+ "SELECT * FROM unique_key_value "
185+ + "WHERE unique_key=? AND unique_value=? AND context=?" )
186+ .setConsistencyLevel (DefaultConsistencyLevel .LOCAL_SERIAL )
187+ .setRoutingKeyspace (KEYSPACE )
188+ .setRoutingKey (ROUTING_KEY )
189+ .build ();
190+ given (tokenMap .getReplicasList (KEYSPACE , null , ROUTING_KEY ))
191+ .willReturn (ImmutableList .of (node1 , node2 ));
192+
193+ // When
194+ Queue <Node > plan = policy .newQueryPlan (statement , session );
195+
196+ // Then
197+ assertThat (statement .isLWT ()).isFalse ();
198+ assertThat (statement .getRequestRoutingType ()).isNull ();
199+ assertThat (policy .getRequestRoutingMethod (statement ))
200+ .isEqualTo (RequestRoutingMethod .PRESERVE_REPLICA_ORDER );
201+ assertThat (plan ).containsExactly (node1 , node2 , node3 );
202+ }
203+
204+ @ Test
205+ public void
206+ should_dispatch_to_preserve_query_plan_when_prepared_local_serial_select_and_config_preserve () {
207+ // Given
208+ initPolicy ("PRESERVE_REPLICA_ORDER" );
209+ BoundStatement statement = newRegularBoundStatementWithLocalSerialConsistency ();
210+ given (tokenMap .getReplicasList (KEYSPACE , null , ROUTING_KEY ))
211+ .willReturn (ImmutableList .of (node1 , node2 ));
212+
213+ // When
214+ Queue <Node > plan = policy .newQueryPlan (statement , session );
215+
216+ // Then
217+ assertThat (statement .isLWT ()).isFalse ();
218+ assertThat (statement .getRequestRoutingType ()).isEqualTo (RequestRoutingType .REGULAR );
219+ assertThat (policy .getRequestRoutingMethod (statement ))
220+ .isEqualTo (RequestRoutingMethod .PRESERVE_REPLICA_ORDER );
221+ assertThat (plan ).containsExactly (node1 , node2 , node3 );
222+ }
223+
224+ @ Test
225+ public void should_dispatch_to_regular_query_plan_when_local_serial_select_and_config_regular () {
226+ // Given
227+ initPolicy ("REGULAR" );
228+ SimpleStatement statement =
229+ SimpleStatement .builder (
230+ "SELECT * FROM unique_key_value "
231+ + "WHERE unique_key=? AND unique_value=? AND context=?" )
232+ .setConsistencyLevel (DefaultConsistencyLevel .LOCAL_SERIAL )
233+ .setRoutingKeyspace (KEYSPACE )
234+ .setRoutingKey (ROUTING_KEY )
235+ .build ();
236+ given (tokenMap .getReplicasList (KEYSPACE , null , ROUTING_KEY ))
237+ .willReturn (ImmutableList .of (node1 , node2 ));
238+
239+ // When
240+ Queue <Node > plan = policy .newQueryPlan (statement , session );
241+
242+ // Then
243+ assertThat (statement .isLWT ()).isFalse ();
244+ assertThat (policy .getRequestRoutingMethod (statement )).isEqualTo (RequestRoutingMethod .REGULAR );
245+ assertThat (plan ).containsExactlyInAnyOrder (node1 , node2 , node3 );
246+ }
247+
248+ @ Test
249+ public void should_dispatch_to_preserve_query_plan_when_profile_has_local_serial_consistency () {
250+ // Given
251+ initPolicy ("PRESERVE_REPLICA_ORDER" );
252+ DriverExecutionProfile serialProfile = mock (DriverExecutionProfile .class );
253+ when (serialProfile .getString (DefaultDriverOption .REQUEST_CONSISTENCY ))
254+ .thenReturn ("LOCAL_SERIAL" );
255+ SimpleStatement statement =
256+ SimpleStatement .builder (
257+ "SELECT * FROM unique_key_value "
258+ + "WHERE unique_key=? AND unique_value=? AND context=?" )
259+ .setExecutionProfile (serialProfile )
260+ .setRoutingKeyspace (KEYSPACE )
261+ .setRoutingKey (ROUTING_KEY )
262+ .build ();
263+ given (tokenMap .getReplicasList (KEYSPACE , null , ROUTING_KEY ))
264+ .willReturn (ImmutableList .of (node1 , node2 ));
265+
266+ // When
267+ Queue <Node > plan = policy .newQueryPlan (statement , session );
268+
269+ // Then
270+ assertThat (statement .getConsistencyLevel ()).isNull ();
271+ assertThat (policy .getRequestRoutingMethod (statement ))
272+ .isEqualTo (RequestRoutingMethod .PRESERVE_REPLICA_ORDER );
273+ assertThat (plan ).containsExactly (node1 , node2 , node3 );
274+ }
275+
276+ @ Test
277+ public void
278+ should_dispatch_to_preserve_query_plan_when_profile_name_has_local_serial_consistency () {
279+ // Given
280+ initPolicy ("PRESERVE_REPLICA_ORDER" );
281+ DriverExecutionProfile serialProfile = mock (DriverExecutionProfile .class );
282+ when (config .getProfile ("serial" )).thenReturn (serialProfile );
283+ when (serialProfile .getString (DefaultDriverOption .REQUEST_CONSISTENCY ))
284+ .thenReturn ("LOCAL_SERIAL" );
285+ SimpleStatement statement =
286+ SimpleStatement .builder (
287+ "SELECT * FROM unique_key_value "
288+ + "WHERE unique_key=? AND unique_value=? AND context=?" )
289+ .setExecutionProfileName ("serial" )
290+ .setRoutingKeyspace (KEYSPACE )
291+ .setRoutingKey (ROUTING_KEY )
292+ .build ();
293+ given (tokenMap .getReplicasList (KEYSPACE , null , ROUTING_KEY ))
294+ .willReturn (ImmutableList .of (node1 , node2 ));
295+
296+ // When
297+ Queue <Node > plan = policy .newQueryPlan (statement , session );
298+
299+ // Then
300+ assertThat (statement .getConsistencyLevel ()).isNull ();
301+ assertThat (policy .getRequestRoutingMethod (statement ))
302+ .isEqualTo (RequestRoutingMethod .PRESERVE_REPLICA_ORDER );
303+ assertThat (plan ).containsExactly (node1 , node2 , node3 );
304+ }
305+
168306 @ Test
169307 public void should_dispatch_to_preserve_query_plan_when_lwt_and_config_preserve () {
170308 // Given
@@ -186,6 +324,37 @@ public void should_dispatch_to_preserve_query_plan_when_lwt_and_config_preserve(
186324 assertThat (plan3 ).containsExactly (node2 , node1 , node3 );
187325 }
188326
327+ private BoundStatement newRegularBoundStatementWithLocalSerialConsistency () {
328+ PreparedStatement preparedStatement = mock (PreparedStatement .class );
329+ ColumnDefinitions variableDefinitions = mock (ColumnDefinitions .class );
330+ when (preparedStatement .isLWT ()).thenReturn (false );
331+ when (preparedStatement .getRequestRoutingType ()).thenReturn (RequestRoutingType .REGULAR );
332+ when (preparedStatement .getVariableDefinitions ()).thenReturn (variableDefinitions );
333+ return new DefaultBoundStatement (
334+ preparedStatement ,
335+ variableDefinitions ,
336+ new ByteBuffer [0 ],
337+ null ,
338+ null ,
339+ KEYSPACE ,
340+ ROUTING_KEY ,
341+ null ,
342+ Collections .emptyMap (),
343+ null ,
344+ false ,
345+ Statement .NO_DEFAULT_TIMESTAMP ,
346+ null ,
347+ Integer .MIN_VALUE ,
348+ DefaultConsistencyLevel .LOCAL_SERIAL ,
349+ null ,
350+ null ,
351+ null ,
352+ null ,
353+ null ,
354+ Statement .NO_NOW_IN_SECONDS ,
355+ null );
356+ }
357+
189358 @ Test
190359 public void should_dispatch_to_regular_query_plan_when_lwt_but_config_regular () {
191360 // Given
0 commit comments