|
16 | 16 |
|
17 | 17 | package com.alibaba.fluss.client.table;
|
18 | 18 |
|
| 19 | +import com.alibaba.fluss.client.Connection; |
| 20 | +import com.alibaba.fluss.client.ConnectionFactory; |
19 | 21 | import com.alibaba.fluss.client.admin.ClientToServerITCaseBase;
|
20 | 22 | import com.alibaba.fluss.client.table.scanner.ScanRecord;
|
21 | 23 | import com.alibaba.fluss.client.table.scanner.log.LogScanner;
|
22 | 24 | import com.alibaba.fluss.client.table.scanner.log.ScanRecords;
|
23 | 25 | import com.alibaba.fluss.client.table.writer.AppendWriter;
|
24 | 26 | import com.alibaba.fluss.client.table.writer.UpsertWriter;
|
| 27 | +import com.alibaba.fluss.cluster.ServerNode; |
| 28 | +import com.alibaba.fluss.cluster.ServerType; |
| 29 | +import com.alibaba.fluss.exception.FlussRuntimeException; |
25 | 30 | import com.alibaba.fluss.row.GenericRow;
|
26 | 31 | import com.alibaba.fluss.row.InternalRow;
|
27 | 32 |
|
|
31 | 36 | import java.time.Duration;
|
32 | 37 | import java.util.ArrayList;
|
33 | 38 | import java.util.List;
|
| 39 | +import java.util.stream.Collectors; |
34 | 40 |
|
35 | 41 | import static com.alibaba.fluss.record.TestData.DATA1_ROW_TYPE;
|
36 | 42 | import static com.alibaba.fluss.record.TestData.DATA1_TABLE_DESCRIPTOR;
|
|
39 | 45 | import static com.alibaba.fluss.record.TestData.DATA1_TABLE_PATH_PK;
|
40 | 46 | import static com.alibaba.fluss.testutils.DataTestUtils.row;
|
41 | 47 | import static com.alibaba.fluss.testutils.InternalRowListAssert.assertThatRows;
|
| 48 | +import static org.assertj.core.api.Assertions.assertThatThrownBy; |
42 | 49 |
|
43 | 50 | /** IT case for {@link FlussTable} in the case of one tablet server fails. */
|
44 | 51 | class FlussFailServerTableITCase extends ClientToServerITCaseBase {
|
@@ -146,6 +153,39 @@ void testLogScan() throws Exception {
|
146 | 153 | }
|
147 | 154 | }
|
148 | 155 |
|
| 156 | + @Test |
| 157 | + void testRetryGetTabletServerNodes() throws Exception { |
| 158 | + createTable(DATA1_TABLE_PATH, DATA1_TABLE_DESCRIPTOR, false); |
| 159 | + try (Table table = conn.getTable(DATA1_TABLE_PATH)) { |
| 160 | + table.newScan().createLogScanner(); |
| 161 | + |
| 162 | + List<ServerNode> serverNodes = |
| 163 | + conn.getAdmin().getServerNodes().get().stream() |
| 164 | + .filter( |
| 165 | + serverNode -> |
| 166 | + serverNode.serverType() == ServerType.TABLET_SERVER) |
| 167 | + .collect(Collectors.toList()); |
| 168 | + |
| 169 | + // kill all tablet server |
| 170 | + for (ServerNode serverNode : serverNodes) { |
| 171 | + FLUSS_CLUSTER_EXTENSION.stopTabletServer(serverNode.id()); |
| 172 | + } |
| 173 | + |
| 174 | + try (Connection connNew = ConnectionFactory.createConnection(clientConf)) { |
| 175 | + assertThatThrownBy(() -> connNew.getTable(DATA1_TABLE_PATH)) |
| 176 | + .cause() |
| 177 | + .isInstanceOf(FlussRuntimeException.class) |
| 178 | + .hasMessage( |
| 179 | + "Execution of Fluss get one available tablet failed, no alive tablet server in cluster, retry times = %d.", |
| 180 | + 5); |
| 181 | + } finally { |
| 182 | + for (ServerNode serverNode : serverNodes) { |
| 183 | + FLUSS_CLUSTER_EXTENSION.startTabletServer(serverNode.id()); |
| 184 | + } |
| 185 | + } |
| 186 | + } |
| 187 | + } |
| 188 | + |
149 | 189 | private List<InternalRow> toRows(ScanRecords scanRecords) {
|
150 | 190 | List<InternalRow> rows = new ArrayList<>();
|
151 | 191 | for (ScanRecord scanRecord : scanRecords) {
|
|
0 commit comments