11package io .tarantool .driver .integration ;
22
3+ import java .lang .reflect .InvocationTargetException ;
4+ import java .lang .reflect .Method ;
5+ import java .util .ArrayList ;
6+ import java .util .Arrays ;
7+ import java .util .Collections ;
8+ import java .util .List ;
9+ import java .util .Map ;
10+ import java .util .Optional ;
11+ import java .util .concurrent .CompletableFuture ;
12+ import java .util .concurrent .ExecutionException ;
13+ import java .util .concurrent .ExecutorService ;
14+ import java .util .concurrent .Executors ;
15+ import java .util .concurrent .atomic .AtomicInteger ;
16+
17+ import org .junit .jupiter .api .BeforeAll ;
18+ import org .junit .jupiter .api .BeforeEach ;
19+ import org .junit .jupiter .api .Test ;
20+ import org .testcontainers .shaded .org .apache .commons .lang3 .reflect .FieldUtils ;
21+ import static org .junit .jupiter .api .Assertions .assertEquals ;
22+ import static org .junit .jupiter .api .Assertions .assertFalse ;
23+ import static org .junit .jupiter .api .Assertions .assertNotNull ;
24+ import static org .junit .jupiter .api .Assertions .assertThrows ;
25+ import static org .junit .jupiter .api .Assertions .assertTrue ;
26+
27+ import io .tarantool .driver .TarantoolUtils ;
328import io .tarantool .driver .api .SingleValueCallResult ;
429import io .tarantool .driver .api .TarantoolClient ;
530import io .tarantool .driver .api .TarantoolClientConfig ;
2752import io .tarantool .driver .core .ClusterTarantoolTupleClient ;
2853import io .tarantool .driver .core .ProxyTarantoolTupleClient ;
2954import io .tarantool .driver .core .RetryingTarantoolTupleClient ;
30- import io .tarantool .driver .core .TarantoolTupleResultImpl ;
55+ import io .tarantool .driver .core .connection . TarantoolClusterConnectionManager ;
3156import io .tarantool .driver .core .tuple .TarantoolTupleImpl ;
3257import io .tarantool .driver .exceptions .TarantoolInternalException ;
3358import io .tarantool .driver .exceptions .TarantoolNoSuchProcedureException ;
3762import io .tarantool .driver .mappers .factories .DefaultMessagePackMapperFactory ;
3863import io .tarantool .driver .mappers .factories .ResultMapperFactoryFactory ;
3964import io .tarantool .driver .mappers .factories .ResultMapperFactoryFactoryImpl ;
40- import org .junit .jupiter .api .BeforeAll ;
41- import org .junit .jupiter .api .BeforeEach ;
42- import org .junit .jupiter .api .Test ;
43-
44- import java .util .ArrayList ;
45- import java .util .Arrays ;
46- import java .util .Collections ;
47- import java .util .List ;
48- import java .util .Map ;
49- import java .util .Optional ;
50- import java .util .concurrent .CompletableFuture ;
51- import java .util .concurrent .ExecutionException ;
52- import java .util .concurrent .ExecutorService ;
53- import java .util .concurrent .Executors ;
54-
55- import static org .junit .jupiter .api .Assertions .assertEquals ;
56- import static org .junit .jupiter .api .Assertions .assertFalse ;
57- import static org .junit .jupiter .api .Assertions .assertNotNull ;
58- import static org .junit .jupiter .api .Assertions .assertThrows ;
59- import static org .junit .jupiter .api .Assertions .assertTrue ;
6065
6166/**
6267 * @author Sergey Volgin
@@ -79,6 +84,9 @@ public class ProxyTarantoolClientIT extends SharedCartridgeContainer {
7984 private static final String PK_FIELD_NAME = "profile_id" ;
8085 private static final String BUCKET_ID_FIELD_NAME = "bucket_id" ;
8186 private static final int DEFAULT_TIMEOUT = 5 * 1000 ;
87+ private static TestWrappedClusterAddressProvider addressProvider ;
88+ private static Method getAliveConnections ;
89+ private static TarantoolClusterConnectionManager connectionManager ;
8290
8391 @ BeforeAll
8492 public static void setUp () throws Exception {
@@ -118,7 +126,7 @@ private static TarantoolClusterAddressProvider getClusterAddressProvider() {
118126
119127 TarantoolClusterDiscoveryConfig clusterDiscoveryConfig = new TarantoolClusterDiscoveryConfig .Builder ()
120128 .withEndpoint (endpoint )
121- .withDelay (1 )
129+ .withDelay (300 )
122130 .build ();
123131
124132 return new TestWrappedClusterAddressProvider (
@@ -395,7 +403,7 @@ public void test_clusterUpdate_shouldReturnTuple_ifSearchByFieldName() throws Ex
395403
396404 @ Test
397405 public void test_crudMetadataResponse_shouldReturnTuple_withoutDDLMetadata ()
398- throws ExecutionException , InterruptedException {
406+ throws ExecutionException , InterruptedException {
399407 Integer id = 123000 ;
400408 String field1 = "Jane Doe" ;
401409 Integer field2 = 999 ;
@@ -672,4 +680,63 @@ public void multiResultWithErrorTest() throws ExecutionException, InterruptedExc
672680 }
673681 assertNotNull (thrown , "Exception was not thrown" );
674682 }
683+
684+ @ Test
685+ public void test_should_reconnect_ifReconnectIsInvoked () throws Exception {
686+ assertEquals (3 , getAliveConnections ());
687+
688+ container .execInContainer ("cartridge" , "stop" , "--run-dir=/tmp/run" , "second-router" );
689+ TarantoolUtils .retry (() -> {
690+ try {
691+ client .getVersion ();
692+ assertEquals (2 , getAliveConnections ());
693+ } catch (IllegalAccessException | NoSuchMethodException e ) {
694+ throw new RuntimeException (e );
695+ }
696+ });
697+ container .execInContainer ("cartridge" , "start" , "--run-dir=/tmp/run" , "--data-dir=/tmp/data" , "-d" );
698+
699+ TarantoolUtils .retry (20 , 200 , () -> {
700+ try {
701+ client .getVersion ();
702+ assertEquals (3 , getAliveConnections ());
703+ } catch (IllegalAccessException | NoSuchMethodException e ) {
704+ throw new RuntimeException (e );
705+ }
706+ });
707+ }
708+
709+ private static int getAliveConnections () throws IllegalAccessException , NoSuchMethodException {
710+ if (addressProvider == null ) {
711+ ClusterTarantoolTupleClient
712+ innerClient = (ClusterTarantoolTupleClient ) FieldUtils .readField (
713+ FieldUtils .readField (client , "client" , true ),
714+ "client" , true );
715+ connectionManager =
716+ (TarantoolClusterConnectionManager ) FieldUtils .readField (innerClient , "connectionManager" , true );
717+
718+ getAliveConnections =
719+ connectionManager .getClass ().getSuperclass ()
720+ .getDeclaredMethod ("getAliveConnections" , TarantoolServerAddress .class );
721+ getAliveConnections .setAccessible (true );
722+
723+ addressProvider =
724+ (TestWrappedClusterAddressProvider ) FieldUtils .readField (innerClient , "addressProvider" , true );
725+ }
726+
727+ return getAliveConnectionsAux ();
728+ }
729+
730+ private static int getAliveConnectionsAux () {
731+ AtomicInteger res = new AtomicInteger ();
732+ addressProvider .getAddresses ().forEach (r -> {
733+ try {
734+ res .addAndGet (((List <?>) getAliveConnections .invoke (connectionManager , r )).size ());
735+ } catch (IllegalAccessException | InvocationTargetException e ) {
736+ throw new RuntimeException (e );
737+ }
738+ });
739+
740+ return res .get ();
741+ }
675742}
0 commit comments