diff --git a/example/pipe-count-point-processor/src/main/java/org/apache/iotdb/CountPointProcessor.java b/example/pipe-count-point-processor/src/main/java/org/apache/iotdb/CountPointProcessor.java
index 61a888d4eca23..a8c71d0fa59fc 100644
--- a/example/pipe-count-point-processor/src/main/java/org/apache/iotdb/CountPointProcessor.java
+++ b/example/pipe-count-point-processor/src/main/java/org/apache/iotdb/CountPointProcessor.java
@@ -44,26 +44,28 @@ public class CountPointProcessor implements PipeProcessor {
private PartialPath aggregateSeries;
@Override
- public void validate(PipeParameterValidator validator) {
+ public void validate(final PipeParameterValidator validator) {
validator.validateRequiredAttribute(AGGREGATE_SERIES_KEY);
}
@Override
- public void customize(PipeParameters parameters, PipeProcessorRuntimeConfiguration configuration)
+ public void customize(
+ final PipeParameters parameters, final PipeProcessorRuntimeConfiguration configuration)
throws Exception {
this.aggregateSeries = new PartialPath(parameters.getString(AGGREGATE_SERIES_KEY));
}
@Override
- public void process(TabletInsertionEvent tabletInsertionEvent, EventCollector eventCollector) {
+ public void process(
+ final TabletInsertionEvent tabletInsertionEvent, final EventCollector eventCollector) {
tabletInsertionEvent.processTablet(
(tablet, rowCollector) -> writePointCount.addAndGet(tablet.rowSize));
}
@Override
- public void process(Event event, EventCollector eventCollector) throws Exception {
+ public void process(final Event event, final EventCollector eventCollector) throws Exception {
if (event instanceof PipeHeartbeatEvent) {
- Tablet tablet =
+ final Tablet tablet =
new Tablet(
aggregateSeries.getIDeviceID().toString(),
Collections.singletonList(
@@ -73,7 +75,7 @@ public void process(Event event, EventCollector eventCollector) throws Exception
tablet.addTimestamp(0, System.currentTimeMillis());
tablet.addValue(aggregateSeries.getMeasurement(), 0, writePointCount.get());
eventCollector.collect(
- new PipeRawTabletInsertionEvent(tablet, false, null, null, null, false));
+ new PipeRawTabletInsertionEvent(tablet, false, null, 0, null, null, false));
}
}
diff --git a/example/schema/pom.xml b/example/schema/pom.xml
index 07c3085767967..54246f9c8064a 100644
--- a/example/schema/pom.xml
+++ b/example/schema/pom.xml
@@ -32,7 +32,6 @@
ch.qos.logbacklogback-classic
- 1.3.13org.apache.tsfile
diff --git a/example/session/src/main/java/org/apache/iotdb/SubscriptionSessionExample.java b/example/session/src/main/java/org/apache/iotdb/SubscriptionSessionExample.java
index 62c869e02bf0a..3c3ae618ce3ec 100644
--- a/example/session/src/main/java/org/apache/iotdb/SubscriptionSessionExample.java
+++ b/example/session/src/main/java/org/apache/iotdb/SubscriptionSessionExample.java
@@ -25,14 +25,23 @@
import org.apache.iotdb.rpc.subscription.config.TopicConstant;
import org.apache.iotdb.session.Session;
import org.apache.iotdb.session.subscription.SubscriptionSession;
+import org.apache.iotdb.session.subscription.consumer.AckStrategy;
+import org.apache.iotdb.session.subscription.consumer.ConsumeResult;
import org.apache.iotdb.session.subscription.consumer.SubscriptionPullConsumer;
+import org.apache.iotdb.session.subscription.consumer.SubscriptionPushConsumer;
import org.apache.iotdb.session.subscription.payload.SubscriptionMessage;
import org.apache.iotdb.session.subscription.payload.SubscriptionSessionDataSet;
+import org.apache.iotdb.session.subscription.payload.SubscriptionTsFileHandler;
import org.apache.tsfile.read.TsFileReader;
+import org.apache.tsfile.read.common.Path;
+import org.apache.tsfile.read.expression.QueryExpression;
+import org.apache.tsfile.read.query.dataset.QueryDataSet;
import java.io.IOException;
+import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
@@ -46,11 +55,14 @@ public class SubscriptionSessionExample {
private static final int PORT = 6667;
private static final String TOPIC_1 = "topic1";
- private static final String TOPIC_2 = "`topic2`";
+ private static final String TOPIC_2 = "`'topic2'`";
+ private static final String TOPIC_3 = "`\"topic3\"`";
+ private static final String TOPIC_4 = "`\"top \\.i.c4\"`";
- public static final long SLEEP_NS = 1_000_000_000L;
- public static final long POLL_TIMEOUT_MS = 10_000L;
+ private static final long SLEEP_NS = 1_000_000_000L;
+ private static final long POLL_TIMEOUT_MS = 10_000L;
private static final int MAX_RETRY_TIMES = 3;
+ private static final int PARALLELISM = 8;
private static void prepareData() throws Exception {
// Open session
@@ -66,13 +78,13 @@ private static void prepareData() throws Exception {
// Insert some historical data
final long currentTime = System.currentTimeMillis();
- for (int i = 0; i < 10000; ++i) {
+ for (int i = 0; i < 100; ++i) {
session.executeNonQueryStatement(
String.format("insert into root.db.d1(time, s1, s2) values (%s, 1, 2)", i));
session.executeNonQueryStatement(
- String.format("insert into root.db.d2(time, s3, s4) values (%s, 3, 4)", currentTime + i));
+ String.format("insert into root.db.d2(time, s1, s2) values (%s, 3, 4)", currentTime + i));
session.executeNonQueryStatement(
- String.format("insert into root.sg.d3(time, s5) values (%s, 5)", currentTime + 2 * i));
+ String.format("insert into root.sg.d3(time, s1) values (%s, 5)", currentTime + 2 * i));
}
session.executeNonQueryStatement("flush");
@@ -104,11 +116,16 @@ private static void dataQuery() throws Exception {
session = null;
}
- private static void subscriptionExample1() throws Exception {
+ /** single pull consumer subscribe topic with path and time range */
+ private static void dataSubscription1() throws Exception {
// Create topics
try (final SubscriptionSession subscriptionSession = new SubscriptionSession(HOST, PORT)) {
subscriptionSession.open();
- subscriptionSession.createTopic(TOPIC_1);
+ final Properties config = new Properties();
+ config.put(TopicConstant.PATH_KEY, "root.db.d1.s1");
+ config.put(TopicConstant.START_TIME_KEY, 25);
+ config.put(TopicConstant.END_TIME_KEY, 75);
+ subscriptionSession.createTopic(TOPIC_1, config);
}
int retryCount = 0;
@@ -151,7 +168,8 @@ private static void subscriptionExample1() throws Exception {
consumer1.close();
}
- private static void subscriptionExample2() throws Exception {
+ /** multi pull consumer subscribe topic with tsfile format */
+ private static void dataSubscription2() throws Exception {
try (final SubscriptionSession subscriptionSession = new SubscriptionSession(HOST, PORT)) {
subscriptionSession.open();
final Properties config = new Properties();
@@ -160,7 +178,7 @@ private static void subscriptionExample2() throws Exception {
}
final List threads = new ArrayList<>();
- for (int i = 0; i < 8; ++i) {
+ for (int i = 0; i < PARALLELISM; ++i) {
final int idx = i;
final Thread thread =
new Thread(
@@ -187,7 +205,16 @@ private static void subscriptionExample2() throws Exception {
}
for (final SubscriptionMessage message : messages) {
try (final TsFileReader reader = message.getTsFileHandler().openReader()) {
- // do something...
+ final QueryDataSet dataSet =
+ reader.query(
+ QueryExpression.create(
+ Arrays.asList(
+ new Path("root.db.d2", "s2", true),
+ new Path("root.db.d3", "s1", true)),
+ null));
+ while (dataSet.hasNext()) {
+ System.out.println(dataSet.next());
+ }
}
}
consumer2.commitSync(messages);
@@ -206,10 +233,109 @@ private static void subscriptionExample2() throws Exception {
}
}
+ /** multi push consumer subscribe topic with tsfile format and query mode */
+ private static void dataSubscription3() throws Exception {
+ try (final SubscriptionSession subscriptionSession = new SubscriptionSession(HOST, PORT)) {
+ subscriptionSession.open();
+ final Properties config = new Properties();
+ config.put(TopicConstant.FORMAT_KEY, TopicConstant.FORMAT_TS_FILE_HANDLER_VALUE);
+ config.put(TopicConstant.MODE_KEY, TopicConstant.MODE_QUERY_VALUE);
+ subscriptionSession.createTopic(TOPIC_3, config);
+ }
+
+ final List threads = new ArrayList<>();
+ for (int i = 0; i < PARALLELISM; ++i) {
+ final int idx = i;
+ final Thread thread =
+ new Thread(
+ () -> {
+ // Subscription: builder-style ctor
+ try (final SubscriptionPushConsumer consumer3 =
+ new SubscriptionPushConsumer.Builder()
+ .consumerId("c" + idx)
+ .consumerGroupId("cg3")
+ .ackStrategy(AckStrategy.AFTER_CONSUME)
+ .consumeListener(
+ message -> {
+ // do something for SubscriptionTsFileHandler
+ System.out.println(
+ message.getTsFileHandler().getFile().getAbsolutePath());
+ return ConsumeResult.SUCCESS;
+ })
+ .buildPushConsumer()) {
+ consumer3.open();
+ consumer3.subscribe(TOPIC_3);
+ while (consumer3.hasMoreData()) {
+ LockSupport.parkNanos(SLEEP_NS); // wait some time
+ }
+ }
+ });
+ thread.start();
+ threads.add(thread);
+ }
+
+ for (final Thread thread : threads) {
+ thread.join();
+ }
+ }
+
+ /** multi pull consumer subscribe topic with tsfile format and query mode */
+ private static void dataSubscription4() throws Exception {
+ try (final SubscriptionSession subscriptionSession = new SubscriptionSession(HOST, PORT)) {
+ subscriptionSession.open();
+ final Properties config = new Properties();
+ config.put(TopicConstant.FORMAT_KEY, TopicConstant.FORMAT_TS_FILE_HANDLER_VALUE);
+ config.put(TopicConstant.MODE_KEY, TopicConstant.MODE_QUERY_VALUE);
+ subscriptionSession.createTopic(TOPIC_4, config);
+ }
+
+ final List threads = new ArrayList<>();
+ for (int i = 0; i < PARALLELISM; ++i) {
+ final int idx = i;
+ final Thread thread =
+ new Thread(
+ () -> {
+ // Subscription: builder-style ctor
+ try (final SubscriptionPullConsumer consumer4 =
+ new SubscriptionPullConsumer.Builder()
+ .consumerId("c" + idx)
+ .consumerGroupId("cg4")
+ .autoCommit(true)
+ .fileSaveFsync(true)
+ .buildPullConsumer()) {
+ consumer4.open();
+ consumer4.subscribe(TOPIC_4);
+ while (true) {
+ LockSupport.parkNanos(SLEEP_NS); // wait some time
+ if (!consumer4.hasMoreData()) {
+ break;
+ }
+ for (final SubscriptionMessage message : consumer4.poll(POLL_TIMEOUT_MS)) {
+ final SubscriptionTsFileHandler handler = message.getTsFileHandler();
+ handler.moveFile(
+ Paths.get(System.getProperty("user.dir"), "new-subscription-dir")
+ .resolve(handler.getPath().getFileName()));
+ }
+ }
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ thread.start();
+ threads.add(thread);
+ }
+
+ for (final Thread thread : threads) {
+ thread.join();
+ }
+ }
+
public static void main(final String[] args) throws Exception {
prepareData();
- dataQuery();
- subscriptionExample1();
- subscriptionExample2();
+ // dataQuery();
+ // dataSubscription1();
+ // dataSubscription2();
+ // dataSubscription3();
+ dataSubscription4();
}
}
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/ClusterConstant.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/ClusterConstant.java
index d688f2169d5d1..12af0d025f75c 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/ClusterConstant.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/ClusterConstant.java
@@ -120,9 +120,6 @@ public class ClusterConstant {
public static final String COMMON_PROPERTIES_FILE = "iotdb-common.properties";
public static final String IOTDB_SYSTEM_PROPERTIES_FILE = "iotdb-system.properties";
- public static final String SYSTEM_PROPERTIES_FILE = "system.properties";
- public static final String CONFIG_NODE_SYSTEM_PROPERTIES_FILE = "confignode-system.properties";
-
// Properties' keys
// Common
public static final String CONFIG_NODE_CONSENSUS_PROTOCOL_CLASS =
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/EnvUtils.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/EnvUtils.java
index 6ecb87c3f0420..f3c9527e5952f 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/EnvUtils.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/EnvUtils.java
@@ -31,8 +31,8 @@
import java.util.stream.IntStream;
import static org.apache.iotdb.consensus.ConsensusFactory.FAST_IOT_CONSENSUS;
-import static org.apache.iotdb.consensus.ConsensusFactory.IOTV2_CONSENSUS;
import static org.apache.iotdb.consensus.ConsensusFactory.IOT_CONSENSUS;
+import static org.apache.iotdb.consensus.ConsensusFactory.IOT_CONSENSUS_V2;
import static org.apache.iotdb.consensus.ConsensusFactory.RATIS_CONSENSUS;
import static org.apache.iotdb.consensus.ConsensusFactory.REAL_PIPE_CONSENSUS;
import static org.apache.iotdb.consensus.ConsensusFactory.SIMPLE_CONSENSUS;
@@ -224,7 +224,7 @@ public static String fromConsensusFullNameToAbbr(String consensus) {
return IOT_CONSENSUS_STR;
case REAL_PIPE_CONSENSUS:
return PIPE_CONSENSUS_STR;
- case IOTV2_CONSENSUS:
+ case IOT_CONSENSUS_V2:
return STREAM_CONSENSUS_STR;
case FAST_IOT_CONSENSUS:
return BATCH_CONSENSUS_STR;
@@ -244,7 +244,7 @@ public static String fromConsensusAbbrToFullName(String consensus) {
case PIPE_CONSENSUS_STR:
return REAL_PIPE_CONSENSUS;
case STREAM_CONSENSUS_STR:
- return IOTV2_CONSENSUS;
+ return IOT_CONSENSUS_V2;
case BATCH_CONSENSUS_STR:
return FAST_IOT_CONSENSUS;
default:
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java
index 95fed66d08b21..095562db5a51f 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppCommonConfig.java
@@ -438,6 +438,32 @@ public CommonConfig setCnConnectionTimeoutMs(int connectionTimeoutMs) {
return this;
}
+ @Override
+ public CommonConfig setPipeHeartbeatIntervalSecondsForCollectingPipeMeta(
+ int pipeHeartbeatIntervalSecondsForCollectingPipeMeta) {
+ setProperty(
+ "pipe_heartbeat_interval_seconds_for_collecting_pipe_meta",
+ String.valueOf(pipeHeartbeatIntervalSecondsForCollectingPipeMeta));
+ return this;
+ }
+
+ @Override
+ public CommonConfig setPipeMetaSyncerInitialSyncDelayMinutes(
+ long pipeMetaSyncerInitialSyncDelayMinutes) {
+ setProperty(
+ "pipe_meta_syncer_initial_sync_delay_minutes",
+ String.valueOf(pipeMetaSyncerInitialSyncDelayMinutes));
+ return this;
+ }
+
+ @Override
+ public CommonConfig setPipeMetaSyncerSyncIntervalMinutes(long pipeMetaSyncerSyncIntervalMinutes) {
+ setProperty(
+ "pipe_meta_syncer_sync_interval_minutes",
+ String.valueOf(pipeMetaSyncerSyncIntervalMinutes));
+ return this;
+ }
+
// For part of the log directory
public String getClusterConfigStr() {
return fromConsensusFullNameToAbbr(properties.getProperty(CONFIG_NODE_CONSENSUS_PROTOCOL_CLASS))
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java
index 1851590dd411e..7724bcf09c0af 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/config/MppSharedCommonConfig.java
@@ -445,4 +445,29 @@ public CommonConfig setCnConnectionTimeoutMs(int connectionTimeoutMs) {
cnConfig.setCnConnectionTimeoutMs(connectionTimeoutMs);
return this;
}
+
+ @Override
+ public CommonConfig setPipeHeartbeatIntervalSecondsForCollectingPipeMeta(
+ int pipeHeartbeatIntervalSecondsForCollectingPipeMeta) {
+ dnConfig.setPipeHeartbeatIntervalSecondsForCollectingPipeMeta(
+ pipeHeartbeatIntervalSecondsForCollectingPipeMeta);
+ cnConfig.setPipeHeartbeatIntervalSecondsForCollectingPipeMeta(
+ pipeHeartbeatIntervalSecondsForCollectingPipeMeta);
+ return this;
+ }
+
+ @Override
+ public CommonConfig setPipeMetaSyncerInitialSyncDelayMinutes(
+ long pipeMetaSyncerInitialSyncDelayMinutes) {
+ dnConfig.setPipeMetaSyncerInitialSyncDelayMinutes(pipeMetaSyncerInitialSyncDelayMinutes);
+ cnConfig.setPipeMetaSyncerInitialSyncDelayMinutes(pipeMetaSyncerInitialSyncDelayMinutes);
+ return this;
+ }
+
+ @Override
+ public CommonConfig setPipeMetaSyncerSyncIntervalMinutes(long pipeMetaSyncerSyncIntervalMinutes) {
+ dnConfig.setPipeMetaSyncerSyncIntervalMinutes(pipeMetaSyncerSyncIntervalMinutes);
+ cnConfig.setPipeMetaSyncerSyncIntervalMinutes(pipeMetaSyncerSyncIntervalMinutes);
+ return this;
+ }
}
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java
index 84425f298d74c..2fd68b5bbf621 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java
@@ -640,10 +640,10 @@ public void setTestMethodName(String testMethodName) {
@Override
public void dumpTestJVMSnapshot() {
for (ConfigNodeWrapper configNodeWrapper : configNodeWrapperList) {
- configNodeWrapper.dumpJVMSnapshot(testMethodName);
+ configNodeWrapper.executeJstack(testMethodName);
}
for (DataNodeWrapper dataNodeWrapper : dataNodeWrapperList) {
- dataNodeWrapper.dumpJVMSnapshot(testMethodName);
+ dataNodeWrapper.executeJstack(testMethodName);
}
}
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java
index fa5447bc5b071..942b6a9e01242 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java
@@ -38,11 +38,14 @@
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
+import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
+import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.net.MalformedURLException;
@@ -61,6 +64,7 @@
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
import java.util.stream.Stream;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.CLUSTER_CONFIGURATIONS;
@@ -566,7 +570,6 @@ public String getNodePath() {
return System.getProperty(USER_DIR) + File.separator + TARGET + File.separator + getId();
}
- @Override
public void dumpJVMSnapshot(String testCaseName) {
JMXServiceURL url;
try {
@@ -675,4 +678,72 @@ private String getKillPoints() {
public abstract String getSystemPropertiesPath();
protected abstract MppJVMConfig initVMConfig();
+
+ @Override
+ public void executeJstack() {
+ executeJstack(logger::info);
+ }
+
+ @Override
+ public void executeJstack(final String testCaseName) {
+ final String fileName =
+ getLogDirPath() + File.separator + testCaseName + "_" + getId() + "-threads.jstack";
+ try (final PrintWriter output = new PrintWriter(fileName)) {
+ executeJstack(output::println);
+ } catch (final IOException e) {
+ logger.warn("IOException occurred when executing Jstack for {}", this.getId(), e);
+ }
+ logger.info("Jstack execution output can be found at {}", fileName);
+ }
+
+ private void executeJstack(final Consumer consumer) {
+ final long pid = this.getPid();
+ if (pid == -1) {
+ logger.warn("Failed to get pid for {} before executing Jstack", this.getId());
+ return;
+ }
+ final String command = "jstack -l " + pid;
+ logger.info("Executing command {} for {}", command, this.getId());
+ try {
+ final Process process = Runtime.getRuntime().exec(command);
+ try (final BufferedReader reader =
+ new BufferedReader(new InputStreamReader(process.getInputStream()))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ consumer.accept(line);
+ }
+ }
+ final int exitCode = process.waitFor();
+ logger.info("Command {} exited with code {}", command, exitCode);
+ } catch (final IOException e) {
+ logger.warn("IOException occurred when executing Jstack for {}", this.getId(), e);
+ } catch (final InterruptedException e) {
+ Thread.currentThread().interrupt();
+ logger.warn("InterruptedException occurred when executing Jstack for {}", this.getId(), e);
+ }
+ }
+
+ /**
+ * @return The native process ID of the process, -1 if failure.
+ */
+ @Override
+ public long getPid() {
+ final JMXServiceURL url;
+ try {
+ url =
+ new JMXServiceURL(
+ String.format("service:jmx:rmi:///jndi/rmi://127.0.0.1:%d/jmxrmi", jmxPort));
+ } catch (final MalformedURLException ignored) {
+ return -1;
+ }
+ try (final JMXConnector connector = JMXConnectorFactory.connect(url)) {
+ final MBeanServerConnection mbsc = connector.getMBeanServerConnection();
+ final RuntimeMXBean rmbean =
+ ManagementFactory.newPlatformMXBeanProxy(
+ mbsc, ManagementFactory.RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
+ return Long.parseLong(rmbean.getName().split("@")[0]);
+ } catch (final Throwable ignored) {
+ return -1;
+ }
+ }
}
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/ConfigNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/ConfigNodeWrapper.java
index a457149f5985e..a93c54c52b82a 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/ConfigNodeWrapper.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/ConfigNodeWrapper.java
@@ -20,6 +20,7 @@
package org.apache.iotdb.it.env.cluster.node;
import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.confignode.conf.ConfigNodeConstant;
import org.apache.iotdb.it.env.cluster.EnvUtils;
import org.apache.iotdb.it.env.cluster.config.MppBaseConfig;
import org.apache.iotdb.it.env.cluster.config.MppJVMConfig;
@@ -37,7 +38,6 @@
import static org.apache.iotdb.it.env.cluster.ClusterConstant.CONFIG_NODE_INIT_HEAP_SIZE;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.CONFIG_NODE_MAX_DIRECT_MEMORY_SIZE;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.CONFIG_NODE_MAX_HEAP_SIZE;
-import static org.apache.iotdb.it.env.cluster.ClusterConstant.CONFIG_NODE_SYSTEM_PROPERTIES_FILE;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.DATA_REGION_CONSENSUS_PROTOCOL_CLASS;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.DATA_REPLICATION_FACTOR;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.DEFAULT_CONFIG_NODE_COMMON_PROPERTIES;
@@ -105,7 +105,7 @@ protected String getDefaultCommonConfigPath() {
@Override
public String getSystemPropertiesPath() {
- return workDirFilePath("data/confignode/system", CONFIG_NODE_SYSTEM_PROPERTIES_FILE);
+ return workDirFilePath("data/confignode/system", ConfigNodeConstant.SYSTEM_FILE_NAME);
}
@Override
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/DataNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/DataNodeWrapper.java
index 1135f5cd055c6..647bd9b9fa003 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/DataNodeWrapper.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/DataNodeWrapper.java
@@ -20,6 +20,7 @@
package org.apache.iotdb.it.env.cluster.node;
import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.db.conf.IoTDBStartCheck;
import org.apache.iotdb.it.env.cluster.EnvUtils;
import org.apache.iotdb.it.env.cluster.config.MppBaseConfig;
import org.apache.iotdb.it.env.cluster.config.MppJVMConfig;
@@ -61,7 +62,6 @@
import static org.apache.iotdb.it.env.cluster.ClusterConstant.REST_SERVICE_PORT;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.SCHEMA_REGION_CONSENSUS_PROTOCOL_CLASS;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.SCHEMA_REPLICATION_FACTOR;
-import static org.apache.iotdb.it.env.cluster.ClusterConstant.SYSTEM_PROPERTIES_FILE;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.TARGET;
import static org.apache.iotdb.it.env.cluster.ClusterConstant.USER_DIR;
@@ -139,7 +139,7 @@ protected String getDefaultCommonConfigPath() {
@Override
public String getSystemPropertiesPath() {
- return workDirFilePath("data/datanode/system/schema", SYSTEM_PROPERTIES_FILE);
+ return workDirFilePath("data/datanode/system/schema", IoTDBStartCheck.PROPERTIES_FILE_NAME);
}
@Override
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java
index 0ac82fc871373..36675e646865d 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/env/remote/config/RemoteCommonConfig.java
@@ -313,4 +313,21 @@ public CommonConfig setTagAttributeTotalSize(int tagAttributeTotalSize) {
public CommonConfig setCnConnectionTimeoutMs(int connectionTimeoutMs) {
return this;
}
+
+ @Override
+ public CommonConfig setPipeHeartbeatIntervalSecondsForCollectingPipeMeta(
+ int pipeHeartbeatIntervalSecondsForCollectingPipeMeta) {
+ return this;
+ }
+
+ @Override
+ public CommonConfig setPipeMetaSyncerInitialSyncDelayMinutes(
+ long pipeMetaSyncerInitialSyncDelayMinutes) {
+ return this;
+ }
+
+ @Override
+ public CommonConfig setPipeMetaSyncerSyncIntervalMinutes(long pipeMetaSyncerSyncIntervalMinutes) {
+ return this;
+ }
}
diff --git a/integration-test/src/main/java/org/apache/iotdb/it/utils/TsFileGenerator.java b/integration-test/src/main/java/org/apache/iotdb/it/utils/TsFileGenerator.java
index bf1ec811f8589..e907cf17455a9 100644
--- a/integration-test/src/main/java/org/apache/iotdb/it/utils/TsFileGenerator.java
+++ b/integration-test/src/main/java/org/apache/iotdb/it/utils/TsFileGenerator.java
@@ -37,6 +37,7 @@
import java.io.File;
import java.io.IOException;
+import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -52,7 +53,7 @@ public class TsFileGenerator implements AutoCloseable {
private final Map> device2MeasurementSchema;
private Random random;
- public TsFileGenerator(File tsFile) throws IOException {
+ public TsFileGenerator(final File tsFile) throws IOException {
this.tsFile = tsFile;
this.writer = new TsFileWriter(tsFile);
this.device2TimeSet = new HashMap<>();
@@ -64,11 +65,12 @@ public void resetRandom() {
random = new Random();
}
- public void resetRandom(long seed) {
+ public void resetRandom(final long seed) {
random = new Random(seed);
}
- public void registerTimeseries(String path, List measurementSchemaList) {
+ public void registerTimeseries(
+ final String path, final List measurementSchemaList) {
if (device2MeasurementSchema.containsKey(path)) {
LOGGER.error("Register same device {}.", path);
return;
@@ -78,7 +80,8 @@ public void registerTimeseries(String path, List measurement
device2MeasurementSchema.put(path, measurementSchemaList);
}
- public void registerAlignedTimeseries(String path, List measurementSchemaList)
+ public void registerAlignedTimeseries(
+ final String path, final List measurementSchemaList)
throws WriteProcessException {
if (device2MeasurementSchema.containsKey(path)) {
LOGGER.error("Register same device {}.", path);
@@ -89,14 +92,15 @@ public void registerAlignedTimeseries(String path, List meas
device2MeasurementSchema.put(path, measurementSchemaList);
}
- public void generateData(String device, int number, long timeGap, boolean isAligned)
+ public void generateData(
+ final String device, final int number, final long timeGap, final boolean isAligned)
throws IOException, WriteProcessException {
- List schemas = device2MeasurementSchema.get(device);
- TreeSet timeSet = device2TimeSet.get(device);
- Tablet tablet = new Tablet(device, schemas);
- long[] timestamps = tablet.timestamps;
- Object[] values = tablet.values;
- long sensorNum = schemas.size();
+ final List schemas = device2MeasurementSchema.get(device);
+ final TreeSet timeSet = device2TimeSet.get(device);
+ final Tablet tablet = new Tablet(device, schemas);
+ final long[] timestamps = tablet.timestamps;
+ final Object[] values = tablet.values;
+ final long sensorNum = schemas.size();
long startTime = timeSet.isEmpty() ? 0L : timeSet.last();
for (long r = 0; r < number; r++) {
@@ -131,18 +135,22 @@ public void generateData(String device, int number, long timeGap, boolean isAlig
}
public void generateData(
- String device, int number, long timeGap, boolean isAligned, long startTimestamp)
+ final String device,
+ final int number,
+ final long timeGap,
+ final boolean isAligned,
+ final long startTimestamp)
throws IOException, WriteProcessException {
- List schemas = device2MeasurementSchema.get(device);
- TreeSet timeSet = device2TimeSet.get(device);
- Tablet tablet = new Tablet(device, schemas);
- long[] timestamps = tablet.timestamps;
- Object[] values = tablet.values;
- long sensorNum = schemas.size();
+ final List schemas = device2MeasurementSchema.get(device);
+ final TreeSet timeSet = device2TimeSet.get(device);
+ final Tablet tablet = new Tablet(device, schemas);
+ final long[] timestamps = tablet.timestamps;
+ final Object[] values = tablet.values;
+ final long sensorNum = schemas.size();
long startTime = startTimestamp;
for (long r = 0; r < number; r++) {
- int row = tablet.rowSize++;
+ final int row = tablet.rowSize++;
startTime += timeGap;
timestamps[row] = startTime;
timeSet.add(startTime);
@@ -172,12 +180,16 @@ public void generateData(
LOGGER.info("Write {} points into device {}", number, device);
}
- private void generateDataPoint(Object obj, int row, IMeasurementSchema schema) {
+ private void generateDataPoint(final Object obj, final int row, final IMeasurementSchema schema) {
switch (schema.getType()) {
case INT32:
generateINT32(obj, row);
break;
+ case DATE:
+ generateDATE(obj, row);
+ break;
case INT64:
+ case TIMESTAMP:
generateINT64(obj, row);
break;
case FLOAT:
@@ -190,6 +202,8 @@ private void generateDataPoint(Object obj, int row, IMeasurementSchema schema) {
generateBOOLEAN(obj, row);
break;
case TEXT:
+ case BLOB:
+ case STRING:
generateTEXT(obj, row);
break;
default:
@@ -197,53 +211,60 @@ private void generateDataPoint(Object obj, int row, IMeasurementSchema schema) {
}
}
- private void generateINT32(Object obj, int row) {
- int[] ints = (int[]) obj;
+ private void generateINT32(final Object obj, final int row) {
+ final int[] ints = (int[]) obj;
ints[row] = random.nextInt();
}
- private void generateINT64(Object obj, int row) {
- long[] longs = (long[]) obj;
+ private void generateDATE(final Object obj, final int row) {
+ final LocalDate[] dates = (LocalDate[]) obj;
+ dates[row] =
+ LocalDate.of(1000 + random.nextInt(9000), 1 + random.nextInt(12), 1 + random.nextInt(28));
+ }
+
+ private void generateINT64(final Object obj, final int row) {
+ final long[] longs = (long[]) obj;
longs[row] = random.nextLong();
}
- private void generateFLOAT(Object obj, int row) {
- float[] floats = (float[]) obj;
+ private void generateFLOAT(final Object obj, final int row) {
+ final float[] floats = (float[]) obj;
floats[row] = random.nextFloat();
}
- private void generateDOUBLE(Object obj, int row) {
- double[] doubles = (double[]) obj;
+ private void generateDOUBLE(final Object obj, final int row) {
+ final double[] doubles = (double[]) obj;
doubles[row] = random.nextDouble();
}
- private void generateBOOLEAN(Object obj, int row) {
- boolean[] booleans = (boolean[]) obj;
+ private void generateBOOLEAN(final Object obj, final int row) {
+ final boolean[] booleans = (boolean[]) obj;
booleans[row] = random.nextBoolean();
}
- private void generateTEXT(Object obj, int row) {
- Binary[] binaries = (Binary[]) obj;
+ private void generateTEXT(final Object obj, final int row) {
+ final Binary[] binaries = (Binary[]) obj;
binaries[row] =
new Binary(String.format("test point %d", random.nextInt()), TSFileConfig.STRING_CHARSET);
}
- public void generateDeletion(String device, int number) throws IOException, IllegalPathException {
- try (ModificationFile modificationFile =
+ public void generateDeletion(final String device, final int number)
+ throws IOException, IllegalPathException {
+ try (final ModificationFile modificationFile =
new ModificationFile(tsFile.getAbsolutePath() + ModificationFile.FILE_SUFFIX)) {
writer.flushAllChunkGroups();
- TreeSet timeSet = device2TimeSet.get(device);
+ final TreeSet timeSet = device2TimeSet.get(device);
if (timeSet.isEmpty()) {
return;
}
- long fileOffset = tsFile.length();
- long maxTime = timeSet.last() - 1;
+ final long fileOffset = tsFile.length();
+ final long maxTime = timeSet.last() - 1;
for (int i = 0; i < number; i++) {
- int endTime = random.nextInt((int) (maxTime)) + 1;
- int startTime = random.nextInt(endTime);
- for (IMeasurementSchema measurementSchema : device2MeasurementSchema.get(device)) {
- Deletion deletion =
+ final int endTime = random.nextInt((int) (maxTime)) + 1;
+ final int startTime = random.nextInt(endTime);
+ for (final IMeasurementSchema measurementSchema : device2MeasurementSchema.get(device)) {
+ final Deletion deletion =
new Deletion(
new PartialPath(
device
diff --git a/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseNodeWrapper.java
index cd0eb86bde18c..b0ce0d4a22147 100644
--- a/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseNodeWrapper.java
+++ b/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseNodeWrapper.java
@@ -45,5 +45,19 @@ public interface BaseNodeWrapper {
String getIpAndPortString();
- void dumpJVMSnapshot(String testCaseName);
+ /**
+ * Perform jstack on the process corresponding to the wrapper, and use logger to output the
+ * results.
+ */
+ void executeJstack();
+
+ /**
+ * Perform jstack on the process corresponding to the wrapper, and output the results to a file in
+ * the log directory.
+ *
+ * @param testCaseName the name of test case
+ */
+ void executeJstack(final String testCaseName);
+
+ long getPid();
}
diff --git a/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java b/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java
index af47c8254e532..c06c45ddcd42d 100644
--- a/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java
+++ b/integration-test/src/main/java/org/apache/iotdb/itbase/env/CommonConfig.java
@@ -139,4 +139,11 @@ CommonConfig setEnableAutoLeaderBalanceForIoTConsensus(
CommonConfig setTagAttributeTotalSize(int tagAttributeTotalSize);
CommonConfig setCnConnectionTimeoutMs(int connectionTimeoutMs);
+
+ CommonConfig setPipeHeartbeatIntervalSecondsForCollectingPipeMeta(
+ int pipeHeartbeatIntervalSecondsForCollectingPipeMeta);
+
+ CommonConfig setPipeMetaSyncerInitialSyncDelayMinutes(long pipeMetaSyncerInitialSyncDelayMinutes);
+
+ CommonConfig setPipeMetaSyncerSyncIntervalMinutes(long pipeMetaSyncerSyncIntervalMinutes);
}
diff --git a/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/RequestDelegate.java b/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/RequestDelegate.java
index bc32c31e7932e..47f31004e6f28 100644
--- a/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/RequestDelegate.java
+++ b/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/RequestDelegate.java
@@ -76,14 +76,10 @@ public final void addRequest(Callable request) {
*/
public final T requestAllAndCompare() throws SQLException {
List results = requestAll();
- T data = results.get(0);
- for (int i = 1; i < results.size(); i++) {
- T anotherData = results.get(i);
- if (!compare(data, anotherData)) {
- throw new InconsistentDataException(results, endpoints);
- }
+ if (!results.stream().allMatch(result -> compare(results.get(0), result))) {
+ throw new InconsistentDataException(results, endpoints);
}
- return data;
+ return results.get(0);
}
private boolean compare(T data, T anotherData) {
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IOTDBLoadTsFileIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
similarity index 65%
rename from integration-test/src/test/java/org/apache/iotdb/db/it/IOTDBLoadTsFileIT.java
rename to integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
index 58bfb125147e4..115ba4bfc9035 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/IOTDBLoadTsFileIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
@@ -65,8 +65,8 @@
@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
-public class IOTDBLoadTsFileIT {
- private static final Logger LOGGER = LoggerFactory.getLogger(IOTDBLoadTsFileIT.class);
+public class IoTDBLoadTsFileIT {
+ private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBLoadTsFileIT.class);
private static final long PARTITION_INTERVAL = 10 * 1000L;
private static final int connectionTimeoutInMS = (int) TimeUnit.SECONDS.toMillis(300);
private static final long loadTsFileAnalyzeSchemaMemorySizeInBytes = 10 * 1024L;
@@ -96,8 +96,8 @@ public void tearDown() throws Exception {
}
private void registerSchema() throws SQLException {
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute("CREATE DATABASE " + SchemaConfig.STORAGE_GROUP_0);
statement.execute("CREATE DATABASE " + SchemaConfig.STORAGE_GROUP_1);
@@ -114,19 +114,24 @@ private void registerSchema() throws SQLException {
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13)));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17)));
statement.execute(convert2SQL(SchemaConfig.DEVICE_2, SchemaConfig.MEASUREMENT_20));
statement.execute(convert2SQL(SchemaConfig.DEVICE_3, SchemaConfig.MEASUREMENT_30));
statement.execute(
- convert2AlignedSQL(SchemaConfig.DEVICE_4, Arrays.asList(SchemaConfig.MEASUREMENT_40)));
+ convert2AlignedSQL(
+ SchemaConfig.DEVICE_4, Collections.singletonList(SchemaConfig.MEASUREMENT_40)));
}
}
- private String convert2SQL(String device, MeasurementSchema schema) {
- String sql =
+ private String convert2SQL(final String device, final MeasurementSchema schema) {
+ final String sql =
String.format(
"create timeseries %s %s",
new Path(device, schema.getMeasurementId(), true).getFullPath(),
@@ -135,10 +140,10 @@ private String convert2SQL(String device, MeasurementSchema schema) {
return sql;
}
- private String convert2AlignedSQL(String device, List schemas) {
+ private String convert2AlignedSQL(final String device, final List schemas) {
String sql = String.format("create aligned timeseries %s(", device);
for (int i = 0; i < schemas.size(); i++) {
- IMeasurementSchema schema = schemas.get(i);
+ final IMeasurementSchema schema = schemas.get(i);
sql += (String.format("%s %s", schema.getMeasurementId(), schema.getType().name()));
sql += (i == schemas.size() - 1 ? ")" : ",");
}
@@ -147,17 +152,17 @@ private String convert2AlignedSQL(String device, List schema
}
private void deleteSG() throws SQLException {
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(String.format("delete database %s", SchemaConfig.STORAGE_GROUP_0));
statement.execute(String.format("delete database %s", SchemaConfig.STORAGE_GROUP_1));
- } catch (IoTDBSQLException ignored) {
+ } catch (final IoTDBSQLException ignored) {
}
}
private boolean deleteDir() {
- for (File file : tmpDir.listFiles()) {
+ for (final File file : tmpDir.listFiles()) {
if (!file.delete()) {
return false;
}
@@ -169,49 +174,59 @@ private boolean deleteDir() {
public void testLoad() throws Exception {
registerSchema();
- long writtenPoint1 = 0;
+ final long writtenPoint1;
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
generator.generateData(SchemaConfig.DEVICE_0, 100000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_1, 100000, PARTITION_INTERVAL / 10_000, true);
writtenPoint1 = generator.getTotalNumber();
}
- long writtenPoint2 = 0;
+ final long writtenPoint2;
// device 2, device 3, device4, sg 1
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "2-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "2-0-0-0.tsfile"))) {
generator.registerTimeseries(
- SchemaConfig.DEVICE_2, Arrays.asList(SchemaConfig.MEASUREMENT_20));
+ SchemaConfig.DEVICE_2, Collections.singletonList(SchemaConfig.MEASUREMENT_20));
generator.registerTimeseries(
- SchemaConfig.DEVICE_3, Arrays.asList(SchemaConfig.MEASUREMENT_30));
+ SchemaConfig.DEVICE_3, Collections.singletonList(SchemaConfig.MEASUREMENT_30));
generator.registerAlignedTimeseries(
- SchemaConfig.DEVICE_4, Arrays.asList(SchemaConfig.MEASUREMENT_40));
+ SchemaConfig.DEVICE_4, Collections.singletonList(SchemaConfig.MEASUREMENT_40));
generator.generateData(SchemaConfig.DEVICE_2, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_3, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_4, 10000, PARTITION_INTERVAL / 10_000, true);
writtenPoint2 = generator.getTotalNumber();
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(String.format("load \"%s\" sglevel=2", tmpDir.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery("select count(*) from root.** group by level=1,2")) {
if (resultSet.next()) {
long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
@@ -224,9 +239,9 @@ public void testLoad() throws Exception {
}
}
- // try delete after loading. Expect no deadlock
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ // Try to delete after loading. Expect no deadlock
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(
String.format(
"delete timeseries %s.%s",
@@ -236,29 +251,38 @@ public void testLoad() throws Exception {
@Test
public void testLoadWithExtendTemplate() throws Exception {
- long writtenPoint1 = 0;
+ final long writtenPoint1;
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
generator.generateData(SchemaConfig.DEVICE_0, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_1, 10000, PARTITION_INTERVAL / 10_000, true);
writtenPoint1 = generator.getTotalNumber();
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute("create database root.sg.test_0");
statement.execute(
@@ -267,17 +291,17 @@ public void testLoadWithExtendTemplate() throws Exception {
statement.execute(String.format("load \"%s\" sglevel=2", tmpDir.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery("select count(*) from root.** group by level=1,2")) {
if (resultSet.next()) {
- long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
+ final long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
Assert.assertEquals(writtenPoint1, sg1Count);
} else {
Assert.fail("This ResultSet is empty.");
}
}
- Set nodes =
+ final Set nodes =
new HashSet<>(
Arrays.asList(
"lat",
@@ -285,14 +309,18 @@ public void testLoadWithExtendTemplate() throws Exception {
SchemaConfig.MEASUREMENT_00.getMeasurementId(),
SchemaConfig.MEASUREMENT_01.getMeasurementId(),
SchemaConfig.MEASUREMENT_02.getMeasurementId(),
- SchemaConfig.MEASUREMENT_03.getMeasurementId()));
- try (ResultSet resultSet = statement.executeQuery("show nodes in schema template t1")) {
+ SchemaConfig.MEASUREMENT_03.getMeasurementId(),
+ SchemaConfig.MEASUREMENT_04.getMeasurementId(),
+ SchemaConfig.MEASUREMENT_05.getMeasurementId(),
+ SchemaConfig.MEASUREMENT_06.getMeasurementId(),
+ SchemaConfig.MEASUREMENT_07.getMeasurementId()));
+ try (final ResultSet resultSet = statement.executeQuery("show nodes in schema template t1")) {
while (resultSet.next()) {
String device = resultSet.getString(ColumnHeaderConstant.CHILD_NODES);
Assert.assertTrue(nodes.remove(device));
}
Assert.assertTrue(nodes.isEmpty());
- } catch (Exception e) {
+ } catch (final Exception e) {
e.printStackTrace();
Assert.fail("Parse result set error.");
}
@@ -301,67 +329,77 @@ public void testLoadWithExtendTemplate() throws Exception {
@Test
public void testLoadWithAutoRegister() throws Exception {
- long writtenPoint1 = 0;
+ final long writtenPoint1;
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
generator.generateData(SchemaConfig.DEVICE_0, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_1, 10000, PARTITION_INTERVAL / 10_000, true);
writtenPoint1 = generator.getTotalNumber();
}
- long writtenPoint2 = 0;
+ final long writtenPoint2;
// device 2, device 3, device4, sg 1
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "2-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "2-0-0-0.tsfile"))) {
generator.registerTimeseries(
- SchemaConfig.DEVICE_2, Arrays.asList(SchemaConfig.MEASUREMENT_20));
+ SchemaConfig.DEVICE_2, Collections.singletonList(SchemaConfig.MEASUREMENT_20));
generator.registerTimeseries(
- SchemaConfig.DEVICE_3, Arrays.asList(SchemaConfig.MEASUREMENT_30));
+ SchemaConfig.DEVICE_3, Collections.singletonList(SchemaConfig.MEASUREMENT_30));
generator.registerAlignedTimeseries(
- SchemaConfig.DEVICE_4, Arrays.asList(SchemaConfig.MEASUREMENT_40));
+ SchemaConfig.DEVICE_4, Collections.singletonList(SchemaConfig.MEASUREMENT_40));
generator.generateData(SchemaConfig.DEVICE_2, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_3, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_4, 10000, PARTITION_INTERVAL / 10_000, true);
writtenPoint2 = generator.getTotalNumber();
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(String.format("load \"%s\" sglevel=2", tmpDir.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery("select count(*) from root.** group by level=1,2")) {
if (resultSet.next()) {
- long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
+ final long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
Assert.assertEquals(writtenPoint1, sg1Count);
- long sg2Count = resultSet.getLong("count(root.sg.test_1.*.*)");
+ final long sg2Count = resultSet.getLong("count(root.sg.test_1.*.*)");
Assert.assertEquals(writtenPoint2, sg2Count);
} else {
Assert.fail("This ResultSet is empty.");
}
}
- Map isAligned = new HashMap<>();
+ final Map isAligned = new HashMap<>();
isAligned.put(SchemaConfig.DEVICE_0, "false");
isAligned.put(SchemaConfig.DEVICE_1, "true");
isAligned.put(SchemaConfig.DEVICE_2, "false");
isAligned.put(SchemaConfig.DEVICE_3, "false");
isAligned.put(SchemaConfig.DEVICE_4, "true");
- try (ResultSet resultSet = statement.executeQuery("show devices")) {
+ try (final ResultSet resultSet = statement.executeQuery("show devices")) {
int size = 0;
while (resultSet.next()) {
size += 1;
@@ -370,7 +408,7 @@ public void testLoadWithAutoRegister() throws Exception {
isAligned.get(device), resultSet.getString(ColumnHeaderConstant.IS_ALIGNED));
}
Assert.assertEquals(isAligned.size(), size);
- } catch (Exception e) {
+ } catch (final Exception e) {
e.printStackTrace();
Assert.fail("Parse result set error.");
}
@@ -382,33 +420,43 @@ public void testAuth() throws Exception {
createUser("test", "test123");
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "test1-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "test1-0-0-0.tsfile"))) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
generator.generateData(SchemaConfig.DEVICE_0, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_1, 10000, PARTITION_INTERVAL / 10_000, true);
}
// device 2, device 3, device4, sg 1
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "test2-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "test2-0-0-0.tsfile"))) {
generator.registerTimeseries(
- SchemaConfig.DEVICE_2, Arrays.asList(SchemaConfig.MEASUREMENT_20));
+ SchemaConfig.DEVICE_2, Collections.singletonList(SchemaConfig.MEASUREMENT_20));
generator.registerTimeseries(
- SchemaConfig.DEVICE_3, Arrays.asList(SchemaConfig.MEASUREMENT_30));
+ SchemaConfig.DEVICE_3, Collections.singletonList(SchemaConfig.MEASUREMENT_30));
generator.registerAlignedTimeseries(
- SchemaConfig.DEVICE_4, Arrays.asList(SchemaConfig.MEASUREMENT_40));
+ SchemaConfig.DEVICE_4, Collections.singletonList(SchemaConfig.MEASUREMENT_40));
generator.generateData(SchemaConfig.DEVICE_2, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_3, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_4, 10000, PARTITION_INTERVAL / 10_000, true);
@@ -444,33 +492,41 @@ public void testAuth() throws Exception {
@Test
public void testLoadWithOnSuccess() throws Exception {
- File file1 = new File(tmpDir, "1-0-0-0.tsfile");
- File file2 = new File(tmpDir, "2-0-0-0.tsfile");
+ final File file1 = new File(tmpDir, "1-0-0-0.tsfile");
+ final File file2 = new File(tmpDir, "2-0-0-0.tsfile");
long writtenPoint1 = 0;
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(file1)) {
+ try (final TsFileGenerator generator = new TsFileGenerator(file1)) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
generator.generateData(SchemaConfig.DEVICE_0, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_1, 10000, PARTITION_INTERVAL / 10_000, true);
writtenPoint1 = generator.getTotalNumber();
}
- long writtenPoint2 = 0;
+ final long writtenPoint2;
// device 2, device 3, device4, sg 1
- try (TsFileGenerator generator = new TsFileGenerator(file2)) {
+ try (final TsFileGenerator generator = new TsFileGenerator(file2)) {
generator.registerTimeseries(
SchemaConfig.DEVICE_2, Arrays.asList(SchemaConfig.MEASUREMENT_20));
generator.registerTimeseries(
@@ -483,16 +539,16 @@ public void testLoadWithOnSuccess() throws Exception {
writtenPoint2 = generator.getTotalNumber();
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(
String.format("load \"%s\" sglevel=2 onSuccess=none", file1.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery("select count(*) from root.** group by level=1,2")) {
if (resultSet.next()) {
- long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
+ final long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
Assert.assertEquals(writtenPoint1, sg1Count);
} else {
Assert.fail("This ResultSet is empty.");
@@ -501,13 +557,13 @@ public void testLoadWithOnSuccess() throws Exception {
Assert.assertTrue(file1.exists());
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(
String.format("load \"%s\" sglevel=2 onSuccess=delete", file2.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery("select count(*) from root.** group by level=1,2")) {
if (resultSet.next()) {
long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
@@ -526,19 +582,19 @@ public void testLoadWithOnSuccess() throws Exception {
public void testLoadWithLastCache() throws Exception {
registerSchema();
- String device = SchemaConfig.DEVICE_0;
- String measurement = SchemaConfig.MEASUREMENT_00.getMeasurementId();
+ final String device = SchemaConfig.DEVICE_0;
+ final String measurement = SchemaConfig.MEASUREMENT_00.getMeasurementId();
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(
String.format("insert into %s(timestamp, %s) values(100, 100)", device, measurement));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery(String.format("select last %s from %s", measurement, device))) {
if (resultSet.next()) {
- String lastValue = resultSet.getString(ColumnHeaderConstant.VALUE);
+ final String lastValue = resultSet.getString(ColumnHeaderConstant.VALUE);
Assert.assertEquals("100", lastValue);
} else {
Assert.fail("This ResultSet is empty.");
@@ -546,50 +602,58 @@ public void testLoadWithLastCache() throws Exception {
}
}
- File file1 = new File(tmpDir, "1-0-0-0.tsfile");
- File file2 = new File(tmpDir, "2-0-0-0.tsfile");
+ final File file1 = new File(tmpDir, "1-0-0-0.tsfile");
+ final File file2 = new File(tmpDir, "2-0-0-0.tsfile");
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(file1)) {
+ try (final TsFileGenerator generator = new TsFileGenerator(file1)) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
generator.generateData(SchemaConfig.DEVICE_0, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_1, 10000, PARTITION_INTERVAL / 10_000, true);
}
// device 2, device 3, device4, sg 1
- try (TsFileGenerator generator = new TsFileGenerator(file2)) {
+ try (final TsFileGenerator generator = new TsFileGenerator(file2)) {
generator.registerTimeseries(
- SchemaConfig.DEVICE_2, Arrays.asList(SchemaConfig.MEASUREMENT_20));
+ SchemaConfig.DEVICE_2, Collections.singletonList(SchemaConfig.MEASUREMENT_20));
generator.registerTimeseries(
- SchemaConfig.DEVICE_3, Arrays.asList(SchemaConfig.MEASUREMENT_30));
+ SchemaConfig.DEVICE_3, Collections.singletonList(SchemaConfig.MEASUREMENT_30));
generator.registerAlignedTimeseries(
- SchemaConfig.DEVICE_4, Arrays.asList(SchemaConfig.MEASUREMENT_40));
+ SchemaConfig.DEVICE_4, Collections.singletonList(SchemaConfig.MEASUREMENT_40));
generator.generateData(SchemaConfig.DEVICE_2, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_3, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_4, 10000, PARTITION_INTERVAL / 10_000, true);
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(String.format("load \"%s\" sglevel=2", tmpDir.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery(String.format("select last %s from %s", measurement, device))) {
if (resultSet.next()) {
- String lastTime = resultSet.getString(ColumnHeaderConstant.TIME);
+ final String lastTime = resultSet.getString(ColumnHeaderConstant.TIME);
Assert.assertEquals(String.valueOf(PARTITION_INTERVAL), lastTime);
} else {
Assert.fail("This ResultSet is empty.");
@@ -600,56 +664,64 @@ public void testLoadWithLastCache() throws Exception {
@Test
public void testLoadWithOnNonStandardTsFileName() throws Exception {
- File file1 = new File(tmpDir, "1-0-0-0.tsfile");
- File file2 = new File(tmpDir, "a-1.tsfile");
- long writtenPoint1 = 0;
+ final File file1 = new File(tmpDir, "1-0-0-0.tsfile");
+ final File file2 = new File(tmpDir, "a-1.tsfile");
+ final long writtenPoint1;
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(file1)) {
+ try (final TsFileGenerator generator = new TsFileGenerator(file1)) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
generator.generateData(SchemaConfig.DEVICE_0, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_1, 10000, PARTITION_INTERVAL / 10_000, true);
writtenPoint1 = generator.getTotalNumber();
}
- long writtenPoint2 = 0;
+ final long writtenPoint2;
// device 2, device 3, device4, sg 1
- try (TsFileGenerator generator = new TsFileGenerator(file2)) {
+ try (final TsFileGenerator generator = new TsFileGenerator(file2)) {
generator.registerTimeseries(
- SchemaConfig.DEVICE_2, Arrays.asList(SchemaConfig.MEASUREMENT_20));
+ SchemaConfig.DEVICE_2, Collections.singletonList(SchemaConfig.MEASUREMENT_20));
generator.registerTimeseries(
- SchemaConfig.DEVICE_3, Arrays.asList(SchemaConfig.MEASUREMENT_30));
+ SchemaConfig.DEVICE_3, Collections.singletonList(SchemaConfig.MEASUREMENT_30));
generator.registerAlignedTimeseries(
- SchemaConfig.DEVICE_4, Arrays.asList(SchemaConfig.MEASUREMENT_40));
+ SchemaConfig.DEVICE_4, Collections.singletonList(SchemaConfig.MEASUREMENT_40));
generator.generateData(SchemaConfig.DEVICE_2, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_3, 10000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_4, 10000, PARTITION_INTERVAL / 10_000, true);
writtenPoint2 = generator.getTotalNumber();
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(String.format("load \"%s\" sglevel=2", tmpDir.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery("select count(*) from root.** group by level=1,2")) {
if (resultSet.next()) {
- long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
+ final long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
Assert.assertEquals(writtenPoint1, sg1Count);
- long sg2Count = resultSet.getLong("count(root.sg.test_1.*.*)");
+ final long sg2Count = resultSet.getLong("count(root.sg.test_1.*.*)");
Assert.assertEquals(writtenPoint2, sg2Count);
} else {
Assert.fail("This ResultSet is empty.");
@@ -660,23 +732,32 @@ public void testLoadWithOnNonStandardTsFileName() throws Exception {
@Test
public void testLoadWithMods() throws Exception {
- long writtenPoint1 = 0;
+ final long writtenPoint1;
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
generator.generateData(SchemaConfig.DEVICE_0, 100000, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_1, 100000, PARTITION_INTERVAL / 10_000, true);
generator.generateDeletion(SchemaConfig.DEVICE_0, 10);
@@ -684,16 +765,17 @@ public void testLoadWithMods() throws Exception {
writtenPoint1 = generator.getTotalNumber();
}
- long writtenPoint2 = 0;
+ final long writtenPoint2;
// device 2, device 3, device4, sg 1
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "2-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "2-0-0-0.tsfile"))) {
generator.resetRandom(1000);
generator.registerTimeseries(
- SchemaConfig.DEVICE_2, Arrays.asList(SchemaConfig.MEASUREMENT_20));
+ SchemaConfig.DEVICE_2, Collections.singletonList(SchemaConfig.MEASUREMENT_20));
generator.registerTimeseries(
- SchemaConfig.DEVICE_3, Arrays.asList(SchemaConfig.MEASUREMENT_30));
+ SchemaConfig.DEVICE_3, Collections.singletonList(SchemaConfig.MEASUREMENT_30));
generator.registerAlignedTimeseries(
- SchemaConfig.DEVICE_4, Arrays.asList(SchemaConfig.MEASUREMENT_40));
+ SchemaConfig.DEVICE_4, Collections.singletonList(SchemaConfig.MEASUREMENT_40));
generator.generateData(SchemaConfig.DEVICE_2, 100, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_3, 100, PARTITION_INTERVAL / 10_000, false);
generator.generateData(SchemaConfig.DEVICE_4, 100, PARTITION_INTERVAL / 10_000, true);
@@ -706,17 +788,17 @@ public void testLoadWithMods() throws Exception {
writtenPoint2 = generator.getTotalNumber();
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(String.format("load \"%s\" sglevel=2", tmpDir.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery("select count(*) from root.** group by level=1,2")) {
if (resultSet.next()) {
- long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
+ final long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
Assert.assertEquals(writtenPoint1, sg1Count);
- long sg2Count = resultSet.getLong("count(root.sg.test_1.*.*)");
+ final long sg2Count = resultSet.getLong("count(root.sg.test_1.*.*)");
Assert.assertEquals(writtenPoint2, sg2Count);
} else {
Assert.fail("This ResultSet is empty.");
@@ -727,14 +809,14 @@ public void testLoadWithMods() throws Exception {
@Test
public void testLoadWithEmptyTsFile() throws Exception {
- try (TsFileGenerator ignored = new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {}
+ try (final TsFileGenerator ignored = new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {}
- try (Connection connection = EnvFactory.getEnv().getConnection();
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
Statement statement = connection.createStatement()) {
statement.execute(String.format("load \"%s\"", tmpDir.getAbsolutePath()));
- try (ResultSet resultSet = statement.executeQuery("show timeseries")) {
+ try (final ResultSet resultSet = statement.executeQuery("show timeseries")) {
Assert.assertFalse(resultSet.next());
}
}
@@ -742,21 +824,30 @@ public void testLoadWithEmptyTsFile() throws Exception {
@Test
public void testLoadTsFileWithWrongTimestampPrecision() throws Exception {
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0,
Arrays.asList(
SchemaConfig.MEASUREMENT_00,
SchemaConfig.MEASUREMENT_01,
SchemaConfig.MEASUREMENT_02,
- SchemaConfig.MEASUREMENT_03));
+ SchemaConfig.MEASUREMENT_03,
+ SchemaConfig.MEASUREMENT_04,
+ SchemaConfig.MEASUREMENT_05,
+ SchemaConfig.MEASUREMENT_06,
+ SchemaConfig.MEASUREMENT_07));
generator.registerAlignedTimeseries(
SchemaConfig.DEVICE_1,
Arrays.asList(
SchemaConfig.MEASUREMENT_10,
SchemaConfig.MEASUREMENT_11,
SchemaConfig.MEASUREMENT_12,
- SchemaConfig.MEASUREMENT_13));
+ SchemaConfig.MEASUREMENT_13,
+ SchemaConfig.MEASUREMENT_14,
+ SchemaConfig.MEASUREMENT_15,
+ SchemaConfig.MEASUREMENT_16,
+ SchemaConfig.MEASUREMENT_17));
// generate ns timestamp
generator.generateData(
SchemaConfig.DEVICE_0, 100000, PARTITION_INTERVAL / 10_000, false, 1694689856546000000L);
@@ -764,11 +855,11 @@ public void testLoadTsFileWithWrongTimestampPrecision() throws Exception {
SchemaConfig.DEVICE_1, 100000, PARTITION_INTERVAL / 10_000, true, 1694689856546000000L);
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(String.format("load \"%s\"", tmpDir.getAbsolutePath()));
- } catch (IoTDBSQLException e) {
+ } catch (final IoTDBSQLException e) {
Assert.assertTrue(e.getMessage().contains("Current system timestamp precision is ms"));
}
}
@@ -777,24 +868,25 @@ public void testLoadTsFileWithWrongTimestampPrecision() throws Exception {
public void testLoadLocally() throws Exception {
registerSchema();
- long writtenPoint1 = 0;
+ final long writtenPoint1;
// device 0, device 1, sg 0
- try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
+ try (final TsFileGenerator generator =
+ new TsFileGenerator(new File(tmpDir, "1-0-0-0.tsfile"))) {
generator.registerTimeseries(
SchemaConfig.DEVICE_0, Collections.singletonList(SchemaConfig.MEASUREMENT_00));
generator.generateData(SchemaConfig.DEVICE_0, 1, PARTITION_INTERVAL / 10_000, false);
writtenPoint1 = generator.getTotalNumber();
}
- try (Connection connection = EnvFactory.getEnv().getConnection();
- Statement statement = connection.createStatement()) {
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
statement.execute(String.format("load \"%s\" sglevel=2", tmpDir.getAbsolutePath()));
- try (ResultSet resultSet =
+ try (final ResultSet resultSet =
statement.executeQuery("select count(*) from root.** group by level=1,2")) {
if (resultSet.next()) {
- long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
+ final long sg1Count = resultSet.getLong("count(root.sg.test_0.*.*)");
Assert.assertEquals(writtenPoint1, sg1Count);
} else {
Assert.fail("This ResultSet is empty.");
@@ -817,6 +909,14 @@ private static class SchemaConfig {
new MeasurementSchema("sensor_02", TSDataType.DOUBLE, TSEncoding.GORILLA);
private static final MeasurementSchema MEASUREMENT_03 =
new MeasurementSchema("sensor_03", TSDataType.TEXT, TSEncoding.PLAIN);
+ private static final MeasurementSchema MEASUREMENT_04 =
+ new MeasurementSchema("sensor_04", TSDataType.TIMESTAMP, TSEncoding.RLE);
+ private static final MeasurementSchema MEASUREMENT_05 =
+ new MeasurementSchema("sensor_05", TSDataType.DATE, TSEncoding.RLE);
+ private static final MeasurementSchema MEASUREMENT_06 =
+ new MeasurementSchema("sensor_06", TSDataType.BLOB, TSEncoding.PLAIN);
+ private static final MeasurementSchema MEASUREMENT_07 =
+ new MeasurementSchema("sensor_07", TSDataType.STRING, TSEncoding.PLAIN);
// device 1, aligned, sg 0
private static final String DEVICE_1 = "root.sg.test_0.a_1";
@@ -828,6 +928,14 @@ private static class SchemaConfig {
new MeasurementSchema("sensor_12", TSDataType.DOUBLE, TSEncoding.GORILLA);
private static final MeasurementSchema MEASUREMENT_13 =
new MeasurementSchema("sensor_13", TSDataType.TEXT, TSEncoding.PLAIN);
+ private static final MeasurementSchema MEASUREMENT_14 =
+ new MeasurementSchema("sensor_14", TSDataType.TIMESTAMP, TSEncoding.RLE);
+ private static final MeasurementSchema MEASUREMENT_15 =
+ new MeasurementSchema("sensor_15", TSDataType.DATE, TSEncoding.RLE);
+ private static final MeasurementSchema MEASUREMENT_16 =
+ new MeasurementSchema("sensor_16", TSDataType.BLOB, TSEncoding.PLAIN);
+ private static final MeasurementSchema MEASUREMENT_17 =
+ new MeasurementSchema("sensor_17", TSDataType.STRING, TSEncoding.PLAIN);
// device 2, non aligned, sg 1
private static final String DEVICE_2 = "root.sg.test_1.d_2";
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBRecoverIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBRecoverIT.java
index 7c4d87511d813..41bcc24a375a3 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBRecoverIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBRecoverIT.java
@@ -98,7 +98,7 @@ public void tearDown() throws Exception {
}
@Test
- public void RecoverTest1() {
+ public void recoverTest1() {
// stop cluster
EnvFactory.getEnv().shutdownAllDataNodes();
logger.info("All DataNodes are shut down");
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBVerifyConnectionIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBVerifyConnectionIT.java
new file mode 100644
index 0000000000000..378f47c0c385d
--- /dev/null
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBVerifyConnectionIT.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.it;
+
+import org.apache.iotdb.commons.service.ThriftService;
+import org.apache.iotdb.consensus.ConsensusFactory;
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({ClusterIT.class})
+public class IoTDBVerifyConnectionIT {
+
+ @Before
+ public void setUp() throws Exception {
+ EnvFactory.getEnv()
+ .getConfig()
+ .getCommonConfig()
+ .setConfigNodeConsensusProtocolClass(ConsensusFactory.RATIS_CONSENSUS);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+
+ @Test
+ public void testVerifyConnectionAllUp() throws Exception {
+ EnvFactory.getEnv().initClusterEnvironment(3, 3);
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ ResultSet resultSet = statement.executeQuery("verify connection");
+ Assert.assertEquals(
+ ImmutableMap.of(ThriftService.STATUS_UP, 12), collectConnectionResult(resultSet));
+ resultSet = statement.executeQuery("verify connection details");
+ Assert.assertEquals(
+ ImmutableMap.of(ThriftService.STATUS_UP, 54), collectConnectionResult(resultSet));
+ }
+ }
+
+ @Test
+ public void testVerifyConnectionWithNodeCrash() throws Exception {
+ EnvFactory.getEnv().initClusterEnvironment(3, 1);
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ ResultSet resultSet = statement.executeQuery("verify connection details");
+ Assert.assertEquals(
+ ImmutableMap.of(ThriftService.STATUS_UP, 18), collectConnectionResult(resultSet));
+ final int leaderIndex = EnvFactory.getEnv().getLeaderConfigNodeIndex();
+ int shutdownIndex = 0;
+ if (shutdownIndex == leaderIndex) {
+ shutdownIndex++;
+ }
+ EnvFactory.getEnv().getConfigNodeWrapperList().get(shutdownIndex++).stopForcibly();
+ resultSet = statement.executeQuery("verify connection");
+ Assert.assertEquals(
+ ImmutableMap.of(ThriftService.STATUS_UP, 2, ThriftService.STATUS_DOWN, 7),
+ collectConnectionResult(resultSet));
+ resultSet = statement.executeQuery("verify connection details");
+ Assert.assertEquals(
+ ImmutableMap.of(ThriftService.STATUS_UP, 11, ThriftService.STATUS_DOWN, 7),
+ collectConnectionResult(resultSet));
+ }
+ }
+
+ private static Map collectConnectionResult(ResultSet resultSet)
+ throws Exception {
+ Map map = new HashMap<>();
+ while (resultSet.next()) {
+ String result = resultSet.getString(3).split(" ")[0];
+ map.computeIfPresent(result, (key, value) -> value + 1);
+ map.putIfAbsent(result, 1);
+ }
+ return map;
+ }
+
+ private static void showResult(ResultSet resultSet) throws Exception {
+ while (resultSet.next()) {
+ System.out.printf(
+ "%s %s %s\n", resultSet.getString(1), resultSet.getString(2), resultSet.getString(3));
+ }
+ }
+}
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateAggregationIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateAggregationIT.java
index 5ec4566c54ce6..6d5d16a40c460 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateAggregationIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/alignbydevice/IoTDBAlignByDeviceWithTemplateAggregationIT.java
@@ -104,7 +104,7 @@ public void aggregationTest() {
// __endTime result is ambiguous
- // not supported: group by session, condition, agg(*), agg(s1+1), count(s1+s2), non-aligned
+ // not supported: group by session, condition, agg(s1+1), count(s1+s2), non-aligned
// template
}
@@ -528,6 +528,134 @@ public void orderByTest() {
"count(s_null) in order by clause doesn't exist.");
}
+ @Test
+ public void wildCardTest() {
+ String[] expectedHeader =
+ new String[] {
+ "Device,max_time(s3),max_time(s1),max_time(s2),last_value(s1),last_value(s3),last_value(s1),last_value(s2)"
+ };
+ String[] retArray =
+ new String[] {
+ "root.sg1.d1,1314000000000,1314000000000,1314000000000,13.14,1314,13.14,true,",
+ "root.sg1.d2,1314000000001,1314000000001,1314000000001,13.15,1315,13.15,false,",
+ "root.sg1.d3,1314000000002,1314000000002,1314000000002,13.16,1316,13.16,false,",
+ "root.sg1.d4,1314000000003,1314000000003,1314000000003,13.14,1314,13.14,true,",
+ };
+ resultSetEqualTest(
+ "SELECT max_time(*), last_value(s1), last_value(*) FROM root.sg1.** align by device;",
+ expectedHeader,
+ retArray);
+ retArray =
+ new String[] {
+ "root.sg2.d1,1314000000000,1314000000000,1314000000000,13.14,1314,13.14,true,",
+ "root.sg2.d2,1314000000001,1314000000001,1314000000001,13.15,1315,13.15,false,",
+ "root.sg2.d3,1314000000002,1314000000002,1314000000002,13.16,1316,13.16,false,",
+ "root.sg2.d4,1314000000003,1314000000003,1314000000003,13.14,1314,13.14,true,",
+ };
+ resultSetEqualTest(
+ "SELECT max_time(*), last_value(s1), last_value(*) FROM root.sg2.** align by device;",
+ expectedHeader,
+ retArray);
+
+ // filter test
+ expectedHeader =
+ new String[] {"Device,max_time(s1),last_value(s3),last_value(s1),last_value(s2),count(s2)"};
+ retArray =
+ new String[] {
+ "root.sg1.d1,1314000000000,1314,13.14,true,3,",
+ "root.sg1.d2,1314000000001,1315,13.15,false,4,",
+ "root.sg1.d3,1314000000002,1316,13.16,false,3,",
+ "root.sg1.d4,1314000000003,1314,13.14,true,4,",
+ };
+ resultSetEqualTest(
+ "SELECT max_time(s1), last_value(*), count(s2) FROM root.sg1.** where s3>1 align by device;",
+ expectedHeader,
+ retArray);
+ retArray =
+ new String[] {
+ "root.sg2.d1,1314000000000,1314,13.14,true,3,",
+ "root.sg2.d2,1314000000001,1315,13.15,false,4,",
+ "root.sg2.d3,1314000000002,1316,13.16,false,3,",
+ "root.sg2.d4,1314000000003,1314,13.14,true,4,",
+ };
+ resultSetEqualTest(
+ "SELECT max_time(s1), last_value(*), count(s2) FROM root.sg2.** where s3>1 align by device;",
+ expectedHeader,
+ retArray);
+
+ // sliding window
+ expectedHeader = new String[] {"Time,Device,last_value(s1),last_value(s2)"};
+ retArray =
+ new String[] {
+ "1,root.sg1.d1,2.2,false,",
+ "1,root.sg1.d2,22.2,false,",
+ "3,root.sg1.d2,50.0,false,",
+ "5,root.sg1.d2,50.0,false,",
+ "7,root.sg1.d3,8.8,false,",
+ "3,root.sg1.d4,5555.5,false,",
+ "5,root.sg1.d4,5555.5,false,",
+ };
+ resultSetEqualTest(
+ "SELECT last_value(*) FROM root.sg1.** where s3+1=1316 or s2=false group by ([1,10),3ms,2ms) having avg(s1)>0 soffset 1 slimit 2 align by device;",
+ expectedHeader,
+ retArray);
+ retArray =
+ new String[] {
+ "1,root.sg2.d1,2.2,false,",
+ "1,root.sg2.d2,22.2,false,",
+ "3,root.sg2.d2,50.0,false,",
+ "5,root.sg2.d2,50.0,false,",
+ "7,root.sg2.d3,8.8,false,",
+ "3,root.sg2.d4,5555.5,false,",
+ "5,root.sg2.d4,5555.5,false,",
+ };
+ resultSetEqualTest(
+ "SELECT last_value(*) FROM root.sg2.** where s3+1=1316 or s2=false group by ([1,10),3ms,2ms) having avg(s1)>0 soffset 1 slimit 2 align by device;",
+ expectedHeader,
+ retArray);
+
+ // having
+ expectedHeader =
+ new String[] {
+ "Device,last_value(s3),last_value(s1),last_value(s2),first_value(s3),first_value(s1),first_value(s2)"
+ };
+ retArray =
+ new String[] {
+ "root.sg1.d2,1315,13.15,false,11,11.1,false,",
+ };
+ resultSetEqualTest(
+ "SELECT last_value(*), first_value(*) FROM root.sg1.** where s2=false having count(s3+s1) > 2 align by device;",
+ expectedHeader,
+ retArray);
+ retArray =
+ new String[] {
+ "root.sg2.d2,1315,13.15,false,11,11.1,false,",
+ };
+ resultSetEqualTest(
+ "SELECT last_value(*), first_value(*) FROM root.sg2.** where s2=false having count(s3+s1) > 2 align by device;",
+ expectedHeader,
+ retArray);
+
+ // not supported expression: agg1(*)+agg2(*), agg(*)/2
+ expectedHeader = new String[] {"Device,count(s3) + 1,count(s1) + 1,count(s2) + 1"};
+ retArray =
+ new String[] {
+ "root.sg1.d2,5.0,5.0,5.0,",
+ };
+ resultSetEqualTest(
+ "SELECT count(*)+1 FROM root.sg1.** where s2=false having count(s3+s1) > 2 align by device;",
+ expectedHeader,
+ retArray);
+ retArray =
+ new String[] {
+ "root.sg2.d2,5.0,5.0,5.0,",
+ };
+ resultSetEqualTest(
+ "SELECT count(*)+1 FROM root.sg2.** where s2=false having count(s3+s1) > 2 align by device;",
+ expectedHeader,
+ retArray);
+ }
+
protected static void insertData() {
try (Connection connection = EnvFactory.getEnv().getConnection();
Statement statement = connection.createStatement()) {
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBPredicatePushDownIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBPredicatePushDownIT.java
index 4d3ff5120df38..1a65682fc5b83 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBPredicatePushDownIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBPredicatePushDownIT.java
@@ -91,6 +91,13 @@ public void testAlignedRawDataAlignByTime1() {
};
resultSetEqualTest(
"select s2 from root.sg1.d1 where s2 - 1 >= 9 and s2 < 30", expectedHeader3, retArray3);
+
+ String expectedHeader4 = "Time,root.sg1.d1.s2,";
+ String[] retArray4 = new String[] {"14,14,", "15,15,"};
+ resultSetEqualTest(
+ "select s2 from root.sg1.d1 where s2 - 1 >= 9 and s2 < 30 offset 3 limit 2",
+ expectedHeader4,
+ retArray4);
}
@Test
@@ -164,6 +171,11 @@ public void testAlignedRawDataAlignByTime2() {
"30,30,",
};
resultSetEqualTest("select s3 from root.sg1.d1 where s3 + 1 > 16", expectedHeader3, retArray3);
+
+ String expectedHeader4 = "Time,root.sg1.d1.s3,";
+ String[] retArray4 = new String[] {"3,30000,", "13,130000,", "16,16,"};
+ resultSetEqualTest(
+ "select s3 from root.sg1.d1 where s3 + 1 > 16 limit 3", expectedHeader4, retArray4);
}
@Test
@@ -203,6 +215,13 @@ public void testNonAlignedRawDataAlignByTime1() {
};
resultSetEqualTest(
"select s2 from root.sg1.d2 where s2 - 1 >= 9 and s2 < 30", expectedHeader3, retArray3);
+
+ String expectedHeader4 = "Time,root.sg1.d2.s2,";
+ String[] retArray4 = new String[] {"12,12,", "13,13,", "14,14,"};
+ resultSetEqualTest(
+ "select s2 from root.sg1.d2 where s2 - 1 >= 9 and s2 < 30 limit 3 offset 2",
+ expectedHeader4,
+ retArray4);
}
@Test
@@ -257,6 +276,14 @@ public void testNonAlignedRawDataAlignByTime2() {
"25,25,", "26,26,", "27,27,", "28,28,", "29,29,", "30,30,",
};
resultSetEqualTest("select s3 from root.sg1.d2 where s3 + 1 > 16", expectedHeader3, retArray3);
+
+ String expectedHeader4 = "Time,root.sg1.d2.s3,";
+ String[] retArray4 =
+ new String[] {
+ "26,26,", "27,27,", "28,28,", "29,29,", "30,30,",
+ };
+ resultSetEqualTest(
+ "select s3 from root.sg1.d2 where s3 + 1 > 16 offset 10", expectedHeader4, retArray4);
}
@Test
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanIT.java
similarity index 98%
rename from integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanIT.java
rename to integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanIT.java
index c608bf3e24c0e..aa568b583c1bd 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanIT.java
@@ -17,18 +17,17 @@
* under the License.
*/
-package org.apache.iotdb.db.it.regionscan;
+package org.apache.iotdb.db.it.schema.regionscan;
import org.apache.iotdb.it.env.EnvFactory;
-import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.ClusterIT;
import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.util.AbstractSchemaIT;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
import java.sql.Connection;
import java.sql.ResultSet;
@@ -45,9 +44,8 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
-public class IoTDBActiveRegionScanIT {
+public class IoTDBActiveRegionScanIT extends AbstractSchemaIT {
// Data can be viewed in
// https://docs.google.com/spreadsheets/d/11tNRIaHmNdFWc0RC4yAloO6JJbmo9S5qxwAqWxeVY6c/edit#gid=0
public static final String[] common_insert_sqls =
@@ -145,6 +143,10 @@ public class IoTDBActiveRegionScanIT {
public static final String COUNT_TIMESERIES_COLUMN_NAMES = "count(timeseries)";
public static final String COUNT_DEVICES_COLUMN_NAMES = "count(devices)";
+ public IoTDBActiveRegionScanIT(SchemaTestMode schemaTestMode) {
+ super(schemaTestMode);
+ }
+
public static void insertData() {
try (Connection connection = EnvFactory.getEnv().getConnection();
Statement statement = connection.createStatement()) {
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanIT2.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanIT2.java
similarity index 91%
rename from integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanIT2.java
rename to integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanIT2.java
index be4751495de4b..da56d3078b01e 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanIT2.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanIT2.java
@@ -17,21 +17,22 @@
* under the License.
*/
-package org.apache.iotdb.db.it.regionscan;
+package org.apache.iotdb.db.it.schema.regionscan;
import org.apache.iotdb.it.env.EnvFactory;
-import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.ClusterIT;
import org.apache.iotdb.itbase.category.LocalStandaloneIT;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
public class IoTDBActiveRegionScanIT2 extends IoTDBActiveRegionScanIT {
+ public IoTDBActiveRegionScanIT2(SchemaTestMode schemaTestMode) {
+ super(schemaTestMode);
+ }
+
@BeforeClass
public static void setUp() throws Exception {
EnvFactory.getEnv()
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanWithModsIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanWithModsIT.java
similarity index 85%
rename from integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanWithModsIT.java
rename to integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanWithModsIT.java
index d977a6d0132e6..0c10f507aa214 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanWithModsIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanWithModsIT.java
@@ -17,34 +17,32 @@
* under the License.
*/
-package org.apache.iotdb.db.it.regionscan;
+package org.apache.iotdb.db.it.schema.regionscan;
import org.apache.iotdb.it.env.EnvFactory;
-import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.ClusterIT;
import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.util.AbstractSchemaIT;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
import java.sql.Connection;
import java.sql.Statement;
-import static org.apache.iotdb.db.it.regionscan.IoTDBActiveRegionScanIT.COUNT_DEVICES_COLUMN_NAMES;
-import static org.apache.iotdb.db.it.regionscan.IoTDBActiveRegionScanIT.COUNT_TIMESERIES_COLUMN_NAMES;
-import static org.apache.iotdb.db.it.regionscan.IoTDBActiveRegionScanIT.SHOW_DEVICES_COLUMN_NAMES;
-import static org.apache.iotdb.db.it.regionscan.IoTDBActiveRegionScanIT.SHOW_TIMESERIES_COLUMN_NAMES;
-import static org.apache.iotdb.db.it.regionscan.IoTDBActiveRegionScanIT.basicCountActiveDeviceTest;
-import static org.apache.iotdb.db.it.regionscan.IoTDBActiveRegionScanIT.basicShowActiveDeviceTest;
-import static org.apache.iotdb.db.it.regionscan.IoTDBActiveRegionScanIT.common_insert_sqls;
+import static org.apache.iotdb.db.it.schema.regionscan.IoTDBActiveRegionScanIT.COUNT_DEVICES_COLUMN_NAMES;
+import static org.apache.iotdb.db.it.schema.regionscan.IoTDBActiveRegionScanIT.COUNT_TIMESERIES_COLUMN_NAMES;
+import static org.apache.iotdb.db.it.schema.regionscan.IoTDBActiveRegionScanIT.SHOW_DEVICES_COLUMN_NAMES;
+import static org.apache.iotdb.db.it.schema.regionscan.IoTDBActiveRegionScanIT.SHOW_TIMESERIES_COLUMN_NAMES;
+import static org.apache.iotdb.db.it.schema.regionscan.IoTDBActiveRegionScanIT.basicCountActiveDeviceTest;
+import static org.apache.iotdb.db.it.schema.regionscan.IoTDBActiveRegionScanIT.basicShowActiveDeviceTest;
+import static org.apache.iotdb.db.it.schema.regionscan.IoTDBActiveRegionScanIT.common_insert_sqls;
import static org.junit.Assert.fail;
-@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
-public class IoTDBActiveRegionScanWithModsIT {
+public class IoTDBActiveRegionScanWithModsIT extends AbstractSchemaIT {
private static String[] delete_sqls =
new String[] {
@@ -57,6 +55,10 @@ public class IoTDBActiveRegionScanWithModsIT {
"delete from root.sg.unaligned.d2.* where time > 40 and time <= 43"
};
+ public IoTDBActiveRegionScanWithModsIT(SchemaTestMode schemaTestMode) {
+ super(schemaTestMode);
+ }
+
public static void insertData() {
try (Connection connection = EnvFactory.getEnv().getConnection();
Statement statement = connection.createStatement()) {
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanWithModsIT2.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanWithModsIT2.java
similarity index 91%
rename from integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanWithModsIT2.java
rename to integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanWithModsIT2.java
index a87240341e019..5adccd1fd6980 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/regionscan/IoTDBActiveRegionScanWithModsIT2.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveRegionScanWithModsIT2.java
@@ -17,21 +17,22 @@
* under the License.
*/
-package org.apache.iotdb.db.it.regionscan;
+package org.apache.iotdb.db.it.schema.regionscan;
import org.apache.iotdb.it.env.EnvFactory;
-import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.ClusterIT;
import org.apache.iotdb.itbase.category.LocalStandaloneIT;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
public class IoTDBActiveRegionScanWithModsIT2 extends IoTDBActiveRegionScanWithModsIT {
+ public IoTDBActiveRegionScanWithModsIT2(SchemaTestMode schemaTestMode) {
+ super(schemaTestMode);
+ }
+
@BeforeClass
public static void setUp() throws Exception {
EnvFactory.getEnv()
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveSchemaQueryIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveSchemaQueryIT.java
new file mode 100644
index 0000000000000..853ef3c87ae00
--- /dev/null
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/regionscan/IoTDBActiveSchemaQueryIT.java
@@ -0,0 +1,363 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.it.schema.regionscan;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.util.AbstractSchemaIT;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runners.Parameterized;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBActiveSchemaQueryIT extends AbstractSchemaIT {
+
+ private static String[] sqls =
+ new String[] {
+ "create aligned timeseries root.sg.d1(s1(alias1) int32 tags('tag1'='v1', 'tag2'='v2'), s2 double attributes('attr3'='v3'))",
+ "CREATE TIMESERIES root.sg.d0.s0 WITH DATATYPE=INT32",
+ "CREATE TIMESERIES root.sg.d0.s1 WITH DATATYPE=INT32,ENCODING=PLAIN,LOSS=SDT,COMPDEV=2",
+ "CREATE TIMESERIES root.sg.d0.s2 WITH DATATYPE=INT32,ENCODING=PLAIN,LOSS=SDT, COMPDEV=0.01, COMPMINTIME=2, COMPMAXTIME=15",
+ "CREATE DEVICE TEMPLATE t1 (s1 INT64 encoding=RLE compressor=SNAPPY, s2 INT32)",
+ "CREATE DEVICE TEMPLATE t2 aligned(s1 INT64 encoding=RLE compressor=SNAPPY, s2 INT32)",
+ "SET DEVICE TEMPLATE t1 to root.sg.d2",
+ "SET DEVICE TEMPLATE t2 to root.sg.d3",
+ "CREATE TIMESERIES OF DEVICE TEMPLATE ON root.sg.d2",
+ "CREATE TIMESERIES OF DEVICE TEMPLATE ON root.sg.d3",
+ "set ttl to root.sg.d3 60000",
+ };
+
+ public IoTDBActiveSchemaQueryIT(SchemaTestMode schemaTestMode) {
+ super(schemaTestMode);
+ }
+
+ @Parameterized.BeforeParam
+ public static void before() throws Exception {
+ SchemaTestMode schemaTestMode = setUpEnvironment();
+ if (schemaTestMode.equals(SchemaTestMode.PBTree)) {
+ allocateMemoryForSchemaRegion(10000);
+ }
+ EnvFactory.getEnv().initClusterEnvironment();
+ }
+
+ @Parameterized.AfterParam
+ public static void after() throws Exception {
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ tearDownEnvironment();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ createSchema();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ clearSchema();
+ }
+
+ private void createSchema() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ for (String sql : sqls) {
+ statement.execute(sql);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testShowTimeSeries() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // 0. Check environment
+ Set expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d1.s1,alias1,root.sg,INT32,TS_2DIFF,LZ4,{\"tag1\":\"v1\",\"tag2\":\"v2\"},null,null,null,BASE,",
+ "root.sg.d1.s2,null,root.sg,DOUBLE,GORILLA,LZ4,null,{\"attr3\":\"v3\"},null,null,BASE,",
+ "root.sg.d0.s0,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.sg.d0.s1,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=2},BASE,",
+ "root.sg.d0.s2,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=0.01, compmintime=2, compmaxtime=15},BASE,",
+ "root.sg.d2.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,",
+ "root.sg.d2.s2,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.sg.d3.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,",
+ "root.sg.d3.s2,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,"));
+ checkResultSet(statement, "show timeseries root.sg.**", expected);
+ // 1. Without any data, result set should be empty
+ try (ResultSet resultSet =
+ statement.executeQuery("show timeseries root.sg.** where time>0")) {
+ Assert.assertFalse(resultSet.next());
+ }
+ // 2. Insert data and check again.
+ // - root.db.d0.* time=1
+ // - root.db.d1.* time=2
+ // - root.db.d2.* time=3
+ // - root.db.d3.* time=now()
+ statement.execute("insert into root.sg.d0(timestamp,s0, s1, s2) values(1,1,1,1)");
+ statement.execute("insert into root.sg.d1(timestamp,s1,s2) values(2,2,2)");
+ statement.execute("insert into root.sg.d2(timestamp,s1,s2) values(3,3,3)");
+ statement.execute("insert into root.sg.d3(timestamp,s1,s2) values(now(),4,4)");
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d1.s1,alias1,root.sg,INT32,TS_2DIFF,LZ4,{\"tag1\":\"v1\",\"tag2\":\"v2\"},null,null,null,BASE,",
+ "root.sg.d1.s2,null,root.sg,DOUBLE,GORILLA,LZ4,null,{\"attr3\":\"v3\"},null,null,BASE,",
+ "root.sg.d0.s0,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.sg.d0.s1,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=2},BASE,",
+ "root.sg.d0.s2,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=0.01, compmintime=2, compmaxtime=15},BASE,",
+ "root.sg.d2.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,",
+ "root.sg.d2.s2,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.sg.d3.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,",
+ "root.sg.d3.s2,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,"));
+ checkResultSet(statement, "show timeseries root.sg.** where time>0", expected);
+ checkResultSet(
+ statement,
+ "count timeseries root.sg.** where time>0",
+ new HashSet<>(Collections.singletonList("9,")));
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d1.s1,alias1,root.sg,INT32,TS_2DIFF,LZ4,{\"tag1\":\"v1\",\"tag2\":\"v2\"},null,null,null,BASE,",
+ "root.sg.d1.s2,null,root.sg,DOUBLE,GORILLA,LZ4,null,{\"attr3\":\"v3\"},null,null,BASE,",
+ "root.sg.d2.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,",
+ "root.sg.d2.s2,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.sg.d3.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,",
+ "root.sg.d3.s2,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,"));
+ checkResultSet(statement, "show timeseries root.sg.** where time>1", expected);
+ checkResultSet(
+ statement,
+ "count timeseries root.sg.** where time>1",
+ new HashSet<>(Collections.singletonList("6,")));
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d1.s1,alias1,root.sg,INT32,TS_2DIFF,LZ4,{\"tag1\":\"v1\",\"tag2\":\"v2\"},null,null,null,BASE,",
+ "root.sg.d1.s2,null,root.sg,DOUBLE,GORILLA,LZ4,null,{\"attr3\":\"v3\"},null,null,BASE,",
+ "root.sg.d2.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,",
+ "root.sg.d2.s2,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.sg.d3.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,",
+ "root.sg.d3.s2,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,"));
+ checkResultSet(statement, "show timeseries root.sg.** where time!=1", expected);
+ checkResultSet(
+ statement,
+ "count timeseries root.sg.** where time!=1",
+ new HashSet<>(Collections.singletonList("6,")));
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d0.s0,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.sg.d0.s1,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=2},BASE,",
+ "root.sg.d0.s2,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=0.01, compmintime=2, compmaxtime=15},BASE,"));
+ checkResultSet(statement, "show timeseries root.sg.** where time<2", expected);
+ checkResultSet(
+ statement,
+ "count timeseries root.sg.** where time<2",
+ new HashSet<>(Collections.singletonList("3,")));
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d0.s0,null,root.sg,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.sg.d0.s1,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=2},BASE,",
+ "root.sg.d0.s2,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=0.01, compmintime=2, compmaxtime=15},BASE,"));
+ checkResultSet(statement, "show timeseries root.sg.** where time=1", expected);
+ checkResultSet(
+ statement,
+ "count timeseries root.sg.** where time=1",
+ new HashSet<>(Collections.singletonList("3,")));
+ // 3. Check non-root user
+ statement.execute("CREATE USER user1 'password'");
+ statement.execute("GRANT READ_SCHEMA ON root.sg.d0.s1 TO USER user1");
+ statement.execute("GRANT READ_SCHEMA ON root.sg.d3.s1 TO USER user1");
+ try (Connection userCon = EnvFactory.getEnv().getConnection("user1", "password");
+ Statement userStmt = userCon.createStatement()) {
+ // 3.1 Without read data permission, result set should be empty
+ try (ResultSet resultSet =
+ userStmt.executeQuery("show timeseries root.sg.** where time>0")) {
+ Assert.assertFalse(resultSet.next());
+ }
+ checkResultSet(
+ userStmt,
+ "count timeseries root.sg.** where time>0",
+ new HashSet<>(Collections.singletonList("0,")));
+ }
+ statement.execute("GRANT READ_DATA ON root.sg.d0.s1 TO USER user1");
+ statement.execute("GRANT READ_DATA ON root.sg.d3.s1 TO USER user1");
+ try (Connection userCon = EnvFactory.getEnv().getConnection("user1", "password");
+ Statement userStmt = userCon.createStatement()) {
+ // 3.2 With read data permission, result set should not be empty
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d0.s1,null,root.sg,INT32,PLAIN,LZ4,null,null,SDT,{compdev=2},BASE,",
+ "root.sg.d3.s1,null,root.sg,INT64,RLE,SNAPPY,null,null,null,null,BASE,"));
+ checkResultSet(userStmt, "show timeseries root.sg.** where time>0", expected);
+ checkResultSet(
+ userStmt,
+ "count timeseries root.sg.** where time>0",
+ new HashSet<>(Collections.singletonList("2,")));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testShowDevices() {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ // 0. Check environment
+ Set expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d0,false,null,INF,",
+ "root.sg.d1,true,null,INF,",
+ "root.sg.d2,false,t1,INF,",
+ "root.sg.d3,true,t2,60000,"));
+ checkResultSet(statement, "show devices root.sg.*", expected);
+ // 1. Without any data, result set should be empty
+ try (ResultSet resultSet = statement.executeQuery("show devices root.sg.* where time>0")) {
+ Assert.assertFalse(resultSet.next());
+ }
+ // 2. Insert data and check again.
+ // - root.sg.d0.* time=1
+ // - root.sg.d1.* time=2
+ // - root.sg.d2.* time=3
+ // - root.sg.d3.* time=now()
+ statement.execute("insert into root.sg.d0(timestamp,s0, s1, s2) values(1,1,1,1)");
+ statement.execute("insert into root.sg.d1(timestamp,s1,s2) values(2,2,2)");
+ statement.execute("insert into root.sg.d2(timestamp,s1,s2) values(3,3,3)");
+ statement.execute("insert into root.sg.d3(timestamp,s1,s2) values(now(),4,4)");
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d0,false,null,INF,",
+ "root.sg.d1,true,null,INF,",
+ "root.sg.d2,false,t1,INF,",
+ "root.sg.d3,true,t2,60000,"));
+ checkResultSet(statement, "show devices root.sg.* where time>0", expected);
+ checkResultSet(
+ statement,
+ "count devices root.sg.* where time>0",
+ new HashSet<>(Collections.singletonList("4,")));
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d1,true,null,INF,",
+ "root.sg.d2,false,t1,INF,",
+ "root.sg.d3,true,t2,60000,"));
+ checkResultSet(statement, "show devices root.sg.* where time>1", expected);
+ checkResultSet(
+ statement,
+ "count devices root.sg.* where time>1",
+ new HashSet<>(Collections.singletonList("3,")));
+ expected =
+ new HashSet<>(
+ Arrays.asList(
+ "root.sg.d1,true,null,INF,",
+ "root.sg.d2,false,t1,INF,",
+ "root.sg.d3,true,t2,60000,"));
+ checkResultSet(statement, "show devices root.sg.* where time!=1", expected);
+ checkResultSet(
+ statement,
+ "count devices root.sg.* where time!=1",
+ new HashSet<>(Collections.singletonList("3,")));
+ expected = new HashSet<>(Collections.singletonList("root.sg.d0,false,null,INF,"));
+ checkResultSet(statement, "show devices root.sg.* where time<2", expected);
+ checkResultSet(
+ statement,
+ "count devices root.sg.* where time<2",
+ new HashSet<>(Collections.singletonList("1,")));
+ expected = new HashSet<>(Collections.singletonList("root.sg.d0,false,null,INF,"));
+ checkResultSet(statement, "show devices root.sg.* where time=1", expected);
+ checkResultSet(
+ statement,
+ "count devices root.sg.* where time=1",
+ new HashSet<>(Collections.singletonList("1,")));
+ // 3. Check non-root user
+ statement.execute("CREATE USER user1 'password'");
+ statement.execute("GRANT READ_SCHEMA ON root.sg.d0.s1 TO USER user1");
+ statement.execute("GRANT READ_SCHEMA ON root.sg.d3.s1 TO USER user1");
+ try (Connection userCon = EnvFactory.getEnv().getConnection("user1", "password");
+ Statement userStmt = userCon.createStatement()) {
+ // 3.1 Without read data permission, result set should be empty
+ try (ResultSet resultSet = userStmt.executeQuery("show devices root.sg.* where time>0")) {
+ Assert.assertFalse(resultSet.next());
+ }
+ checkResultSet(
+ userStmt,
+ "count devices root.sg.* where time>0",
+ new HashSet<>(Collections.singletonList("0,")));
+ }
+ statement.execute("GRANT READ_DATA ON root.sg.d0.s1 TO USER user1");
+ statement.execute("GRANT READ_DATA ON root.sg.d3.s1 TO USER user1");
+ try (Connection userCon = EnvFactory.getEnv().getConnection("user1", "password");
+ Statement userStmt = userCon.createStatement()) {
+ // 3.2 With read data permission, result set should not be empty
+ expected =
+ new HashSet<>(Arrays.asList("root.sg.d0,false,null,INF,", "root.sg.d3,true,t2,60000,"));
+ checkResultSet(userStmt, "show devices root.sg.* where time>0", expected);
+ checkResultSet(
+ userStmt,
+ "count devices root.sg.* where time>0",
+ new HashSet<>(Collections.singletonList("2,")));
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ private void checkResultSet(Statement statement, String sql, Set expected)
+ throws Exception {
+ try (ResultSet resultSet = statement.executeQuery(sql)) {
+ ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+ while (resultSet.next()) {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
+ builder.append(resultSet.getString(i)).append(",");
+ }
+ if (!expected.contains(builder.toString())) {
+ System.out.println(builder.toString());
+ }
+ Assert.assertTrue(expected.contains(builder.toString()));
+ expected.remove(builder.toString());
+ }
+ }
+ Assert.assertTrue(expected.isEmpty());
+ }
+}
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java b/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
index 176d0158dfce7..372c9200c5e6c 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
@@ -704,6 +704,9 @@ public static void assertDataEventuallyOnEnv(
Statement statement = connection.createStatement()) {
// Keep retrying if there are execution failures
await()
+ .pollInSameThread()
+ .pollDelay(1L, TimeUnit.SECONDS)
+ .pollInterval(1L, TimeUnit.SECONDS)
.atMost(timeoutSeconds, TimeUnit.SECONDS)
.untilAsserted(
() -> {
@@ -720,6 +723,36 @@ public static void assertDataEventuallyOnEnv(
}
}
+ public static void assertDataEventuallyOnEnv(
+ BaseEnv env, String sql, Map expectedHeaderWithResult) {
+ assertDataEventuallyOnEnv(env, sql, expectedHeaderWithResult, 600);
+ }
+
+ public static void assertDataEventuallyOnEnv(
+ BaseEnv env, String sql, Map expectedHeaderWithResult, long timeoutSeconds) {
+ try (Connection connection = env.getConnection();
+ Statement statement = connection.createStatement()) {
+ // Keep retrying if there are execution failures
+ await()
+ .pollInSameThread()
+ .pollDelay(1L, TimeUnit.SECONDS)
+ .pollInterval(1L, TimeUnit.SECONDS)
+ .atMost(timeoutSeconds, TimeUnit.SECONDS)
+ .untilAsserted(
+ () -> {
+ try {
+ TestUtils.assertSingleResultSetEqual(
+ executeQueryWithRetry(statement, sql), expectedHeaderWithResult);
+ } catch (Exception e) {
+ Assert.fail();
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
public static void assertDataAlwaysOnEnv(
BaseEnv env, String sql, String expectedHeader, Set expectedResSet) {
assertDataAlwaysOnEnv(env, sql, expectedHeader, expectedResSet, 10);
@@ -735,6 +768,9 @@ public static void assertDataAlwaysOnEnv(
Statement statement = connection.createStatement()) {
// Keep retrying if there are execution failures
await()
+ .pollInSameThread()
+ .pollDelay(1L, TimeUnit.SECONDS)
+ .pollInterval(1L, TimeUnit.SECONDS)
.atMost(consistentSeconds, TimeUnit.SECONDS)
.failFast(
() -> {
diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeDataSinkIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeDataSinkIT.java
index 50a9b0d2ec5b2..8cd8d66d38791 100644
--- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeDataSinkIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeDataSinkIT.java
@@ -148,4 +148,109 @@ public void testLegacyConnector() throws Exception {
Collections.singleton("0,1.0,"));
}
}
+
+ @Test
+ public void testReceiverAutoCreateByLog() throws Exception {
+ testReceiverAutoCreate(
+ new HashMap() {
+ {
+ put("source.realtime.mode", "forced-log");
+ }
+ });
+ }
+
+ @Test
+ public void testReceiverAutoCreateByFile() throws Exception {
+ testReceiverAutoCreate(
+ new HashMap() {
+ {
+ put("source.realtime.mode", "batch");
+ }
+ });
+ }
+
+ @Test
+ public void testReceiverAutoCreateWithPattern() throws Exception {
+ testReceiverAutoCreate(
+ new HashMap() {
+ {
+ put("source.realtime.mode", "batch");
+ put("source.path", "root.ln.wf01.wt0*.*");
+ }
+ });
+ }
+
+ private void testReceiverAutoCreate(final Map extractorAttributes)
+ throws Exception {
+ final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
+
+ final String receiverIp = receiverDataNode.getIp();
+ final int receiverPort = receiverDataNode.getPort();
+
+ try (final SyncConfigNodeIServiceClient client =
+ (SyncConfigNodeIServiceClient) senderEnv.getLeaderConfigNodeConnection()) {
+ final Map processorAttributes = new HashMap<>();
+ final Map connectorAttributes = new HashMap<>();
+
+ connectorAttributes.put("sink", "iotdb-thrift-sink");
+ connectorAttributes.put("sink.batch.enable", "false");
+ connectorAttributes.put("sink.ip", receiverIp);
+ connectorAttributes.put("sink.port", Integer.toString(receiverPort));
+
+ final TSStatus status =
+ client.createPipe(
+ new TCreatePipeReq("testPipe", connectorAttributes)
+ .setExtractorAttributes(extractorAttributes)
+ .setProcessorAttributes(processorAttributes));
+
+ Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+
+ // Do not fail if the failure has nothing to do with pipe
+ // Because the failures will randomly generate due to resource limitation
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ senderEnv,
+ Arrays.asList(
+ "create timeSeries root.ln.wf01.wt01.boolean boolean",
+ "create timeSeries root.ln.wf01.wt01.int32 int32",
+ "create timeSeries root.ln.wf01.wt01.int64 int64",
+ "create timeSeries root.ln.wf01.wt01.float float",
+ "create timeSeries root.ln.wf01.wt01.double double",
+ "create timeSeries root.ln.wf01.wt01.time_stamp timestamp",
+ "create timeSeries root.ln.wf01.wt01.date date",
+ "create timeSeries root.ln.wf01.wt01.text text",
+ "create timeSeries root.ln.wf01.wt01.string string",
+ "create timeSeries root.ln.wf01.wt01.blob blob",
+ "create aligned timeSeries root.ln.wf01.wt02(int32 int32, boolean boolean)",
+ "insert into root.ln.wf01.wt01(time, boolean, int32, int64, float, double, time_stamp, date, text, string, blob) values (20000, false, 123, 321, 13.3, 14.4, now(), '2000-12-13', 'abc', 'def', X'f103')",
+ "insert into root.ln.wf01.wt02(time, int32, boolean) values (20000, 123, false)",
+ // For pattern parse
+ "insert into root.ln.wf01.wt11(time, redundant_data) values (20000, -1)",
+ "flush"))) {
+ return;
+ }
+
+ TestUtils.assertDataEventuallyOnEnv(
+ receiverEnv,
+ "show timeSeries root.ln.wf01.wt01.*",
+ "Timeseries,Alias,Database,DataType,Encoding,Compression,Tags,Attributes,Deadband,DeadbandParameters,ViewType,",
+ Collections.unmodifiableSet(
+ new HashSet<>(
+ Arrays.asList(
+ "root.ln.wf01.wt01.boolean,null,root.ln,BOOLEAN,RLE,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.int32,null,root.ln,INT32,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.int64,null,root.ln,INT64,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.float,null,root.ln,FLOAT,GORILLA,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.double,null,root.ln,DOUBLE,GORILLA,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.time_stamp,null,root.ln,TIMESTAMP,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.date,null,root.ln,DATE,TS_2DIFF,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.text,null,root.ln,TEXT,PLAIN,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.string,null,root.ln,STRING,PLAIN,LZ4,null,null,null,null,BASE,",
+ "root.ln.wf01.wt01.blob,null,root.ln,BLOB,PLAIN,LZ4,null,null,null,null,BASE,"))));
+ TestUtils.assertDataEventuallyOnEnv(
+ receiverEnv,
+ "show devices root.ln.wf01.wt02",
+ "Device,IsAligned,Template,TTL,",
+ Collections.singleton("root.ln.wf01.wt02,true,null,INF,"));
+ }
+ }
}
diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeExtractorIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeExtractorIT.java
index 1befb2b765d7b..2a4439eb605c9 100644
--- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeExtractorIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeExtractorIT.java
@@ -24,7 +24,9 @@
import org.apache.iotdb.confignode.rpc.thrift.TCreatePipeReq;
import org.apache.iotdb.confignode.rpc.thrift.TShowPipeInfo;
import org.apache.iotdb.confignode.rpc.thrift.TShowPipeReq;
+import org.apache.iotdb.consensus.ConsensusFactory;
import org.apache.iotdb.db.it.utils.TestUtils;
+import org.apache.iotdb.it.env.MultiEnvFactory;
import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.MultiClusterIT2AutoCreateSchema;
@@ -32,6 +34,7 @@
import org.apache.iotdb.rpc.TSStatusCode;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
@@ -51,6 +54,39 @@
@RunWith(IoTDBTestRunner.class)
@Category({MultiClusterIT2AutoCreateSchema.class})
public class IoTDBPipeExtractorIT extends AbstractPipeDualAutoIT {
+
+ @Before
+ public void setUp() {
+ MultiEnvFactory.createEnv(2);
+ senderEnv = MultiEnvFactory.getEnv(0);
+ receiverEnv = MultiEnvFactory.getEnv(1);
+
+ // TODO: delete ratis configurations
+ senderEnv
+ .getConfig()
+ .getCommonConfig()
+ .setAutoCreateSchemaEnabled(true)
+ .setConfigNodeConsensusProtocolClass(ConsensusFactory.RATIS_CONSENSUS)
+ .setSchemaRegionConsensusProtocolClass(ConsensusFactory.RATIS_CONSENSUS)
+ // Disable sender compaction for tsfile determination in loose range test
+ .setEnableSeqSpaceCompaction(false)
+ .setEnableUnseqSpaceCompaction(false)
+ .setEnableCrossSpaceCompaction(false);
+ receiverEnv
+ .getConfig()
+ .getCommonConfig()
+ .setAutoCreateSchemaEnabled(true)
+ .setConfigNodeConsensusProtocolClass(ConsensusFactory.RATIS_CONSENSUS)
+ .setSchemaRegionConsensusProtocolClass(ConsensusFactory.RATIS_CONSENSUS);
+
+ // 10 min, assert that the operations will not time out
+ senderEnv.getConfig().getCommonConfig().setCnConnectionTimeoutMs(600000);
+ receiverEnv.getConfig().getCommonConfig().setCnConnectionTimeoutMs(600000);
+
+ senderEnv.initClusterEnvironment();
+ receiverEnv.initClusterEnvironment();
+ }
+
@Test
public void testExtractorValidParameter() throws Exception {
final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
@@ -867,6 +903,136 @@ public void testSourceStartTimeAndEndTimeWorkingWithOrWithoutPattern() throws Ex
}
}
+ @Test
+ public void testHistoryLooseRange() throws Exception {
+ final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
+
+ final String receiverIp = receiverDataNode.getIp();
+ final int receiverPort = receiverDataNode.getPort();
+
+ try (final SyncConfigNodeIServiceClient client =
+ (SyncConfigNodeIServiceClient) senderEnv.getLeaderConfigNodeConnection()) {
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ senderEnv,
+ Arrays.asList(
+ // TsFile 1, extracted without parse
+ "insert into root.db.d1 (time, at1, at2)" + " values (1000, 1, 2), (2000, 3, 4)",
+ // TsFile 2, not extracted because pattern not overlapped
+ "insert into root.db1.d1 (time, at1, at2)" + " values (1000, 1, 2), (2000, 3, 4)",
+ "flush"))) {
+ return;
+ }
+
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ senderEnv,
+ Arrays.asList(
+ // TsFile 3, not extracted because time range not overlapped
+ "insert into root.db.d1 (time, at1, at2)" + " values (3000, 1, 2), (4000, 3, 4)",
+ "flush"))) {
+ return;
+ }
+
+ final Map extractorAttributes = new HashMap<>();
+ final Map processorAttributes = new HashMap<>();
+ final Map connectorAttributes = new HashMap<>();
+
+ extractorAttributes.put("source.path", "root.db.d1.at1");
+ extractorAttributes.put("source.inclusion", "data.insert");
+ extractorAttributes.put("source.history.start-time", "1500");
+ extractorAttributes.put("source.history.end-time", "2500");
+ extractorAttributes.put("source.history.loose-range", "time, path");
+
+ connectorAttributes.put("connector", "iotdb-thrift-connector");
+ connectorAttributes.put("connector.batch.enable", "false");
+ connectorAttributes.put("connector.ip", receiverIp);
+ connectorAttributes.put("connector.port", Integer.toString(receiverPort));
+
+ TSStatus status =
+ client.createPipe(
+ new TCreatePipeReq("p1", connectorAttributes)
+ .setExtractorAttributes(extractorAttributes)
+ .setProcessorAttributes(processorAttributes));
+ Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+ Assert.assertEquals(
+ TSStatusCode.SUCCESS_STATUS.getStatusCode(), client.startPipe("p1").getCode());
+
+ TestUtils.assertDataEventuallyOnEnv(
+ receiverEnv,
+ "select count(*) from root.** group by level=0",
+ "count(root.*.*.*),",
+ Collections.singleton("4,"));
+ }
+ }
+
+ @Test
+ public void testRealtimeLooseRange() throws Exception {
+ final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
+ final String receiverIp = receiverDataNode.getIp();
+ final int receiverPort = receiverDataNode.getPort();
+
+ final Map extractorAttributes = new HashMap<>();
+ final Map processorAttributes = new HashMap<>();
+ final Map connectorAttributes = new HashMap<>();
+
+ extractorAttributes.put("source.path", "root.db.d1.at1");
+ extractorAttributes.put("source.inclusion", "data.insert");
+ extractorAttributes.put("source.realtime.loose-range", "time, path");
+ extractorAttributes.put("source.start-time", "2000");
+ extractorAttributes.put("source.end-time", "10000");
+ extractorAttributes.put("source.realtime.mode", "batch");
+
+ connectorAttributes.put("connector", "iotdb-thrift-connector");
+ connectorAttributes.put("connector.batch.enable", "false");
+ connectorAttributes.put("connector.ip", receiverIp);
+ connectorAttributes.put("connector.port", Integer.toString(receiverPort));
+
+ try (final SyncConfigNodeIServiceClient client =
+ (SyncConfigNodeIServiceClient) senderEnv.getLeaderConfigNodeConnection()) {
+ TSStatus status =
+ client.createPipe(
+ new TCreatePipeReq("p1", connectorAttributes)
+ .setExtractorAttributes(extractorAttributes)
+ .setProcessorAttributes(processorAttributes));
+ Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+ Assert.assertEquals(
+ TSStatusCode.SUCCESS_STATUS.getStatusCode(), client.startPipe("p1").getCode());
+
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ senderEnv,
+ Arrays.asList(
+ "insert into root.db.d1 (time, at1, at2)" + " values (1000, 1, 2), (3000, 3, 4)",
+ "flush"))) {
+ return;
+ }
+
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ senderEnv,
+ Arrays.asList(
+ "insert into root.db1.d1 (time, at1, at2)" + " values (1000, 1, 2), (3000, 3, 4)",
+ "flush"))) {
+ return;
+ }
+
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ senderEnv,
+ Arrays.asList(
+ "insert into root.db.d1 (time, at1)" + " values (5000, 1), (16000, 3)",
+ "insert into root.db.d1 (time, at1, at2)" + " values (5001, 1, 2), (6001, 3, 4)",
+ "flush"))) {
+ return;
+ }
+
+ TestUtils.assertDataEventuallyOnEnv(
+ receiverEnv,
+ "select count(at1) from root.db.d1 where time >= 2000 and time <= 10000",
+ new HashMap() {
+ {
+ put("count(root.db.d1.at1)", "4");
+ }
+ });
+ }
+ }
+
private void assertTimeseriesCountOnReceiver(BaseEnv receiverEnv, int count) {
TestUtils.assertDataEventuallyOnEnv(
receiverEnv, "count timeseries", "count(timeseries),", Collections.singleton(count + ","));
diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/single/IoTDBPipeAggregateIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/single/IoTDBPipeAggregateIT.java
index 544509b82894a..cbd9c08f4e5c2 100644
--- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/single/IoTDBPipeAggregateIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/single/IoTDBPipeAggregateIT.java
@@ -78,6 +78,20 @@ public void testAggregator() throws Exception {
.setProcessorAttributes(processorAttributes));
Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+ // Test unsupported types
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ env,
+ Arrays.asList(
+ "create timeSeries root.ln.wf01.wt01.boolean boolean",
+ "create timeSeries root.ln.wf01.wt01.date date",
+ "create timeSeries root.ln.wf01.wt01.text text",
+ "create timeSeries root.ln.wf01.wt01.string string",
+ "create timeSeries root.ln.wf01.wt01.blob blob",
+ "insert into root.ln.wf01.wt01(time, boolean, date, text, string, blob) values (20000, false, '2000-12-13', 'abc', 'def', X'f103')",
+ "flush"))) {
+ return;
+ }
+
if (!TestUtils.tryExecuteNonQueriesWithRetry(
env,
Arrays.asList(
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/AbstractSubscriptionIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/AbstractSubscriptionIT.java
new file mode 100644
index 0000000000000..a168dbc78ba72
--- /dev/null
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/AbstractSubscriptionIT.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.subscription.it;
+
+import org.apache.iotdb.session.subscription.consumer.SubscriptionExecutorServiceManager;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.junit.rules.TestRule;
+
+public abstract class AbstractSubscriptionIT {
+
+ @Rule public TestName testName = new TestName();
+
+ @Rule public final TestRule skipOnSetUpFailure = new SkipOnSetUpFailure("setUp");
+
+ @Before
+ public void setUp() {
+ // set thread name
+ Thread.currentThread().setName(String.format("%s - main", testName.getMethodName()));
+
+ // set thread pools core size
+ SubscriptionExecutorServiceManager.setControlFlowExecutorCorePoolSize(1);
+ SubscriptionExecutorServiceManager.setUpstreamDataFlowExecutorCorePoolSize(1);
+ SubscriptionExecutorServiceManager.setDownstreamDataFlowExecutorCorePoolSize(1);
+ }
+
+ @After
+ public void tearDown() {}
+}
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/IoTDBSubscriptionITConstant.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/IoTDBSubscriptionITConstant.java
index d2dc8ee49a5fc..5b8ec39327414 100644
--- a/integration-test/src/test/java/org/apache/iotdb/subscription/it/IoTDBSubscriptionITConstant.java
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/IoTDBSubscriptionITConstant.java
@@ -19,11 +19,24 @@
package org.apache.iotdb.subscription.it;
+import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionFactory;
+
+import java.util.concurrent.TimeUnit;
+
public class IoTDBSubscriptionITConstant {
- public static final long AWAITILITY_POLL_DELAY_SECOND = 1L;
- public static final long AWAITILITY_POLL_INTERVAL_SECOND = 2L;
- public static final long AWAITILITY_AT_MOST_SECOND = 240L;
+ private static final long AWAITILITY_POLL_DELAY_SECOND = 1L;
+ private static final long AWAITILITY_POLL_INTERVAL_SECOND = 1L;
+ private static final long AWAITILITY_AT_MOST_SECOND = 600L;
+
+ public static final ConditionFactory AWAIT =
+ Awaitility.await()
+ .pollInSameThread()
+ .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
+ .pollInterval(
+ IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
+ .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS);
public static final long SLEEP_NS = 1_000_000_000L;
public static final long POLL_TIMEOUT_MS = 10_000L;
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/SkipOnSetUpFailure.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/SkipOnSetUpFailure.java
new file mode 100644
index 0000000000000..add7b7c1e2b88
--- /dev/null
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/SkipOnSetUpFailure.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.subscription.it;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.junit.AssumptionViolatedException;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.lang.reflect.Method;
+
+public class SkipOnSetUpFailure implements TestRule {
+
+ private final String setUpMethodName;
+
+ /**
+ * @param setUpMethodName Should be exactly the same as the method name decorated with @Before.
+ */
+ public SkipOnSetUpFailure(@NonNull final String setUpMethodName) {
+ this.setUpMethodName = setUpMethodName;
+ }
+
+ @Override
+ public Statement apply(final Statement base, final Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ base.evaluate();
+ } catch (final Throwable e) {
+ // Trace back the exception stack to determine whether the exception was thrown during the
+ // setUp phase.
+ for (final StackTraceElement stackTraceElement : e.getStackTrace()) {
+ if (setUpMethodName.equals(stackTraceElement.getMethodName())
+ && description.getClassName().equals(stackTraceElement.getClassName())
+ && isMethodAnnotationWithBefore(stackTraceElement.getMethodName())) {
+ e.printStackTrace();
+ // Skip this test.
+ throw new AssumptionViolatedException(
+ String.format(
+ "Skipping test due to setup failure for %s#%s",
+ description.getClassName(), description.getMethodName()));
+ }
+ }
+
+ // Re-throw the exception (which means the test has failed).
+ throw e;
+
+ // Regardless of the circumstances, the method decorated with @After will always be
+ // executed.
+ }
+ }
+
+ private boolean isMethodAnnotationWithBefore(final String methodName) {
+ try {
+ final Method method = description.getTestClass().getDeclaredMethod(methodName);
+ return method.isAnnotationPresent(org.junit.Before.class);
+ } catch (final Throwable ignored) {
+ return false;
+ }
+ }
+ };
+ }
+}
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionRestartIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/cluster/IoTDBSubscriptionRestartIT.java
similarity index 89%
rename from integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionRestartIT.java
rename to integration-test/src/test/java/org/apache/iotdb/subscription/it/cluster/IoTDBSubscriptionRestartIT.java
index 2764fad56b83e..41dd654383d66 100644
--- a/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionRestartIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/cluster/IoTDBSubscriptionRestartIT.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.iotdb.subscription.it.local;
+package org.apache.iotdb.subscription.it.cluster;
import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient;
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq;
@@ -36,9 +36,9 @@
import org.apache.iotdb.session.subscription.consumer.SubscriptionPullConsumer;
import org.apache.iotdb.session.subscription.payload.SubscriptionMessage;
import org.apache.iotdb.session.subscription.payload.SubscriptionSessionDataSet;
+import org.apache.iotdb.subscription.it.AbstractSubscriptionIT;
import org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant;
-import org.awaitility.Awaitility;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -51,20 +51,23 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
+import static org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant.AWAIT;
import static org.junit.Assert.fail;
@RunWith(IoTDBTestRunner.class)
@Category({ClusterIT.class})
-public class IoTDBSubscriptionRestartIT {
+public class IoTDBSubscriptionRestartIT extends AbstractSubscriptionIT {
private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBSubscriptionRestartIT.class);
+ @Override
@Before
- public void setUp() throws Exception {
+ public void setUp() {
+ super.setUp();
+
EnvFactory.getEnv()
.getConfig()
.getCommonConfig()
@@ -77,8 +80,11 @@ public void setUp() throws Exception {
EnvFactory.getEnv().initClusterEnvironment(3, 3);
}
+ @Override
@After
- public void tearDown() throws Exception {
+ public void tearDown() {
+ super.tearDown();
+
EnvFactory.getEnv().cleanClusterEnvironment();
}
@@ -123,6 +129,7 @@ public void testSubscriptionAfterRestartCluster() throws Exception {
TestUtils.restartCluster(EnvFactory.getEnv());
} catch (final Throwable e) {
e.printStackTrace();
+ // Avoid failure
return;
}
@@ -148,9 +155,10 @@ public void testSubscriptionAfterRestartCluster() throws Exception {
String.format("insert into root.db.d1(time, s1) values (%s, 1)", i));
}
session.executeNonQueryStatement("flush");
- } catch (final Exception e) {
+ } catch (final Throwable e) {
e.printStackTrace();
- fail(e.getMessage());
+ // Avoid failure
+ return;
}
// Subscription again
@@ -188,18 +196,14 @@ public void testSubscriptionAfterRestartCluster() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - %s", testName.getMethodName(), consumer));
thread.start();
// Check timestamps size
try {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(() -> Assert.assertEquals(100, timestamps.size()));
+ AWAIT.untilAsserted(() -> Assert.assertEquals(100, timestamps.size()));
} catch (final Exception e) {
e.printStackTrace();
fail(e.getMessage());
@@ -253,9 +257,10 @@ public void testSubscriptionAfterRestartDataNode() throws Exception {
String.format("insert into root.db.d1(time, s1) values (%s, 1)", i));
}
session.executeNonQueryStatement("flush");
- } catch (final Exception e) {
+ } catch (final Throwable e) {
e.printStackTrace();
- fail(e.getMessage());
+ // Avoid failure
+ return;
}
// Shutdown DN 1 & DN 2
@@ -265,6 +270,7 @@ public void testSubscriptionAfterRestartDataNode() throws Exception {
EnvFactory.getEnv().shutdownDataNode(2);
} catch (final Throwable e) {
e.printStackTrace();
+ // Avoid failure
return;
}
@@ -303,7 +309,8 @@ public void testSubscriptionAfterRestartDataNode() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - %s", testName.getMethodName(), consumer));
thread.start();
// Start DN 1 & DN 2
@@ -314,6 +321,7 @@ public void testSubscriptionAfterRestartDataNode() throws Exception {
((AbstractEnv) EnvFactory.getEnv()).checkClusterStatusWithoutUnknown();
} catch (final Throwable e) {
e.printStackTrace();
+ // Avoid failure
return;
}
@@ -324,20 +332,16 @@ public void testSubscriptionAfterRestartDataNode() throws Exception {
String.format("insert into root.db.d1(time, s1) values (%s, 1)", i));
}
session.executeNonQueryStatement("flush");
- } catch (final Exception e) {
+ } catch (final Throwable e) {
e.printStackTrace();
- fail(e.getMessage());
+ // Avoid failure
+ return;
}
// Check timestamps size
try {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(() -> Assert.assertEquals(200, timestamps.size()));
+ AWAIT.untilAsserted(() -> Assert.assertEquals(200, timestamps.size()));
} catch (final Exception e) {
e.printStackTrace();
fail(e.getMessage());
@@ -391,9 +395,10 @@ public void testSubscriptionWhenConfigNodeLeaderChange() throws Exception {
String.format("insert into root.db.d1(time, s1) values (%s, 1)", i));
}
session.executeNonQueryStatement("flush");
- } catch (final Exception e) {
+ } catch (final Throwable e) {
e.printStackTrace();
- fail(e.getMessage());
+ // Avoid failure
+ return;
}
// Subscription again
@@ -431,11 +436,18 @@ public void testSubscriptionWhenConfigNodeLeaderChange() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - %s", testName.getMethodName(), consumer));
thread.start();
// Shutdown leader CN
- EnvFactory.getEnv().shutdownConfigNode(EnvFactory.getEnv().getLeaderConfigNodeIndex());
+ try {
+ EnvFactory.getEnv().shutdownConfigNode(EnvFactory.getEnv().getLeaderConfigNodeIndex());
+ } catch (final Throwable e) {
+ e.printStackTrace();
+ // Avoid failure
+ return;
+ }
// Insert some realtime data
try (final ISession session = EnvFactory.getEnv().getSessionConnection()) {
@@ -444,9 +456,10 @@ public void testSubscriptionWhenConfigNodeLeaderChange() throws Exception {
String.format("insert into root.db.d1(time, s1) values (%s, 1)", i));
}
session.executeNonQueryStatement("flush");
- } catch (final Exception e) {
+ } catch (final Throwable e) {
e.printStackTrace();
- fail(e.getMessage());
+ // Avoid failure
+ return;
}
// Show topics and subscriptions
@@ -467,12 +480,7 @@ public void testSubscriptionWhenConfigNodeLeaderChange() throws Exception {
// Check timestamps size
try {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(() -> Assert.assertEquals(200, timestamps.size()));
+ AWAIT.untilAsserted(() -> Assert.assertEquals(200, timestamps.size()));
} catch (final Exception e) {
e.printStackTrace();
fail(e.getMessage());
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/AbstractSubscriptionDualIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/AbstractSubscriptionDualIT.java
index 9aa01ad4acfba..fb25cdc3a6c09 100644
--- a/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/AbstractSubscriptionDualIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/AbstractSubscriptionDualIT.java
@@ -21,17 +21,21 @@
import org.apache.iotdb.it.env.MultiEnvFactory;
import org.apache.iotdb.itbase.env.BaseEnv;
+import org.apache.iotdb.subscription.it.AbstractSubscriptionIT;
import org.junit.After;
import org.junit.Before;
-abstract class AbstractSubscriptionDualIT {
+abstract class AbstractSubscriptionDualIT extends AbstractSubscriptionIT {
protected BaseEnv senderEnv;
protected BaseEnv receiverEnv;
+ @Override
@Before
public void setUp() {
+ super.setUp();
+
MultiEnvFactory.createEnv(2);
senderEnv = MultiEnvFactory.getEnv(0);
receiverEnv = MultiEnvFactory.getEnv(1);
@@ -42,7 +46,7 @@ public void setUp() {
receiverEnv.initClusterEnvironment();
}
- void setUpConfig() {
+ protected void setUpConfig() {
// enable auto create schema
senderEnv.getConfig().getCommonConfig().setAutoCreateSchemaEnabled(true);
receiverEnv.getConfig().getCommonConfig().setAutoCreateSchemaEnabled(true);
@@ -52,8 +56,11 @@ void setUpConfig() {
receiverEnv.getConfig().getCommonConfig().setCnConnectionTimeoutMs(600000);
}
+ @Override
@After
- public final void tearDown() {
+ public void tearDown() {
+ super.tearDown();
+
senderEnv.cleanClusterEnvironment();
receiverEnv.cleanClusterEnvironment();
}
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionConsumerGroupIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionConsumerGroupIT.java
index 992d151520f90..e332574925004 100644
--- a/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionConsumerGroupIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionConsumerGroupIT.java
@@ -42,7 +42,6 @@
import org.apache.tsfile.read.expression.QueryExpression;
import org.apache.tsfile.read.query.dataset.QueryDataSet;
import org.apache.tsfile.utils.Pair;
-import org.awaitility.Awaitility;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -62,11 +61,11 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
import java.util.stream.Collectors;
+import static org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant.AWAIT;
import static org.junit.Assert.fail;
@RunWith(IoTDBTestRunner.class)
@@ -109,7 +108,7 @@ static final class SubscriptionInfo {
}
@Override
- void setUpConfig() {
+ protected void setUpConfig() {
super.setUpConfig();
// Enable air gap receiver
@@ -1005,31 +1004,36 @@ private void pollMessagesAndCheck(
LOGGER.info("consumer {} exiting...", consumers.get(index));
}
},
- consumers.get(index).toString());
+ String.format("%s - %s", testName.getMethodName(), consumers.get(index).toString()));
t.start();
threads.add(t);
}
// Check data on receiver
+ final long[] currentTime = {System.currentTimeMillis()};
try {
try (final Connection connection = receiverEnv.getConnection();
final Statement statement = connection.createStatement()) {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () -> {
- if (receiverCrashed.get()) {
- LOGGER.info("detect receiver crashed, skipping this test...");
- return;
- }
- TestUtils.assertSingleResultSetEqual(
- TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
- expectedHeaderWithResult);
- });
+ AWAIT.untilAsserted(
+ () -> {
+ if (receiverCrashed.get()) {
+ LOGGER.info("detect receiver crashed, skipping this test...");
+ return;
+ }
+ // potential stuck
+ if (System.currentTimeMillis() - currentTime[0] > 60_000L) {
+ for (final DataNodeWrapper wrapper : senderEnv.getDataNodeWrapperList()) {
+ wrapper.executeJstack();
+ // wrapper.executeJstack(String.format("%s_%s", testName.getMethodName(),
+ // currentTime[0]));
+ }
+ currentTime[0] = System.currentTimeMillis();
+ }
+ TestUtils.assertSingleResultSetEqual(
+ TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
+ expectedHeaderWithResult);
+ });
}
} catch (final Exception e) {
e.printStackTrace();
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionTimePrecisionIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionTimePrecisionIT.java
index 2b1cc407b7f79..39a9f2225f6bb 100644
--- a/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionTimePrecisionIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionTimePrecisionIT.java
@@ -30,7 +30,6 @@
import org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant;
import org.apache.tsfile.write.record.Tablet;
-import org.awaitility.Awaitility;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
@@ -43,10 +42,10 @@
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
+import static org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant.AWAIT;
import static org.junit.Assert.fail;
@RunWith(IoTDBTestRunner.class)
@@ -57,7 +56,7 @@ public class IoTDBSubscriptionTimePrecisionIT extends AbstractSubscriptionDualIT
LoggerFactory.getLogger(IoTDBSubscriptionTimePrecisionIT.class);
@Override
- void setUpConfig() {
+ protected void setUpConfig() {
super.setUpConfig();
// Set timestamp precision to nanosecond
@@ -160,7 +159,8 @@ public void testTopicTimePrecision() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check data on receiver
@@ -168,21 +168,16 @@ public void testTopicTimePrecision() throws Exception {
try (final Connection connection = receiverEnv.getConnection();
final Statement statement = connection.createStatement()) {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () ->
- TestUtils.assertSingleResultSetEqual(
- TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
- new HashMap() {
- {
- put("count(root.db.d1.s2)", "100");
- put("count(root.db.d2.s1)", "100");
- }
- }));
+ AWAIT.untilAsserted(
+ () ->
+ TestUtils.assertSingleResultSetEqual(
+ TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
+ new HashMap() {
+ {
+ put("count(root.db.d1.s2)", "100");
+ put("count(root.db.d2.s1)", "100");
+ }
+ }));
}
} catch (final Exception e) {
e.printStackTrace();
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionTopicIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionTopicIT.java
index 0cd6bc0d0a106..d4aee45c482ad 100644
--- a/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionTopicIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/dual/IoTDBSubscriptionTopicIT.java
@@ -20,12 +20,15 @@
package org.apache.iotdb.subscription.it.dual;
import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient;
+import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq;
+import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp;
import org.apache.iotdb.confignode.rpc.thrift.TShowTopicInfo;
import org.apache.iotdb.confignode.rpc.thrift.TShowTopicReq;
import org.apache.iotdb.db.it.utils.TestUtils;
import org.apache.iotdb.isession.ISession;
import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.MultiClusterIT2Subscription;
+import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.subscription.config.TopicConstant;
import org.apache.iotdb.rpc.subscription.exception.SubscriptionRuntimeCriticalException;
import org.apache.iotdb.session.subscription.SubscriptionSession;
@@ -33,8 +36,11 @@
import org.apache.iotdb.session.subscription.payload.SubscriptionMessage;
import org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant;
+import org.apache.tsfile.read.TsFileReader;
+import org.apache.tsfile.read.common.Path;
+import org.apache.tsfile.read.expression.QueryExpression;
+import org.apache.tsfile.read.query.dataset.QueryDataSet;
import org.apache.tsfile.write.record.Tablet;
-import org.awaitility.Awaitility;
import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -45,17 +51,18 @@
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
+import static org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant.AWAIT;
import static org.junit.Assert.fail;
@RunWith(IoTDBTestRunner.class)
@@ -64,6 +71,19 @@ public class IoTDBSubscriptionTopicIT extends AbstractSubscriptionDualIT {
private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBSubscriptionTopicIT.class);
+ @Override
+ protected void setUpConfig() {
+ super.setUpConfig();
+
+ // Shorten heartbeat and sync interval to avoid timeout of query mode test
+ senderEnv
+ .getConfig()
+ .getCommonConfig()
+ .setPipeHeartbeatIntervalSecondsForCollectingPipeMeta(30);
+ senderEnv.getConfig().getCommonConfig().setPipeMetaSyncerInitialSyncDelayMinutes(1);
+ senderEnv.getConfig().getCommonConfig().setPipeMetaSyncerSyncIntervalMinutes(1);
+ }
+
@Test
public void testTopicPathSubscription() throws Exception {
// Insert some historical data on sender
@@ -136,7 +156,8 @@ public void testTopicPathSubscription() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check data on receiver
@@ -144,21 +165,16 @@ public void testTopicPathSubscription() throws Exception {
try (final Connection connection = receiverEnv.getConnection();
final Statement statement = connection.createStatement()) {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () ->
- TestUtils.assertSingleResultSetEqual(
- TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
- new HashMap() {
- {
- put("count(root.db.d1.s)", "100");
- put("count(root.db.d2.s)", "100");
- }
- }));
+ AWAIT.untilAsserted(
+ () ->
+ TestUtils.assertSingleResultSetEqual(
+ TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
+ new HashMap() {
+ {
+ put("count(root.db.d1.s)", "100");
+ put("count(root.db.d2.s)", "100");
+ }
+ }));
}
} catch (final Exception e) {
e.printStackTrace();
@@ -238,7 +254,8 @@ public void testTopicTimeSubscription() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check data on receiver
@@ -246,20 +263,15 @@ public void testTopicTimeSubscription() throws Exception {
try (final Connection connection = receiverEnv.getConnection();
final Statement statement = connection.createStatement()) {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () ->
- TestUtils.assertSingleResultSetEqual(
- TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
- new HashMap() {
- {
- put("count(root.db.d2.s)", "100");
- }
- }));
+ AWAIT.untilAsserted(
+ () ->
+ TestUtils.assertSingleResultSetEqual(
+ TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
+ new HashMap() {
+ {
+ put("count(root.db.d2.s)", "100");
+ }
+ }));
}
} catch (final Exception e) {
e.printStackTrace();
@@ -336,7 +348,8 @@ public void testTopicProcessorSubscription() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check data on receiver
@@ -348,17 +361,12 @@ public void testTopicProcessorSubscription() throws Exception {
try (final Connection connection = receiverEnv.getConnection();
final Statement statement = connection.createStatement()) {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () ->
- TestUtils.assertResultSetEqual(
- TestUtils.executeQueryWithRetry(statement, "select * from root.**"),
- "Time,root.db.d1.at1,",
- expectedResSet));
+ AWAIT.untilAsserted(
+ () ->
+ TestUtils.assertResultSetEqual(
+ TestUtils.executeQueryWithRetry(statement, "select * from root.**"),
+ "Time,root.db.d1.at1,",
+ expectedResSet));
}
} catch (final Exception e) {
e.printStackTrace();
@@ -392,9 +400,9 @@ public void testTopicNameWithBackQuote() throws Exception {
}
// Create topic on sender
- final String topic1 = "`topic1`";
- final String topic2 = "`'topic2'`";
- final String topic3 = "`\"topic3\"`";
+ final String topic1 = "`topic4`";
+ final String topic2 = "`'topic5'`";
+ final String topic3 = "`\"topic6\"`";
final String host = senderEnv.getIP();
final int port = Integer.parseInt(senderEnv.getPort());
try (final SubscriptionSession session = new SubscriptionSession(host, port)) {
@@ -464,7 +472,8 @@ public void testTopicNameWithBackQuote() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check data on receiver
@@ -472,20 +481,15 @@ public void testTopicNameWithBackQuote() throws Exception {
try (final Connection connection = receiverEnv.getConnection();
final Statement statement = connection.createStatement()) {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () ->
- TestUtils.assertSingleResultSetEqual(
- TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
- new HashMap() {
- {
- put("count(root.db.d1.s)", "300");
- }
- }));
+ AWAIT.untilAsserted(
+ () ->
+ TestUtils.assertSingleResultSetEqual(
+ TestUtils.executeQueryWithRetry(statement, "select count(*) from root.**"),
+ new HashMap() {
+ {
+ put("count(root.db.d1.s)", "300");
+ }
+ }));
}
} catch (final Exception e) {
e.printStackTrace();
@@ -507,7 +511,7 @@ public void testTopicInvalidTimeRangeConfig() throws Exception {
final Properties properties = new Properties();
properties.put(TopicConstant.START_TIME_KEY, "2024-01-32");
properties.put(TopicConstant.END_TIME_KEY, TopicConstant.NOW_TIME_VALUE);
- session.createTopic("topic1", properties);
+ session.createTopic("topic7", properties);
fail();
} catch (final Exception ignored) {
}
@@ -519,7 +523,7 @@ public void testTopicInvalidTimeRangeConfig() throws Exception {
final Properties properties = new Properties();
properties.put(TopicConstant.START_TIME_KEY, "2001.01.01T08:00:00");
properties.put(TopicConstant.END_TIME_KEY, "2000.01.01T08:00:00");
- session.createTopic("topic2", properties);
+ session.createTopic("topic8", properties);
fail();
} catch (final Exception ignored) {
}
@@ -529,21 +533,258 @@ public void testTopicInvalidTimeRangeConfig() throws Exception {
@Test
public void testTopicInvalidPathConfig() throws Exception {
// Test invalid path when using tsfile format
+ // NOTE: Delete this test after the restriction "on path/time range/processor when subscribing
+ // to tsfile" is removed.
final Properties config = new Properties();
config.put(TopicConstant.FORMAT_KEY, TopicConstant.FORMAT_TS_FILE_HANDLER_VALUE);
config.put(TopicConstant.PATH_KEY, "root.db.*.s");
- testTopicInvalidRuntimeConfigTemplate("topic3", config);
+ testTopicInvalidRuntimeConfigTemplate("topic9", config);
}
@Test
public void testTopicInvalidProcessorConfig() throws Exception {
// Test invalid processor when using tsfile format
+ // NOTE: Delete this test after the restriction "on path/time range/processor when subscribing
+ // to tsfile" is removed.
final Properties config = new Properties();
config.put(TopicConstant.FORMAT_KEY, TopicConstant.FORMAT_TS_FILE_HANDLER_VALUE);
config.put("processor", "tumbling-time-sampling-processor");
config.put("processor.tumbling-time.interval-seconds", "1");
config.put("processor.down-sampling.split-file", "true");
- testTopicInvalidRuntimeConfigTemplate("topic4", config);
+ testTopicInvalidRuntimeConfigTemplate("topic10", config);
+ }
+
+ @Test
+ public void testTopicWithQueryMode() throws Exception {
+ // Insert some historical data
+ try (final ISession session = senderEnv.getSessionConnection()) {
+ for (int i = 0; i < 100; ++i) {
+ session.executeNonQueryStatement(
+ String.format("insert into root.db.d1(time, s1) values (%s, 1)", i));
+ }
+ session.executeNonQueryStatement("flush");
+ } catch (final Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ // Create topic
+ final String topicName = "topic11";
+ final String host = senderEnv.getIP();
+ final int port = Integer.parseInt(senderEnv.getPort());
+ try (final SubscriptionSession session = new SubscriptionSession(host, port)) {
+ session.open();
+ final Properties config = new Properties();
+ config.put(TopicConstant.FORMAT_KEY, TopicConstant.FORMAT_TS_FILE_HANDLER_VALUE);
+ config.put(TopicConstant.MODE_KEY, TopicConstant.MODE_QUERY_VALUE);
+ session.createTopic(topicName, config);
+ } catch (final Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ assertTopicCount(1);
+
+ // Subscription
+ final AtomicInteger rowCount = new AtomicInteger();
+ final AtomicBoolean isClosed = new AtomicBoolean(false);
+ final Thread thread =
+ new Thread(
+ () -> {
+ try (final SubscriptionPullConsumer consumer =
+ new SubscriptionPullConsumer.Builder()
+ .host(host)
+ .port(port)
+ .consumerId("c1")
+ .consumerGroupId("cg1")
+ .autoCommit(false)
+ .buildPullConsumer()) {
+ consumer.open();
+ consumer.subscribe(topicName);
+ while (!isClosed.get()) {
+ LockSupport.parkNanos(IoTDBSubscriptionITConstant.SLEEP_NS); // wait some time
+ final List messages =
+ consumer.poll(IoTDBSubscriptionITConstant.POLL_TIMEOUT_MS);
+ for (final SubscriptionMessage message : messages) {
+ try (final TsFileReader tsFileReader =
+ message.getTsFileHandler().openReader()) {
+ final Path path = new Path("root.db.d1", "s1", true);
+ final QueryDataSet dataSet =
+ tsFileReader.query(
+ QueryExpression.create(Collections.singletonList(path), null));
+ while (dataSet.hasNext()) {
+ dataSet.next();
+ rowCount.addAndGet(1);
+ }
+ }
+ }
+ consumer.commitSync(messages);
+ }
+ // Exiting the loop represents passing the awaitility test, at this point the result
+ // of 'show subscription' is empty, so there is no need to explicitly unsubscribe.
+ } catch (final Exception e) {
+ e.printStackTrace();
+ // Avoid failure
+ } finally {
+ LOGGER.info("consumer exiting...");
+ }
+ },
+ String.format("%s - consumer", testName.getMethodName()));
+ thread.start();
+
+ try {
+ // Keep retrying if there are execution failures
+ AWAIT.untilAsserted(
+ () -> {
+ // Check row count
+ Assert.assertEquals(100, rowCount.get());
+ // Check empty subscription
+ try (final SyncConfigNodeIServiceClient client =
+ (SyncConfigNodeIServiceClient) senderEnv.getLeaderConfigNodeConnection()) {
+ final TShowSubscriptionResp showSubscriptionResp =
+ client.showSubscription(new TShowSubscriptionReq());
+ Assert.assertEquals(
+ RpcUtils.SUCCESS_STATUS.getCode(), showSubscriptionResp.status.getCode());
+ Assert.assertNotNull(showSubscriptionResp.subscriptionInfoList);
+ Assert.assertEquals(0, showSubscriptionResp.subscriptionInfoList.size());
+ }
+ });
+ } catch (final Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } finally {
+ isClosed.set(true);
+ thread.join();
+ }
+ }
+
+ @Test
+ public void testTopicWithLooseRange() throws Exception {
+ // Insert some historical data on sender
+ try (final ISession session = senderEnv.getSessionConnection()) {
+ session.executeNonQueryStatement(
+ "insert into root.db.d1 (time, at1, at2) values (1000, 1, 2), (2000, 3, 4)");
+ session.executeNonQueryStatement(
+ "insert into root.db1.d1 (time, at1, at2) values (1000, 1, 2), (2000, 3, 4)");
+ session.executeNonQueryStatement(
+ "insert into root.db.d1 (time, at1, at2) values (3000, 1, 2), (4000, 3, 4)");
+ session.executeNonQueryStatement("flush");
+ } catch (final Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ // Create topic
+ final String topicName = "topic12";
+ final String host = senderEnv.getIP();
+ final int port = Integer.parseInt(senderEnv.getPort());
+ try (final SubscriptionSession session = new SubscriptionSession(host, port)) {
+ session.open();
+ final Properties config = new Properties();
+ config.put(TopicConstant.LOOSE_RANGE_KEY, TopicConstant.LOOSE_RANGE_TIME_AND_PATH_VALUE);
+ config.put(TopicConstant.PATH_KEY, "root.db.d1.at1");
+ config.put(TopicConstant.START_TIME_KEY, "1500");
+ config.put(TopicConstant.END_TIME_KEY, "2500");
+ session.createTopic(topicName, config);
+ } catch (final Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ assertTopicCount(1);
+
+ final AtomicBoolean dataPrepared = new AtomicBoolean(false);
+ final AtomicBoolean topicSubscribed = new AtomicBoolean(false);
+ final AtomicBoolean result = new AtomicBoolean(false);
+ final List threads = new ArrayList<>();
+
+ // Subscribe on sender
+ threads.add(
+ new Thread(
+ () -> {
+ try (final SubscriptionPullConsumer consumer =
+ new SubscriptionPullConsumer.Builder()
+ .host(host)
+ .port(port)
+ .consumerId("c1")
+ .consumerGroupId("cg1")
+ .autoCommit(false)
+ .buildPullConsumer();
+ final ISession session = receiverEnv.getSessionConnection()) {
+ consumer.open();
+ consumer.subscribe(topicName);
+ topicSubscribed.set(true);
+ while (!result.get()) {
+ LockSupport.parkNanos(IoTDBSubscriptionITConstant.SLEEP_NS); // wait some time
+ if (dataPrepared.get()) {
+ final List messages =
+ consumer.poll(IoTDBSubscriptionITConstant.POLL_TIMEOUT_MS);
+ for (final SubscriptionMessage message : messages) {
+ for (final Iterator it =
+ message.getSessionDataSetsHandler().tabletIterator();
+ it.hasNext(); ) {
+ final Tablet tablet = it.next();
+ session.insertTablet(tablet);
+ }
+ }
+ consumer.commitSync(messages);
+ }
+ }
+ consumer.unsubscribe(topicName);
+ } catch (final Exception e) {
+ e.printStackTrace();
+ // Avoid failure
+ } finally {
+ LOGGER.info("consumer exiting...");
+ }
+ },
+ String.format("%s - consumer", testName.getMethodName())));
+
+ // Insert some realtime data on sender
+ threads.add(
+ new Thread(
+ () -> {
+ while (!topicSubscribed.get()) {
+ LockSupport.parkNanos(IoTDBSubscriptionITConstant.SLEEP_NS); // wait some time
+ }
+ try (final ISession session = senderEnv.getSessionConnection()) {
+ session.executeNonQueryStatement(
+ "insert into root.db.d1 (time, at1, at2) values (1001, 1, 2), (2001, 3, 4)");
+ session.executeNonQueryStatement(
+ "insert into root.db1.d1 (time, at1, at2) values (1001, 1, 2), (2001, 3, 4)");
+ session.executeNonQueryStatement(
+ "insert into root.db.d1 (time, at1, at2) values (3001, 1, 2), (4001, 3, 4)");
+ session.executeNonQueryStatement("flush");
+ } catch (final Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ dataPrepared.set(true);
+ },
+ String.format("%s - data inserter", testName.getMethodName())));
+
+ for (final Thread thread : threads) {
+ thread.start();
+ }
+
+ try (final Connection connection = receiverEnv.getConnection();
+ final Statement statement = connection.createStatement()) {
+ // Keep retrying if there are execution failures
+ AWAIT.untilAsserted(
+ () ->
+ TestUtils.assertSingleResultSetEqual(
+ TestUtils.executeQueryWithRetry(
+ statement,
+ "select count(at1) from root.db.d1 where time >= 1500 and time <= 2500"),
+ new HashMap() {
+ {
+ put("count(root.db.d1.at1)", "2");
+ }
+ }));
+ }
+
+ result.set(true);
+ for (final Thread thread : threads) {
+ thread.join();
+ }
}
private void testTopicInvalidRuntimeConfigTemplate(
@@ -600,7 +841,8 @@ private void testTopicInvalidRuntimeConfigTemplate(
} finally {
LOGGER.info("consumer exiting...");
}
- }));
+ },
+ String.format("%s - consumer", testName.getMethodName())));
// Insert some realtime data on sender
threads.add(
@@ -628,18 +870,15 @@ private void testTopicInvalidRuntimeConfigTemplate(
fail(e.getMessage());
}
dataPrepared.set(true);
- }));
+ },
+ String.format("%s - data inserter", testName.getMethodName())));
for (final Thread thread : threads) {
thread.start();
}
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- // The expected SubscriptionRuntimeCriticalException was not thrown if result is false
- .untilTrue(result);
+ // The expected SubscriptionRuntimeCriticalException was not thrown if result is false
+ AWAIT.untilTrue(result);
for (final Thread thread : threads) {
thread.join();
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/AbstractSubscriptionLocalIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/AbstractSubscriptionLocalIT.java
new file mode 100644
index 0000000000000..bb248f745d4ed
--- /dev/null
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/AbstractSubscriptionLocalIT.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.subscription.it.local;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.subscription.it.AbstractSubscriptionIT;
+
+import org.junit.After;
+import org.junit.Before;
+
+abstract class AbstractSubscriptionLocalIT extends AbstractSubscriptionIT {
+
+ @Override
+ @Before
+ public void setUp() {
+ super.setUp();
+
+ EnvFactory.getEnv().initClusterEnvironment();
+ }
+
+ @Override
+ @After
+ public void tearDown() {
+ super.tearDown();
+
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+}
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionBasicIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionBasicIT.java
index 13a5e8abc2617..e9c97c0689672 100644
--- a/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionBasicIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionBasicIT.java
@@ -36,14 +36,16 @@
import org.apache.iotdb.session.subscription.payload.SubscriptionTsFileHandler;
import org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.read.TsFileReader;
import org.apache.tsfile.read.common.Path;
+import org.apache.tsfile.read.common.RowRecord;
import org.apache.tsfile.read.expression.QueryExpression;
import org.apache.tsfile.read.query.dataset.QueryDataSet;
-import org.awaitility.Awaitility;
-import org.junit.After;
+import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.write.record.Tablet;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
@@ -53,42 +55,87 @@
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.time.Duration;
+import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;
import java.util.stream.Collectors;
+import static org.apache.iotdb.subscription.it.IoTDBSubscriptionITConstant.AWAIT;
import static org.junit.Assert.fail;
@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class})
-public class IoTDBSubscriptionBasicIT {
+public class IoTDBSubscriptionBasicIT extends AbstractSubscriptionLocalIT {
private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBSubscriptionBasicIT.class);
- @Before
- public void setUp() throws Exception {
- EnvFactory.getEnv().initClusterEnvironment();
+ @Test
+ public void testSubscribeBooleanData() throws Exception {
+ testBasicSubscribeTablets(TSDataType.BOOLEAN, "true", true);
+ }
+
+ @Test
+ public void testSubscribeIntData() throws Exception {
+ testBasicSubscribeTablets(TSDataType.INT32, "1", 1);
+ }
+
+ @Test
+ public void testSubscribeLongData() throws Exception {
+ testBasicSubscribeTablets(TSDataType.INT64, "1", 1L);
+ }
+
+ @Test
+ public void testSubscribeFloatData() throws Exception {
+ testBasicSubscribeTablets(TSDataType.FLOAT, "1.0", 1.0F);
+ }
+
+ @Test
+ public void testSubscribeDoubleData() throws Exception {
+ testBasicSubscribeTablets(TSDataType.DOUBLE, "1.0", 1.0);
+ }
+
+ @Test
+ public void testSubscribeTextData() throws Exception {
+ testBasicSubscribeTablets(TSDataType.TEXT, "'a'", new Binary("a", TSFileConfig.STRING_CHARSET));
+ }
+
+ @Test
+ public void testSubscribeTimestampData() throws Exception {
+ testBasicSubscribeTablets(TSDataType.TIMESTAMP, "123", 123L);
}
- @After
- public void tearDown() throws Exception {
- EnvFactory.getEnv().cleanClusterEnvironment();
+ @Test
+ public void testSubscribeDateData() throws Exception {
+ testBasicSubscribeTablets(TSDataType.DATE, "'2011-03-01'", LocalDate.of(2011, 3, 1));
+ }
+
+ @Test
+ public void testSubscribeBlobData() throws Exception {
+ testBasicSubscribeTablets(
+ TSDataType.BLOB, "X'f013'", new Binary(new byte[] {(byte) 0xf0, 0x13}));
}
@Test
- public void testBasicSubscribeTablets() throws Exception {
+ public void testSubscribeStringData() throws Exception {
+ testBasicSubscribeTablets(
+ TSDataType.STRING, "'a'", new Binary("a", TSFileConfig.STRING_CHARSET));
+ }
+
+ private void testBasicSubscribeTablets(
+ final TSDataType type, final String valueStr, final Object expectedData) throws Exception {
// Insert some historical data
try (final ISession session = EnvFactory.getEnv().getSessionConnection()) {
+ session.executeNonQueryStatement(
+ String.format("create timeseries root.db.d1.s1 %s", type.toString()));
for (int i = 0; i < 100; ++i) {
session.executeNonQueryStatement(
- String.format("insert into root.db.d1(time, s1) values (%s, 1)", i));
+ String.format("insert into root.db.d1(time, s1) values (%s, %s)", i, valueStr));
}
session.executeNonQueryStatement("flush");
} catch (final Exception e) {
@@ -132,7 +179,12 @@ public void testBasicSubscribeTablets() throws Exception {
for (final SubscriptionSessionDataSet dataSet :
message.getSessionDataSetsHandler()) {
while (dataSet.hasNext()) {
- dataSet.next();
+ final RowRecord record = dataSet.next();
+ Assert.assertEquals(type.toString(), dataSet.getColumnTypes().get(1));
+ Assert.assertEquals(type, record.getFields().get(0).getDataType());
+ Assert.assertEquals(expectedData, getValue(type, dataSet.getTablet()));
+ Assert.assertEquals(
+ expectedData, record.getFields().get(0).getObjectValue(type));
rowCount.addAndGet(1);
}
}
@@ -146,18 +198,14 @@ public void testBasicSubscribeTablets() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check row count
try {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(() -> Assert.assertEquals(100, rowCount.get()));
+ AWAIT.untilAsserted(() -> Assert.assertEquals(100, rowCount.get()));
} catch (final Exception e) {
e.printStackTrace();
fail(e.getMessage());
@@ -167,6 +215,30 @@ public void testBasicSubscribeTablets() throws Exception {
}
}
+ private Object getValue(final TSDataType type, final Tablet tablet) {
+ switch (type) {
+ case BOOLEAN:
+ return ((boolean[]) tablet.values[0])[0];
+ case INT32:
+ return ((int[]) tablet.values[0])[0];
+ case INT64:
+ case TIMESTAMP:
+ return ((long[]) tablet.values[0])[0];
+ case FLOAT:
+ return ((float[]) tablet.values[0])[0];
+ case DOUBLE:
+ return ((double[]) tablet.values[0])[0];
+ case TEXT:
+ case BLOB:
+ case STRING:
+ return ((Binary[]) tablet.values[0])[0];
+ case DATE:
+ return ((LocalDate[]) tablet.values[0])[0];
+ default:
+ return null;
+ }
+ }
+
@Test
public void testBasicSubscribeTsFile() throws Exception {
// Insert some historical data
@@ -242,18 +314,14 @@ public void testBasicSubscribeTsFile() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check row count
try {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(() -> Assert.assertEquals(100, rowCount.get()));
+ AWAIT.untilAsserted(() -> Assert.assertEquals(100, rowCount.get()));
} catch (final Exception e) {
e.printStackTrace();
fail(e.getMessage());
@@ -379,18 +447,14 @@ public void onFailure(final Throwable e) {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check row count
try {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(() -> Assert.assertEquals(100, rowCount.get()));
+ AWAIT.untilAsserted(() -> Assert.assertEquals(100, rowCount.get()));
Assert.assertTrue(commitSuccessCount.get() > lastCommitSuccessCount.get());
Assert.assertEquals(0, commitFailureCount.get());
} catch (final Exception e) {
@@ -416,12 +480,7 @@ public void onFailure(final Throwable e) {
// Check row count
try {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(() -> Assert.assertEquals(200, rowCount.get()));
+ AWAIT.untilAsserted(() -> Assert.assertEquals(200, rowCount.get()));
Assert.assertTrue(commitSuccessCount.get() > lastCommitSuccessCount.get());
Assert.assertEquals(0, commitFailureCount.get());
} catch (final Exception e) {
@@ -486,16 +545,11 @@ public void testBasicPushConsumer() {
consumer.subscribe(topicName);
// The push consumer should automatically poll 10 rows of data by 1 onReceive()
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () -> {
- Assert.assertEquals(10, rowCount.get());
- Assert.assertTrue(onReceiveCount.get() > lastOnReceiveCount.get());
- });
+ AWAIT.untilAsserted(
+ () -> {
+ Assert.assertEquals(10, rowCount.get());
+ Assert.assertTrue(onReceiveCount.get() > lastOnReceiveCount.get());
+ });
lastOnReceiveCount.set(onReceiveCount.get());
@@ -508,16 +562,11 @@ public void testBasicPushConsumer() {
session.executeNonQueryStatement("flush");
}
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () -> {
- Assert.assertEquals(20, rowCount.get());
- Assert.assertTrue(onReceiveCount.get() > lastOnReceiveCount.get());
- });
+ AWAIT.untilAsserted(
+ () -> {
+ Assert.assertEquals(20, rowCount.get());
+ Assert.assertTrue(onReceiveCount.get() > lastOnReceiveCount.get());
+ });
lastOnReceiveCount.set(onReceiveCount.get());
@@ -529,16 +578,11 @@ public void testBasicPushConsumer() {
session.executeNonQueryStatement("flush");
}
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () -> {
- Assert.assertEquals(30, rowCount.get());
- Assert.assertTrue(onReceiveCount.get() > lastOnReceiveCount.get());
- });
+ AWAIT.untilAsserted(
+ () -> {
+ Assert.assertEquals(30, rowCount.get());
+ Assert.assertTrue(onReceiveCount.get() > lastOnReceiveCount.get());
+ });
consumer.unsubscribe(topicName);
} catch (final Exception e) {
@@ -624,22 +668,18 @@ public void testPollUnsubscribedTopics() throws Exception {
} finally {
LOGGER.info("consumer exiting...");
}
- });
+ },
+ String.format("%s - consumer", testName.getMethodName()));
thread.start();
// Check row count
try {
// Keep retrying if there are execution failures
- Awaitility.await()
- .pollDelay(IoTDBSubscriptionITConstant.AWAITILITY_POLL_DELAY_SECOND, TimeUnit.SECONDS)
- .pollInterval(
- IoTDBSubscriptionITConstant.AWAITILITY_POLL_INTERVAL_SECOND, TimeUnit.SECONDS)
- .atMost(IoTDBSubscriptionITConstant.AWAITILITY_AT_MOST_SECOND, TimeUnit.SECONDS)
- .untilAsserted(
- () -> {
- Assert.assertEquals(100, rowCount.get());
- Assert.assertEquals((100 + 199) * 100 / 2, timestampSum.get());
- });
+ AWAIT.untilAsserted(
+ () -> {
+ Assert.assertEquals(100, rowCount.get());
+ Assert.assertEquals((100 + 199) * 100 / 2, timestampSum.get());
+ });
} catch (final Exception e) {
e.printStackTrace();
fail(e.getMessage());
diff --git a/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionIdempotentIT.java b/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionIdempotentIT.java
index b671acd6709f4..85fff437f18e6 100644
--- a/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionIdempotentIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/subscription/it/local/IoTDBSubscriptionIdempotentIT.java
@@ -25,9 +25,7 @@
import org.apache.iotdb.session.subscription.SubscriptionSession;
import org.apache.iotdb.session.subscription.consumer.SubscriptionPullConsumer;
-import org.junit.After;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
@@ -38,20 +36,10 @@
@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class})
-public class IoTDBSubscriptionIdempotentIT {
+public class IoTDBSubscriptionIdempotentIT extends AbstractSubscriptionLocalIT {
private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBSubscriptionIdempotentIT.class);
- @Before
- public void setUp() throws Exception {
- EnvFactory.getEnv().initClusterEnvironment();
- }
-
- @After
- public void tearDown() throws Exception {
- EnvFactory.getEnv().cleanClusterEnvironment();
- }
-
@Test
public void testSubscribeOrUnsubscribeNonExistedTopicTest() {
final String host = EnvFactory.getEnv().getIP();
diff --git a/integration-test/src/test/java/org/apache/iotdb/tools/it/ExportTsFileTestIT.java b/integration-test/src/test/java/org/apache/iotdb/tools/it/ExportTsFileTestIT.java
index 71a3d62a382ab..5994d4d554eea 100644
--- a/integration-test/src/test/java/org/apache/iotdb/tools/it/ExportTsFileTestIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/tools/it/ExportTsFileTestIT.java
@@ -90,7 +90,7 @@ protected void testOnWindows() throws IOException {
"root",
"-pw",
"root",
- "-td",
+ "-t",
"target",
"-q",
"select * from root.test.t2 where time > 1 and time < 1000000000000",
@@ -116,7 +116,7 @@ protected void testOnWindows() throws IOException {
"root",
"-pw",
"root",
- "-td",
+ "-t",
"target",
"-q",
"select * from root.test.t2 where time > 1 and time < 1000000000000",
@@ -143,7 +143,7 @@ protected void testOnUnix() throws IOException {
"root",
"-pw",
"root",
- "-td",
+ "-t",
"target",
"-q",
"select * from root.**");
@@ -166,7 +166,7 @@ protected void testOnUnix() throws IOException {
"root",
"-pw",
"root",
- "-td",
+ "-t",
"target",
"-q",
"select * from root.**");
diff --git a/integration-test/src/test/java/org/apache/iotdb/util/AbstractSchemaIT.java b/integration-test/src/test/java/org/apache/iotdb/util/AbstractSchemaIT.java
index deefd0cccc90e..1c3f3708ae374 100644
--- a/integration-test/src/test/java/org/apache/iotdb/util/AbstractSchemaIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/util/AbstractSchemaIT.java
@@ -100,6 +100,14 @@ protected static void clearSchema() throws Exception {
"DROP DEVICE TEMPLATE " + resultSet.getString(ColumnHeaderConstant.TEMPLATE_NAME));
}
}
+ // drop all users
+ try (ResultSet resultSet = statement.executeQuery("LIST USER")) {
+ while (resultSet.next()) {
+ if (!resultSet.getString(ColumnHeaderConstant.USER).equals("root")) {
+ statement.execute("DROP USER " + resultSet.getString(ColumnHeaderConstant.USER));
+ }
+ }
+ }
}
}
diff --git a/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/access/Row.java b/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/access/Row.java
index b3c1342347da1..f22ac5e026dc6 100644
--- a/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/access/Row.java
+++ b/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/access/Row.java
@@ -25,6 +25,7 @@
import org.apache.tsfile.read.common.Path;
+import java.time.LocalDate;
import java.util.List;
public interface Row {
@@ -44,17 +45,28 @@ public interface Row {
* @param columnIndex index of the specified column
* @return the int value at the specified column in this row
*/
- int getInt(int columnIndex);
+ int getInt(final int columnIndex);
+
+ /**
+ * Returns the localDate value at the specified column in this row.
+ *
+ *
Users need to ensure that the data type of the specified column is {@code Type.DATE}.
+ *
+ * @param columnIndex index of the specified column
+ * @return the int value at the specified column in this row
+ */
+ LocalDate getDate(final int columnIndex);
/**
* Returns the long value at the specified column in this row.
*
- *
Users need to ensure that the data type of the specified column is {@code Type.INT64}.
+ *
Users need to ensure that the data type of the specified column is {@code Type.INT64} or
+ * {@code Type.TIMESTAMP}.
*
* @param columnIndex index of the specified column
* @return the long value at the specified column in this row
*/
- long getLong(int columnIndex);
+ long getLong(final int columnIndex);
/**
* Returns the float value at the specified column in this row.
@@ -64,7 +76,7 @@ public interface Row {
* @param columnIndex index of the specified column
* @return the float value at the specified column in this row
*/
- float getFloat(int columnIndex);
+ float getFloat(final int columnIndex);
/**
* Returns the double value at the specified column in this row.
@@ -74,7 +86,7 @@ public interface Row {
* @param columnIndex index of the specified column
* @return the double value at the specified column in this row
*/
- double getDouble(int columnIndex);
+ double getDouble(final int columnIndex);
/**
* Returns the boolean value at the specified column in this row.
@@ -84,35 +96,37 @@ public interface Row {
* @param columnIndex index of the specified column
* @return the boolean value at the specified column in this row
*/
- boolean getBoolean(int columnIndex);
+ boolean getBoolean(final int columnIndex);
/**
* Returns the Binary value at the specified column in this row.
*
- *
Users need to ensure that the data type of the specified column is {@code Type.TEXT}.
+ *
Users need to ensure that the data type of the specified column is {@code Type.TEXT}, {@code
+ * Type.BLOB} or {@code Type.STRING}.
*
* @param columnIndex index of the specified column
* @return the Binary value at the specified column in this row
*/
- Binary getBinary(int columnIndex);
+ Binary getBinary(final int columnIndex);
/**
* Returns the String value at the specified column in this row.
*
- *
Users need to ensure that the data type of the specified column is {@code Type.TEXT}.
+ *
Users need to ensure that the data type of the specified column is {@code Type.TEXT} or
+ * {@code Type.STRING}.
*
* @param columnIndex index of the specified column
* @return the String value at the specified column in this row
*/
- String getString(int columnIndex);
+ String getString(final int columnIndex);
/**
- * Returns the Object value at the specified column in this row.
+ * Returns the raw Object stored at the specified column in this row.
*
* @param columnIndex index of the specified column
* @return the Object value at the specified column in this row
*/
- Object getObject(int columnIndex);
+ Object getObject(final int columnIndex);
/**
* Returns the actual data type of the value at the specified column in this row.
@@ -120,7 +134,7 @@ public interface Row {
* @param columnIndex index of the specified column
* @return the actual data type of the value at the specified column in this row
*/
- Type getDataType(int columnIndex);
+ Type getDataType(final int columnIndex);
/**
* Returns {@code true} if the value of the specified column is null.
@@ -128,7 +142,7 @@ public interface Row {
* @param columnIndex index of the specified column
* @return {@code true} if the value of the specified column is null
*/
- boolean isNull(int columnIndex);
+ boolean isNull(final int columnIndex);
/**
* Returns the number of columns (excluding the timestamp column).
@@ -144,7 +158,7 @@ public interface Row {
* @return the actual column index of the given column name
* @throws PipeParameterNotValidException if the given column name is not existed in the Row
*/
- int getColumnIndex(Path columnName) throws PipeParameterNotValidException;
+ int getColumnIndex(final Path columnName) throws PipeParameterNotValidException;
/**
* Returns the actual column (measurement) name of the given column index.
@@ -152,7 +166,7 @@ public interface Row {
* @param columnIndex the column index
* @return the actual column (measurement) name of the given column index
*/
- String getColumnName(int columnIndex);
+ String getColumnName(final int columnIndex);
/**
* Returns the column data types in the Row.
diff --git a/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/type/Type.java b/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/type/Type.java
index 85a4390eae46e..9093133631a0e 100644
--- a/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/type/Type.java
+++ b/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/type/Type.java
@@ -36,7 +36,20 @@ public enum Type {
DOUBLE((byte) 4),
/* TEXT */
- TEXT((byte) 5);
+ TEXT((byte) 5),
+
+ /* TsDataType.Vector and TsDataType.UNKNOWN are inner types of TsFile-module, which should not be supported in UDF APIs. To be consistent with TsDataType, the next value starts with 8 */
+ /* TIMESTAMP */
+ TIMESTAMP((byte) 8),
+
+ /* DATE */
+ DATE((byte) 9),
+
+ /* BLOB */
+ BLOB((byte) 10),
+
+ /* STRING */
+ STRING((byte) 11);
private final byte dataType;
diff --git a/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/utils/RowImpl.java b/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/utils/RowImpl.java
index d7d3a88486902..533ab9574df6d 100644
--- a/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/utils/RowImpl.java
+++ b/iotdb-api/udf-api/src/main/java/org/apache/iotdb/udf/api/utils/RowImpl.java
@@ -142,6 +142,14 @@ private static Type transformToUDFDataType(TSDataType tsDataType) {
return Type.DOUBLE;
case 5:
return Type.TEXT;
+ case 8:
+ return Type.TIMESTAMP;
+ case 9:
+ return Type.DATE;
+ case 10:
+ return Type.BLOB;
+ case 11:
+ return Type.STRING;
default:
throw new IllegalArgumentException("Invalid input: " + type);
}
diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/AbstractTsFileTool.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/AbstractTsFileTool.java
index 4a4ee1dbb11fc..fe8691ddf8b65 100644
--- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/AbstractTsFileTool.java
+++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/AbstractTsFileTool.java
@@ -42,8 +42,8 @@ public abstract class AbstractTsFileTool {
protected static final String USERNAME_ARGS = "u";
protected static final String USERNAME_NAME = "username";
- protected static final String TIMEOUT_ARGS = "t";
- protected static final String TIMEOUT_NAME = "timeout";
+ protected static final String TIMEOUT_ARGS = "timeout";
+ protected static final String TIMEOUT_NAME = "queryTimeout";
protected static final int MAX_HELP_CONSOLE_WIDTH = 92;
protected static final int CODE_OK = 0;
protected static final int CODE_ERROR = 1;
@@ -109,7 +109,7 @@ protected static void createBaseOptions() {
.longOpt(HOST_NAME)
.argName(HOST_NAME)
.hasArg()
- .desc("Host Name")
+ .desc("Host Name (optional)")
.build();
options.addOption(opHost);
@@ -118,7 +118,7 @@ protected static void createBaseOptions() {
.longOpt(PORT_NAME)
.argName(PORT_NAME)
.hasArg()
- .desc("Port")
+ .desc("Port (optional)")
.build();
options.addOption(opPort);
@@ -127,7 +127,7 @@ protected static void createBaseOptions() {
.longOpt(USERNAME_NAME)
.argName(USERNAME_NAME)
.hasArg()
- .desc("Username")
+ .desc("Username (optional)")
.build();
options.addOption(opUsername);
@@ -137,7 +137,7 @@ protected static void createBaseOptions() {
.optionalArg(true)
.argName(PW_NAME)
.hasArg()
- .desc("Password")
+ .desc("Password (optional)")
.build();
options.addOption(opPassword);
}
diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/ExportTsFile.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/ExportTsFile.java
index 3f89ec69c5296..9ab3d6b3ec65b 100644
--- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/ExportTsFile.java
+++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/ExportTsFile.java
@@ -62,13 +62,13 @@
public class ExportTsFile extends AbstractTsFileTool {
- private static final String TARGET_DIR_ARGS = "td";
+ private static final String TARGET_DIR_ARGS = "t";
private static final String TARGET_DIR_NAME = "targetDirectory";
- private static final String TARGET_FILE_ARGS = "f";
- private static final String TARGET_FILE_NAME = "targetFile";
+ private static final String TARGET_FILE_ARGS = "tfn";
+ private static final String TARGET_FILE_NAME = "targetFileName";
private static final String SQL_FILE_ARGS = "s";
- private static final String SQL_FILE_NAME = "sqlfile";
+ private static final String SQL_FILE_NAME = "sourceSqlFile";
private static final String QUERY_COMMAND_ARGS = "q";
private static final String QUERY_COMMAND_NAME = "queryCommand";
private static final String DUMP_FILE_NAME_DEFAULT = "dump";
@@ -266,7 +266,7 @@ private static void createOptions() {
Option opTimeout =
Option.builder(TIMEOUT_ARGS)
- .longOpt(TIMEOUT_NAME)
+ .argName(TIMEOUT_NAME)
.hasArg()
.desc("Timeout for session query")
.build();
diff --git a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/ImportTsFile.java b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/ImportTsFile.java
index 4e74dbe5f594e..320b03334df59 100644
--- a/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/ImportTsFile.java
+++ b/iotdb-client/cli/src/main/java/org/apache/iotdb/tool/ImportTsFile.java
@@ -310,7 +310,9 @@ public static int importFromTargetPath() {
}
sessionPool =
- new SessionPool(host, Integer.parseInt(port), username, password, threadNum + 1);
+ new SessionPool(
+ host, Integer.parseInt(port), username, password, threadNum + 1, false, false);
+ sessionPool.setEnableQueryRedirection(false);
traverseAndCollectFiles(file);
addNoResourceOrModsToQueue();
diff --git a/iotdb-client/client-cpp/README.md b/iotdb-client/client-cpp/README.md
index deb6ea4e428bc..81983e06e2e4d 100644
--- a/iotdb-client/client-cpp/README.md
+++ b/iotdb-client/client-cpp/README.md
@@ -20,46 +20,79 @@
-->
# Building C++ Client
-To compile cpp client, add "-P with-cpp" option to maven build command.
-
-The compiling requires the module "compile-tools" to be built first.
-For more information, please refer to "compile-tools/README.md".
-
-Explicitly using mvnw here as the build requires maven 3.9 and the default installation is older
-
## Compile and Test:
### Compile
-`mvn clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests`
-### Test
-First build IoTDB server
-
-Explicitly using "install" instead of package in order to be sure we're using libs built on this machine
+#### Unix
+To compile the cpp client, use the following command:
+`mvn clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests`
-`mvn clean install -P with-cpp -pl distribution,iotdb-client/client-cpp -am -DskipTests`
+#### Windows
+To compile on Windows, please install Boost first and add following Maven
+settings:
+```
+-Dboost.include.dir=${your boost header folder} -Dboost.library.dir=${your boost lib (stage) folder}`
+```
-After run verify
+The thrift dependency that the cpp client uses is incompatible with MinGW, please use Visual
+Studio. It is highly recommended to use Visual Studio 2022 or later.
-`mvn clean verify -P with-cpp -pl iotdb-client/client-cpp -am`
+##### Visual Studio 2022
+If you are using Visual Studio 2022, you can compile the cpp client with the following command:
-To compile on Windows, please install Boost first and add following Maven settings:
```
--Dboost.include.dir=${your boost header folder} -Dboost.library.dir=${your boost lib (stage) folder}`
+mvn clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTest
+-D"boost.include.dir"="D:\boost_1_75_0" -D"boost.library.dir"="D:\boost_1_75_0\stage\lib"
```
-e.g.,
+#### Visual Studio 2019 or older
+If you are using Visual Studio 2019 or older, the pre-built Thrift library is incompatible. You
+will have to compile the thrift library manually:
+
+1. Install the dependencies of Thrift:
+* flex http://gnuwin32.sourceforge.net/packages/flex.htm
+* bison http://gnuwin32.sourceforge.net/packages/bison.htm
+* openssl https://slproweb.com/products/Win32OpenSSL.html
+
+2. Clone the repository: https://github.com/apache/iotdb-bin-resources.
+
+3. Enter the "iotdb-tools-thrift" folder in the cloned repository; use the following command to
+ compile the thrift library:
+
+`mvn install`
+
+4. If you encounter a problem like "cannot find 'unistd.h'", please open the file
+"iotdb-bin-resources\iotdb-tools-thrift\target\build\compiler\cpp\thrift\thriftl.cc" and replace
+"#include " with "#include " and "#include "; then, rerun the command
+ in the third step;
+
+5. Return to the cpp client repository and compile it with:
+
```
mvn clean package -P with-cpp -pl iotdb-client/client-cpp -am -DskipTest
-D"boost.include.dir"="D:\boost_1_75_0" -D"boost.library.dir"="D:\boost_1_75_0\stage\lib"
```
-##
+
+### Test
+First build IoTDB server together with the cpp client.
+
+Explicitly using "install" instead of package in order to be sure we're using libs built on this
+machine.
+
+`mvn clean install -P with-cpp -pl distribution,iotdb-client/client-cpp -am -DskipTests`
+
+After run verify
+
+`mvn clean verify -P with-cpp -pl iotdb-client/client-cpp -am`
+
+## Package Hierarchy
If the compilation finishes successfully, the packaged zip file will be placed under
"client-cpp/target/client-cpp-${project.version}-cpp-${os}.zip".
-On Mac machines, the hierarchy of the package should look like this:
+On macOS, the hierarchy of the package should look like this:
```
.
+-- client
@@ -71,17 +104,22 @@ On Mac machines, the hierarchy of the package should look like this:
| +-- thrift
| +-- thrift_headers...
| +-- lib
-| +-- libiotdb_session.dylib
+| +-- Release
+| +-- libiotdb_session.dylib
+| +-- parser.dylib
+| +-- thriftmd.dylib
+| +-- tutorialgencpp.dylib
```
## Using C++ Client:
```
-1. Put the zip file "client-cpp-${project.version}-cpp-${os}.zip" wherever you want
+1. Put the zip file "client-cpp-${project.version}-cpp-${os}.zip" wherever you want;
-2. Unzip the archive using the following command, and then you can get the two directories mentioned above, the header file and the dynamic library
+2. Unzip the archive using the following command, and then you can get the two directories
+mentioned above, the header file and the dynamic library:
unzip client-cpp-${project.version}-cpp-${os}.zip
-3. Write C++ code to call the operation interface of cpp-client to operate IOTDB,
+3. Write C++ code to call the operation interface of the cpp client to operate IoTDB,
for detail interface information, please refer to the link: https://iotdb.apache.org/zh/UserGuide/Master/API/Programming-Cpp-Native-API.html
E.g:
diff --git a/iotdb-client/client-cpp/src/assembly/client-cpp.xml b/iotdb-client/client-cpp/src/assembly/client-cpp.xml
index 9de99eae649a9..729fdadde235a 100644
--- a/iotdb-client/client-cpp/src/assembly/client-cpp.xml
+++ b/iotdb-client/client-cpp/src/assembly/client-cpp.xml
@@ -33,13 +33,19 @@
include
- ${project.basedir}/../compile-tools/thrift/target/thrift-${thrift.version}/lib/cpp/src
+ ${project.build.directory}/thrift/include
- **/*.h
- **/*.tcc
+ **include
+
+ ${project.build.directory}/thrift/lib
+
+ **
+
+ lib
+ ${project.build.directory}/build/main
diff --git a/iotdb-client/client-py/iotdb/utils/IoTDBRpcDataSet.py b/iotdb-client/client-py/iotdb/utils/IoTDBRpcDataSet.py
index 53ef09b8e7aa3..eb859d7d30c1d 100644
--- a/iotdb-client/client-py/iotdb/utils/IoTDBRpcDataSet.py
+++ b/iotdb-client/client-py/iotdb/utils/IoTDBRpcDataSet.py
@@ -151,7 +151,7 @@ def construct_one_data_frame(self):
self.__query_data_set.time, np.dtype(np.longlong).newbyteorder(">")
)
if time_array.dtype.byteorder == ">":
- time_array = time_array.byteswap().newbyteorder("<")
+ time_array = time_array.byteswap().view(time_array.dtype.newbyteorder("<"))
result[0] = time_array
total_length = len(time_array)
for i in range(self.column_size):
@@ -205,7 +205,9 @@ def construct_one_data_frame(self):
else:
raise RuntimeError("unsupported data type {}.".format(data_type))
if data_array.dtype.byteorder == ">":
- data_array = data_array.byteswap().newbyteorder("<")
+ data_array = data_array.byteswap().view(
+ data_array.dtype.newbyteorder("<")
+ )
# self.__query_data_set.valueList[location] = None
if len(data_array) < total_length:
# INT32 or INT64 or boolean
@@ -258,7 +260,9 @@ def resultset_to_pandas(self):
self.__query_data_set.time, np.dtype(np.longlong).newbyteorder(">")
)
if time_array.dtype.byteorder == ">":
- time_array = time_array.byteswap().newbyteorder("<")
+ time_array = time_array.byteswap().view(
+ time_array.dtype.newbyteorder("<")
+ )
if self.ignore_timestamp is None or self.ignore_timestamp is False:
result[IoTDBRpcDataSet.TIMESTAMP_STR].append(time_array)
@@ -317,7 +321,9 @@ def resultset_to_pandas(self):
else:
raise RuntimeError("unsupported data type {}.".format(data_type))
if data_array.dtype.byteorder == ">":
- data_array = data_array.byteswap().newbyteorder("<")
+ data_array = data_array.byteswap().view(
+ data_array.dtype.newbyteorder("<")
+ )
self.__query_data_set.valueList[location] = None
tmp_array = []
if len(data_array) < total_length:
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcUtils.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcUtils.java
index 9b29f052f28b2..e48054abb1974 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcUtils.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/RpcUtils.java
@@ -146,18 +146,20 @@ public static TSStatus getStatus(TSStatusCode tsStatusCode) {
public static TSStatus getStatus(List statusList) {
TSStatus status = new TSStatus(TSStatusCode.MULTIPLE_ERROR.getStatusCode());
status.setSubStatus(statusList);
- StringBuilder errMsg = new StringBuilder().append("Multiple error occur, messages: ");
- Set msgSet = new HashSet<>();
- for (TSStatus subStatus : statusList) {
- if (subStatus.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()
- && subStatus.getCode() != TSStatusCode.REDIRECTION_RECOMMEND.getStatusCode()) {
- if (!msgSet.contains(status.getMessage())) {
- errMsg.append(status.getMessage()).append("; ");
- msgSet.add(status.getMessage());
+ if (LOGGER.isDebugEnabled()) {
+ StringBuilder errMsg = new StringBuilder().append("Multiple error occur, messages: ");
+ Set msgSet = new HashSet<>();
+ for (TSStatus subStatus : statusList) {
+ if (subStatus.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()
+ && subStatus.getCode() != TSStatusCode.REDIRECTION_RECOMMEND.getStatusCode()) {
+ if (!msgSet.contains(status)) {
+ errMsg.append(status).append("; ");
+ msgSet.add(status);
+ }
}
}
+ LOGGER.debug(errMsg.toString(), new Exception(errMsg.toString()));
}
- LOGGER.warn(errMsg.toString());
return status;
}
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
index 2324dbbd575f2..e57365b33ea46 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
@@ -166,6 +166,7 @@ public enum TSStatusCode {
CAN_NOT_CONNECT_DATANODE(1007),
TRANSFER_LEADER_ERROR(1008),
GET_CLUSTER_ID_ERROR(1009),
+ CAN_NOT_CONNECT_CONFIGNODE(1010),
// Sync, Load TsFile
LOAD_FILE_ERROR(1100),
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/config/TopicConfig.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/config/TopicConfig.java
index fe62ba622a965..6dc42ed634aea 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/config/TopicConfig.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/config/TopicConfig.java
@@ -28,7 +28,10 @@
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
public class TopicConfig extends PipeParameters {
@@ -40,6 +43,25 @@ public TopicConfig(final Map attributes) {
super(attributes);
}
+ private static final Map REALTIME_BATCH_MODE_CONFIG =
+ Collections.singletonMap("realtime.mode", "batch");
+ private static final Map REALTIME_STREAM_MODE_CONFIG =
+ Collections.singletonMap("realtime.mode", "stream");
+
+ private static final Map QUERY_MODE_CONFIG =
+ Collections.singletonMap("mode", "query");
+ private static final Map SUBSCRIBE_MODE_CONFIG =
+ Collections.singletonMap("mode", "subscribe");
+
+ private static final Set LOOSE_RANGE_KEY_SET =
+ Collections.unmodifiableSet(
+ new HashSet() {
+ {
+ add("history.loose-range");
+ add("realtime.loose-range");
+ }
+ });
+
/////////////////////////////// de/ser ///////////////////////////////
public void serialize(final DataOutputStream stream) throws IOException {
@@ -84,21 +106,29 @@ public Map getAttributesWithTimeRange(final long creationTime) {
attributesWithTimeRange.put(TopicConstant.END_TIME_KEY, endTime);
}
- // enable loose range when using tsfile format
- if (TopicConstant.FORMAT_TS_FILE_HANDLER_VALUE.equals(
- attributes.getOrDefault(TopicConstant.FORMAT_KEY, TopicConstant.FORMAT_DEFAULT_VALUE))) {
- attributesWithTimeRange.put("history.loose-range", "time");
- attributesWithTimeRange.put("realtime.loose-range", "time");
- }
-
return attributesWithTimeRange;
}
public Map getAttributesWithRealtimeMode() {
return TopicConstant.FORMAT_TS_FILE_HANDLER_VALUE.equals(
attributes.getOrDefault(TopicConstant.FORMAT_KEY, TopicConstant.FORMAT_DEFAULT_VALUE))
- ? Collections.singletonMap("realtime.mode", "batch")
- : Collections.singletonMap("realtime.mode", "hybrid");
+ ? REALTIME_BATCH_MODE_CONFIG
+ : REALTIME_STREAM_MODE_CONFIG;
+ }
+
+ public Map getAttributesWithSourceMode() {
+ return TopicConstant.MODE_QUERY_VALUE.equals(
+ attributes.getOrDefault(TopicConstant.MODE_KEY, TopicConstant.MODE_DEFAULT_VALUE))
+ ? QUERY_MODE_CONFIG
+ : SUBSCRIBE_MODE_CONFIG;
+ }
+
+ public Map getAttributesWithSourceLooseRange() {
+ final String looseRangeValue =
+ attributes.getOrDefault(
+ TopicConstant.LOOSE_RANGE_KEY, TopicConstant.LOOSE_RANGE_DEFAULT_VALUE);
+ return LOOSE_RANGE_KEY_SET.stream()
+ .collect(Collectors.toMap(key -> key, key -> looseRangeValue));
}
public Map getAttributesWithProcessorPrefix() {
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/config/TopicConstant.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/config/TopicConstant.java
index bd44cf1bcc95d..a3226c1d64063 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/config/TopicConstant.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/config/TopicConstant.java
@@ -30,11 +30,22 @@ public class TopicConstant {
public static final String END_TIME_KEY = "end-time";
public static final String NOW_TIME_VALUE = "now";
+ public static final String MODE_KEY = "mode";
+ public static final String MODE_SUBSCRIBE_VALUE = "subscribe";
+ public static final String MODE_QUERY_VALUE = "query";
+ public static final String MODE_DEFAULT_VALUE = MODE_SUBSCRIBE_VALUE;
+
public static final String FORMAT_KEY = "format";
public static final String FORMAT_SESSION_DATA_SETS_HANDLER_VALUE = "SessionDataSetsHandler";
public static final String FORMAT_TS_FILE_HANDLER_VALUE = "TsFileHandler";
public static final String FORMAT_DEFAULT_VALUE = FORMAT_SESSION_DATA_SETS_HANDLER_VALUE;
+ public static final String LOOSE_RANGE_KEY = "loose-range";
+ public static final String LOOSE_RANGE_TIME_VALUE = "time";
+ public static final String LOOSE_RANGE_PATH_VALUE = "path";
+ public static final String LOOSE_RANGE_TIME_AND_PATH_VALUE = "time,path";
+ public static final String LOOSE_RANGE_DEFAULT_VALUE = "";
+
private TopicConstant() {
throw new IllegalStateException("Utility class");
}
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/exception/SubscriptionIdentifierSemanticException.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/exception/SubscriptionIdentifierSemanticException.java
new file mode 100644
index 0000000000000..6eb9ba6d73484
--- /dev/null
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/exception/SubscriptionIdentifierSemanticException.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.rpc.subscription.exception;
+
+import java.util.Objects;
+
+public class SubscriptionIdentifierSemanticException extends SubscriptionException {
+
+ public SubscriptionIdentifierSemanticException(final String message) {
+ super(message);
+ }
+
+ public SubscriptionIdentifierSemanticException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return obj instanceof SubscriptionIdentifierSemanticException
+ && Objects.equals(
+ getMessage(), ((SubscriptionIdentifierSemanticException) obj).getMessage())
+ && Objects.equals(
+ getTimeStamp(), ((SubscriptionIdentifierSemanticException) obj).getTimeStamp());
+ }
+}
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/SubscriptionPollResponse.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/SubscriptionPollResponse.java
index d386903f124d0..01d173d274283 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/SubscriptionPollResponse.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/SubscriptionPollResponse.java
@@ -95,6 +95,9 @@ public static SubscriptionPollResponse deserialize(final ByteBuffer buffer) {
case ERROR:
payload = new ErrorPayload().deserialize(buffer);
break;
+ case TERMINATION:
+ payload = new TerminationPayload().deserialize(buffer);
+ break;
default:
LOGGER.warn("unexpected response type: {}, payload will be null", responseType);
break;
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/SubscriptionPollResponseType.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/SubscriptionPollResponseType.java
index a22c9590c65fc..b27791b36c538 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/SubscriptionPollResponseType.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/SubscriptionPollResponseType.java
@@ -31,6 +31,8 @@ public enum SubscriptionPollResponseType {
FILE_INIT((short) 2),
FILE_PIECE((short) 3),
FILE_SEAL((short) 4),
+
+ TERMINATION((short) 5),
;
private final short type;
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/task/DecoratingLock.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/TerminationPayload.java
similarity index 61%
rename from iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/task/DecoratingLock.java
rename to iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/TerminationPayload.java
index cc5d0d93e5eee..c2da3f92e6dd8 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/task/DecoratingLock.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/poll/TerminationPayload.java
@@ -17,28 +17,26 @@
* under the License.
*/
-package org.apache.iotdb.commons.pipe.task;
+package org.apache.iotdb.rpc.subscription.payload.poll;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.io.DataOutputStream;
+import java.nio.ByteBuffer;
-public class DecoratingLock {
- private final AtomicBoolean isDecorating = new AtomicBoolean(false);
+public class TerminationPayload implements SubscriptionPollPayload {
- public void waitForDecorated() {
- while (isDecorating.get()) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
+ @Override
+ public void serialize(final DataOutputStream stream) {
+ // do nothing
}
- public void markAsDecorating() {
- isDecorating.set(true);
+ @Override
+ public SubscriptionPollPayload deserialize(final ByteBuffer buffer) {
+ // do nothing
+ return null;
}
- public void markAsDecorated() {
- isDecorating.set(false);
+ @Override
+ public String toString() {
+ return "TerminationPayload";
}
}
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/response/PipeSubscribeSubscribeResp.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/response/PipeSubscribeSubscribeResp.java
index a5540150898d2..1d1571b0122ee 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/response/PipeSubscribeSubscribeResp.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/response/PipeSubscribeSubscribeResp.java
@@ -22,10 +22,25 @@
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.service.rpc.thrift.TPipeSubscribeResp;
+import org.apache.tsfile.utils.PublicBAOS;
+import org.apache.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Objects;
+import java.util.Set;
public class PipeSubscribeSubscribeResp extends TPipeSubscribeResp {
+ private transient Set topicNames = new HashSet<>(); // subscribed topic names
+
+ public Set getTopicNames() {
+ return topicNames;
+ }
+
/////////////////////////////// Thrift ///////////////////////////////
/**
@@ -34,11 +49,32 @@ public class PipeSubscribeSubscribeResp extends TPipeSubscribeResp {
*/
public static PipeSubscribeSubscribeResp toTPipeSubscribeResp(final TSStatus status) {
final PipeSubscribeSubscribeResp resp = new PipeSubscribeSubscribeResp();
+ resp.status = status;
+ resp.version = PipeSubscribeResponseVersion.VERSION_1.getVersion();
+ resp.type = PipeSubscribeResponseType.ACK.getType();
+ return resp;
+ }
+
+ /**
+ * Serialize the incoming parameters into `PipeSubscribeSubscribeResp`, called by the subscription
+ * server.
+ */
+ public static PipeSubscribeSubscribeResp toTPipeSubscribeResp(
+ final TSStatus status, final Set topicNames) throws IOException {
+ final PipeSubscribeSubscribeResp resp = new PipeSubscribeSubscribeResp();
resp.status = status;
resp.version = PipeSubscribeResponseVersion.VERSION_1.getVersion();
resp.type = PipeSubscribeResponseType.ACK.getType();
+ try (final PublicBAOS byteArrayOutputStream = new PublicBAOS();
+ final DataOutputStream outputStream = new DataOutputStream(byteArrayOutputStream)) {
+ ReadWriteIOUtils.writeObjectSet(topicNames, outputStream);
+ resp.body =
+ Collections.singletonList(
+ ByteBuffer.wrap(byteArrayOutputStream.getBuf(), 0, byteArrayOutputStream.size()));
+ }
+
return resp;
}
@@ -47,11 +83,19 @@ public static PipeSubscribeSubscribeResp fromTPipeSubscribeResp(
final TPipeSubscribeResp subscribeResp) {
final PipeSubscribeSubscribeResp resp = new PipeSubscribeSubscribeResp();
+ if (Objects.nonNull(subscribeResp.body)) {
+ for (final ByteBuffer byteBuffer : subscribeResp.body) {
+ if (Objects.nonNull(byteBuffer) && byteBuffer.hasRemaining()) {
+ resp.topicNames = ReadWriteIOUtils.readObjectSet(byteBuffer);
+ break;
+ }
+ }
+ }
+
resp.status = subscribeResp.status;
resp.version = subscribeResp.version;
resp.type = subscribeResp.type;
resp.body = subscribeResp.body;
-
return resp;
}
@@ -66,7 +110,8 @@ public boolean equals(final Object obj) {
return false;
}
final PipeSubscribeSubscribeResp that = (PipeSubscribeSubscribeResp) obj;
- return Objects.equals(this.status, that.status)
+ return Objects.equals(this.topicNames, that.topicNames)
+ && Objects.equals(this.status, that.status)
&& this.version == that.version
&& this.type == that.type
&& Objects.equals(this.body, that.body);
@@ -74,6 +119,6 @@ public boolean equals(final Object obj) {
@Override
public int hashCode() {
- return Objects.hash(status, version, type, body);
+ return Objects.hash(topicNames, status, version, type, body);
}
}
diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/response/PipeSubscribeUnsubscribeResp.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/response/PipeSubscribeUnsubscribeResp.java
index a93e38013acc6..e5d8ccf69cf4b 100644
--- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/response/PipeSubscribeUnsubscribeResp.java
+++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/subscription/payload/response/PipeSubscribeUnsubscribeResp.java
@@ -22,10 +22,25 @@
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.service.rpc.thrift.TPipeSubscribeResp;
+import org.apache.tsfile.utils.PublicBAOS;
+import org.apache.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Objects;
+import java.util.Set;
public class PipeSubscribeUnsubscribeResp extends TPipeSubscribeResp {
+ private transient Set topicNames = new HashSet<>(); // subscribed topic names
+
+ public Set getTopicNames() {
+ return topicNames;
+ }
+
/////////////////////////////// Thrift ///////////////////////////////
/**
@@ -34,11 +49,32 @@ public class PipeSubscribeUnsubscribeResp extends TPipeSubscribeResp {
*/
public static PipeSubscribeUnsubscribeResp toTPipeSubscribeResp(final TSStatus status) {
final PipeSubscribeUnsubscribeResp resp = new PipeSubscribeUnsubscribeResp();
+ resp.status = status;
+ resp.version = PipeSubscribeResponseVersion.VERSION_1.getVersion();
+ resp.type = PipeSubscribeResponseType.ACK.getType();
+ return resp;
+ }
+
+ /**
+ * Serialize the incoming parameters into `PipeSubscribeUnsubscribeResp`, called by the
+ * subscription server.
+ */
+ public static PipeSubscribeUnsubscribeResp toTPipeSubscribeResp(
+ final TSStatus status, final Set topicNames) throws IOException {
+ final PipeSubscribeUnsubscribeResp resp = new PipeSubscribeUnsubscribeResp();
resp.status = status;
resp.version = PipeSubscribeResponseVersion.VERSION_1.getVersion();
resp.type = PipeSubscribeResponseType.ACK.getType();
+ try (final PublicBAOS byteArrayOutputStream = new PublicBAOS();
+ final DataOutputStream outputStream = new DataOutputStream(byteArrayOutputStream)) {
+ ReadWriteIOUtils.writeObjectSet(topicNames, outputStream);
+ resp.body =
+ Collections.singletonList(
+ ByteBuffer.wrap(byteArrayOutputStream.getBuf(), 0, byteArrayOutputStream.size()));
+ }
+
return resp;
}
@@ -47,11 +83,19 @@ public static PipeSubscribeUnsubscribeResp fromTPipeSubscribeResp(
final TPipeSubscribeResp unsubscribeResp) {
final PipeSubscribeUnsubscribeResp resp = new PipeSubscribeUnsubscribeResp();
+ if (Objects.nonNull(unsubscribeResp.body)) {
+ for (final ByteBuffer byteBuffer : unsubscribeResp.body) {
+ if (Objects.nonNull(byteBuffer) && byteBuffer.hasRemaining()) {
+ resp.topicNames = ReadWriteIOUtils.readObjectSet(byteBuffer);
+ break;
+ }
+ }
+ }
+
resp.status = unsubscribeResp.status;
resp.version = unsubscribeResp.version;
resp.type = unsubscribeResp.type;
resp.body = unsubscribeResp.body;
-
return resp;
}
@@ -66,7 +110,8 @@ public boolean equals(final Object obj) {
return false;
}
final PipeSubscribeUnsubscribeResp that = (PipeSubscribeUnsubscribeResp) obj;
- return Objects.equals(this.status, that.status)
+ return Objects.equals(this.topicNames, that.topicNames)
+ && Objects.equals(this.status, that.status)
&& this.version == that.version
&& this.type == that.type
&& Objects.equals(this.body, that.body);
@@ -74,6 +119,6 @@ public boolean equals(final Object obj) {
@Override
public int hashCode() {
- return Objects.hash(status, version, type, body);
+ return Objects.hash(topicNames, status, version, type, body);
}
}
diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionConsumer.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionConsumer.java
index 2bbd4a129a91b..410348c991b38 100644
--- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionConsumer.java
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionConsumer.java
@@ -40,6 +40,7 @@
import org.apache.iotdb.rpc.subscription.payload.poll.SubscriptionPollResponseType;
import org.apache.iotdb.rpc.subscription.payload.poll.TabletsPayload;
import org.apache.iotdb.session.subscription.payload.SubscriptionMessage;
+import org.apache.iotdb.session.subscription.util.IdentifierUtils;
import org.apache.iotdb.session.subscription.util.RandomStringGenerator;
import org.apache.iotdb.session.subscription.util.SubscriptionPollTimer;
import org.apache.iotdb.session.util.SessionUtils;
@@ -50,8 +51,10 @@
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
+import java.net.URLEncoder;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
@@ -69,6 +72,7 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
+import java.util.stream.Collectors;
abstract class SubscriptionConsumer implements AutoCloseable {
@@ -92,6 +96,10 @@ abstract class SubscriptionConsumer implements AutoCloseable {
private final String fileSaveDir;
private final boolean fileSaveFsync;
+ protected volatile Set subscribedTopicNames = new HashSet<>();
+
+ /////////////////////////////// getter ///////////////////////////////
+
public String getConsumerId() {
return consumerId;
}
@@ -100,6 +108,14 @@ public String getConsumerGroupId() {
return consumerGroupId;
}
+ /**
+ * @return When only subscribing to the query mode topics, if there is no new data to
+ * process, return {@code false}; otherwise, return {@code true}.
+ */
+ public boolean hasMoreData() {
+ return !subscribedTopicNames.isEmpty();
+ }
+
/////////////////////////////// ctor ///////////////////////////////
protected SubscriptionConsumer(final Builder builder) {
@@ -221,6 +237,17 @@ public void subscribe(final String... topicNames) throws SubscriptionException {
}
public void subscribe(final Set topicNames) throws SubscriptionException {
+ // parse topic names from external source
+ subscribe(topicNames, true);
+ }
+
+ private void subscribe(Set topicNames, final boolean needParse)
+ throws SubscriptionException {
+ if (needParse) {
+ topicNames =
+ topicNames.stream().map(IdentifierUtils::parseIdentifier).collect(Collectors.toSet());
+ }
+
providers.acquireReadLock();
try {
subscribeWithRedirection(topicNames);
@@ -238,6 +265,17 @@ public void unsubscribe(final String... topicNames) throws SubscriptionException
}
public void unsubscribe(final Set topicNames) throws SubscriptionException {
+ // parse topic names from external source
+ unsubscribe(topicNames, true);
+ }
+
+ private void unsubscribe(Set topicNames, final boolean needParse)
+ throws SubscriptionException {
+ if (needParse) {
+ topicNames =
+ topicNames.stream().map(IdentifierUtils::parseIdentifier).collect(Collectors.toSet());
+ }
+
providers.acquireReadLock();
try {
unsubscribeWithRedirection(topicNames);
@@ -284,33 +322,51 @@ private Path getFileDir(final String topicName) throws IOException {
return dirPath;
}
- private Path getFilePath(final String topicName, String fileName) throws SubscriptionException {
- Path filePath;
+ private Path getFilePath(
+ final String topicName,
+ final String fileName,
+ final boolean allowFileAlreadyExistsException,
+ final boolean allowInvalidPathException)
+ throws SubscriptionException {
try {
- filePath = getFileDir(topicName).resolve(fileName);
+ final Path filePath = getFileDir(topicName).resolve(fileName);
Files.createFile(filePath);
+ return filePath;
} catch (final FileAlreadyExistsException fileAlreadyExistsException) {
- fileName += "." + RandomStringGenerator.generate(16);
- try {
- filePath = getFileDir(topicName).resolve(fileName);
- Files.createFile(filePath);
- } catch (final IOException e) {
- throw new SubscriptionRuntimeNonCriticalException(e.getMessage(), e);
+ if (allowFileAlreadyExistsException) {
+ return getFilePath(
+ topicName, fileName + "." + RandomStringGenerator.generate(16), false, true);
+ }
+ throw new SubscriptionRuntimeNonCriticalException(
+ fileAlreadyExistsException.getMessage(), fileAlreadyExistsException);
+ } catch (final InvalidPathException invalidPathException) {
+ if (allowInvalidPathException) {
+ return getFilePath(URLEncoder.encode(topicName), fileName, true, false);
}
+ throw new SubscriptionRuntimeNonCriticalException(
+ invalidPathException.getMessage(), invalidPathException);
} catch (final IOException e) {
throw new SubscriptionRuntimeNonCriticalException(e.getMessage(), e);
}
- return filePath;
}
/////////////////////////////// poll ///////////////////////////////
- protected List poll(final Set topicNames, final long timeoutMs)
+ protected List poll(
+ /* @NotNull */ final Set topicNames, final long timeoutMs)
throws SubscriptionException {
final List messages = new ArrayList<>();
final SubscriptionPollTimer timer =
new SubscriptionPollTimer(System.currentTimeMillis(), timeoutMs);
+ // check topic names
+ topicNames.stream()
+ .filter(topicName -> !subscribedTopicNames.contains(topicName))
+ .forEach(
+ topicName ->
+ LOGGER.warn(
+ "SubscriptionConsumer {} does not subscribe to topic {}", this, topicName));
+
do {
try {
// poll tablets or file
@@ -336,18 +392,21 @@ protected List poll(final Set topicNames, final lon
case ERROR:
final ErrorPayload payload = (ErrorPayload) pollResponse.getPayload();
final String errorMessage = payload.getErrorMessage();
- final boolean critical = payload.isCritical();
- LOGGER.warn(
- "Error occurred when SubscriptionConsumer {} polling topics {}: {}, critical: {}",
- this,
- topicNames,
- errorMessage,
- critical);
- if (critical) {
+ if (payload.isCritical()) {
throw new SubscriptionRuntimeCriticalException(errorMessage);
} else {
throw new SubscriptionRuntimeNonCriticalException(errorMessage);
}
+ case TERMINATION:
+ final SubscriptionCommitContext commitContext = pollResponse.getCommitContext();
+ final String topicNameToUnsubscribe = commitContext.getTopicName();
+ LOGGER.info(
+ "Termination occurred when SubscriptionConsumer {} polling topics {}, unsubscribe topic {} automatically",
+ this,
+ topicNames,
+ topicNameToUnsubscribe);
+ unsubscribe(Collections.singleton(topicNameToUnsubscribe), false);
+ break;
default:
LOGGER.warn("unexpected response type: {}", responseType);
break;
@@ -398,7 +457,7 @@ private Optional pollFile(
final SubscriptionCommitContext commitContext, final String fileName)
throws SubscriptionException {
final String topicName = commitContext.getTopicName();
- final Path filePath = getFilePath(topicName, fileName);
+ final Path filePath = getFilePath(topicName, fileName, true, true);
final File file = filePath.toFile();
try (final RandomAccessFile fileWriter = new RandomAccessFile(file, "rw")) {
return Optional.of(pollFileInternal(commitContext, file, fileWriter));
@@ -576,6 +635,9 @@ private List pollInternal(final Set topicNames
try {
final SubscriptionProvider provider = providers.getNextAvailableProvider();
if (Objects.isNull(provider) || !provider.isAvailable()) {
+ if (isClosed()) {
+ return Collections.emptyList();
+ }
throw new SubscriptionConnectionException(
String.format(
"Cluster has no available subscription providers when %s poll topic %s",
@@ -601,6 +663,9 @@ private List pollFileInternal(
try {
final SubscriptionProvider provider = providers.getProvider(dataNodeId);
if (Objects.isNull(provider) || !provider.isAvailable()) {
+ if (isClosed()) {
+ return Collections.emptyList();
+ }
throw new SubscriptionConnectionException(
String.format(
"something unexpected happened when %s poll file from subscription provider with data node id %s, the subscription provider may be unavailable or not existed",
@@ -660,6 +725,9 @@ private void commitInternal(
try {
final SubscriptionProvider provider = providers.getProvider(dataNodeId);
if (Objects.isNull(provider) || !provider.isAvailable()) {
+ if (isClosed()) {
+ return;
+ }
throw new SubscriptionConnectionException(
String.format(
"something unexpected happened when %s commit (nack: %s) messages to subscription provider with data node id %s, the subscription provider may be unavailable or not existed",
@@ -775,7 +843,7 @@ private void subscribeWithRedirection(final Set topicNames) throws Subsc
}
for (final SubscriptionProvider provider : providers) {
try {
- provider.subscribe(topicNames);
+ subscribedTopicNames = provider.subscribe(topicNames);
return;
} catch (final Exception e) {
LOGGER.warn(
@@ -805,7 +873,7 @@ private void unsubscribeWithRedirection(final Set topicNames)
}
for (final SubscriptionProvider provider : providers) {
try {
- provider.unsubscribe(topicNames);
+ subscribedTopicNames = provider.unsubscribe(topicNames);
return;
} catch (final Exception e) {
LOGGER.warn(
@@ -897,12 +965,12 @@ public Builder password(final String password) {
}
public Builder consumerId(final String consumerId) {
- this.consumerId = consumerId;
+ this.consumerId = IdentifierUtils.parseIdentifier(consumerId);
return this;
}
public Builder consumerGroupId(final String consumerGroupId) {
- this.consumerGroupId = consumerGroupId;
+ this.consumerGroupId = IdentifierUtils.parseIdentifier(consumerGroupId);
return this;
}
diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionExecutorServiceManager.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionExecutorServiceManager.java
index 5a587ff96fba6..6ce5946d4fcc6 100644
--- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionExecutorServiceManager.java
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionExecutorServiceManager.java
@@ -29,12 +29,12 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-final class SubscriptionExecutorServiceManager {
+public final class SubscriptionExecutorServiceManager {
private static final Logger LOGGER =
LoggerFactory.getLogger(SubscriptionExecutorServiceManager.class);
- private static final long AWAIT_TERMINATION_TIMEOUT_MS = 10_000L;
+ private static final long AWAIT_TERMINATION_TIMEOUT_MS = 15_000L;
private static final String CONTROL_FLOW_EXECUTOR_NAME = "SubscriptionControlFlowExecutor";
private static final String UPSTREAM_DATA_FLOW_EXECUTOR_NAME =
@@ -172,9 +172,9 @@ boolean isShutdown() {
}
void setCorePoolSize(final int corePoolSize) {
- if (!isShutdown()) {
+ if (isShutdown()) {
synchronized (this) {
- if (!isShutdown()) {
+ if (isShutdown()) {
this.corePoolSize = corePoolSize;
return;
}
diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionProvider.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionProvider.java
index 70589472f8287..9bce0d6774faf 100644
--- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionProvider.java
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionProvider.java
@@ -40,6 +40,8 @@
import org.apache.iotdb.rpc.subscription.payload.request.PipeSubscribeUnsubscribeReq;
import org.apache.iotdb.rpc.subscription.payload.response.PipeSubscribeHandshakeResp;
import org.apache.iotdb.rpc.subscription.payload.response.PipeSubscribePollResp;
+import org.apache.iotdb.rpc.subscription.payload.response.PipeSubscribeSubscribeResp;
+import org.apache.iotdb.rpc.subscription.payload.response.PipeSubscribeUnsubscribeResp;
import org.apache.iotdb.service.rpc.thrift.TPipeSubscribeResp;
import org.apache.iotdb.session.subscription.SubscriptionSession;
import org.apache.iotdb.session.subscription.SubscriptionSessionConnection;
@@ -215,7 +217,7 @@ void heartbeat() throws SubscriptionException {
verifyPipeSubscribeSuccess(resp.status);
}
- void subscribe(final Set topicNames) throws SubscriptionException {
+ Set subscribe(final Set topicNames) throws SubscriptionException {
final PipeSubscribeSubscribeReq req;
try {
req = PipeSubscribeSubscribeReq.toTPipeSubscribeReq(topicNames);
@@ -241,9 +243,12 @@ void subscribe(final Set topicNames) throws SubscriptionException {
throw new SubscriptionConnectionException(e.getMessage(), e);
}
verifyPipeSubscribeSuccess(resp.status);
+ final PipeSubscribeSubscribeResp subscribeResp =
+ PipeSubscribeSubscribeResp.fromTPipeSubscribeResp(resp);
+ return subscribeResp.getTopicNames();
}
- void unsubscribe(final Set topicNames) throws SubscriptionException {
+ Set unsubscribe(final Set topicNames) throws SubscriptionException {
final PipeSubscribeUnsubscribeReq req;
try {
req = PipeSubscribeUnsubscribeReq.toTPipeSubscribeReq(topicNames);
@@ -269,6 +274,9 @@ void unsubscribe(final Set topicNames) throws SubscriptionException {
throw new SubscriptionConnectionException(e.getMessage(), e);
}
verifyPipeSubscribeSuccess(resp.status);
+ final PipeSubscribeUnsubscribeResp unsubscribeResp =
+ PipeSubscribeUnsubscribeResp.fromTPipeSubscribeResp(resp);
+ return unsubscribeResp.getTopicNames();
}
List poll(final SubscriptionPollRequest pollMessage)
diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionPullConsumer.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionPullConsumer.java
index 2306e4d05c1e2..38dfc530ee352 100644
--- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionPullConsumer.java
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionPullConsumer.java
@@ -22,6 +22,7 @@
import org.apache.iotdb.rpc.subscription.config.ConsumerConstant;
import org.apache.iotdb.rpc.subscription.exception.SubscriptionException;
import org.apache.iotdb.session.subscription.payload.SubscriptionMessage;
+import org.apache.iotdb.session.subscription.util.IdentifierUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,6 +40,7 @@
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
/**
* The {@link SubscriptionPullConsumer} corresponds to the pull consumption mode in the message
@@ -150,7 +152,12 @@ public List poll(final Set topicNames, final Durati
@Override
public List poll(final Set topicNames, final long timeoutMs)
throws SubscriptionException {
- final List messages = super.poll(topicNames, timeoutMs);
+ // parse topic names from external source
+ final Set parsedTopicNames =
+ topicNames.stream().map(IdentifierUtils::parseIdentifier).collect(Collectors.toSet());
+
+ // poll messages
+ final List messages = super.poll(parsedTopicNames, timeoutMs);
// add to uncommitted messages
if (autoCommit) {
diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionPushConsumer.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionPushConsumer.java
index 7ff1dd39b15bd..7323473552caf 100644
--- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionPushConsumer.java
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/consumer/SubscriptionPushConsumer.java
@@ -27,7 +27,6 @@
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
@@ -162,9 +161,12 @@ public void run() {
return;
}
+ if (subscribedTopicNames.isEmpty()) {
+ return;
+ }
+
try {
- // Poll all subscribed topics by passing an empty set
- final List messages = poll(Collections.emptySet(), autoPollTimeoutMs);
+ final List messages = poll(subscribedTopicNames, autoPollTimeoutMs);
if (ackStrategy.equals(AckStrategy.BEFORE_CONSUME)) {
ack(messages);
diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/payload/SubscriptionFileHandler.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/payload/SubscriptionFileHandler.java
index 60c269b86370c..0ec121f96992a 100644
--- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/payload/SubscriptionFileHandler.java
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/payload/SubscriptionFileHandler.java
@@ -39,14 +39,14 @@ public SubscriptionFileHandler(final String absolutePath) {
/**
* @return a new File instance of the corresponding file
*/
- public File getFile() {
+ public synchronized File getFile() {
return new File(absolutePath);
}
/**
* @return a new Path instance of the corresponding file
*/
- public Path getPath() {
+ public synchronized Path getPath() {
return Paths.get(absolutePath);
}
@@ -54,7 +54,7 @@ public Path getPath() {
* @return the path to the source file
* @throws IOException if an I/O error occurs
*/
- public Path deleteFile() throws IOException {
+ public synchronized Path deleteFile() throws IOException {
final Path sourcePath = getPath();
Files.delete(sourcePath);
return sourcePath;
@@ -65,7 +65,7 @@ public Path deleteFile() throws IOException {
* @return the path to the target file
* @throws IOException if an I/O error occurs
*/
- public Path moveFile(final String target) throws IOException {
+ public synchronized Path moveFile(final String target) throws IOException {
return this.moveFile(Paths.get(target));
}
@@ -74,7 +74,10 @@ public Path moveFile(final String target) throws IOException {
* @return the path to the target file
* @throws IOException if an I/O error occurs
*/
- public Path moveFile(final Path target) throws IOException {
+ public synchronized Path moveFile(final Path target) throws IOException {
+ if (!Files.exists(target.getParent())) {
+ Files.createDirectories(target.getParent());
+ }
return Files.move(getPath(), target, StandardCopyOption.REPLACE_EXISTING);
}
@@ -83,7 +86,7 @@ public Path moveFile(final Path target) throws IOException {
* @return the path to the target file
* @throws IOException if an I/O error occurs
*/
- public Path copyFile(final String target) throws IOException {
+ public synchronized Path copyFile(final String target) throws IOException {
return this.copyFile(Paths.get(target));
}
@@ -92,7 +95,10 @@ public Path copyFile(final String target) throws IOException {
* @return the path to the target file
* @throws IOException if an I/O error occurs
*/
- public Path copyFile(final Path target) throws IOException {
+ public synchronized Path copyFile(final Path target) throws IOException {
+ if (!Files.exists(target.getParent())) {
+ Files.createDirectories(target.getParent());
+ }
return Files.copy(
getPath(), target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
}
diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/payload/SubscriptionSessionDataSet.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/payload/SubscriptionSessionDataSet.java
index 8b5b244950459..ee2beafdd9619 100644
--- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/payload/SubscriptionSessionDataSet.java
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/payload/SubscriptionSessionDataSet.java
@@ -25,10 +25,12 @@
import org.apache.tsfile.read.common.Field;
import org.apache.tsfile.read.common.RowRecord;
import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.utils.DateUtils;
import org.apache.tsfile.write.UnSupportedDataTypeException;
import org.apache.tsfile.write.record.Tablet;
import org.apache.tsfile.write.schema.IMeasurementSchema;
+import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -84,7 +86,7 @@ public List getColumnTypes() {
List schemas = tablet.getSchemas();
columnTypeList.addAll(
- schemas.stream().map((schema) -> schema.getType().toString()).collect(Collectors.toList()));
+ schemas.stream().map(schema -> schema.getType().toString()).collect(Collectors.toList()));
return columnTypeList;
}
@@ -149,10 +151,13 @@ private static Field generateFieldFromTabletValue(
field.setBoolV(booleanValue);
break;
case INT32:
- case DATE:
final int intValue = ((int[]) value)[index];
field.setIntV(intValue);
break;
+ case DATE:
+ final LocalDate dateValue = ((LocalDate[]) value)[index];
+ field.setIntV(DateUtils.parseDateExpressionToInt(dateValue));
+ break;
case INT64:
case TIMESTAMP:
final long longValue = ((long[]) value)[index];
diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/util/IdentifierUtils.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/util/IdentifierUtils.java
new file mode 100644
index 0000000000000..9f6d09ef44e0f
--- /dev/null
+++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/subscription/util/IdentifierUtils.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.session.subscription.util;
+
+import org.apache.iotdb.rpc.subscription.exception.SubscriptionIdentifierSemanticException;
+
+import org.apache.tsfile.common.constant.TsFileConstant;
+import org.apache.tsfile.read.common.parser.PathVisitor;
+
+public class IdentifierUtils {
+
+ /**
+ * refer org.apache.iotdb.db.queryengine.plan.parser.ASTVisitor#parseIdentifier(java.lang.String)
+ */
+ public static String parseIdentifier(final String src) {
+ if (src.startsWith(TsFileConstant.BACK_QUOTE_STRING)
+ && src.endsWith(TsFileConstant.BACK_QUOTE_STRING)) {
+ return src.substring(1, src.length() - 1)
+ .replace(TsFileConstant.DOUBLE_BACK_QUOTE_STRING, TsFileConstant.BACK_QUOTE_STRING);
+ }
+ checkIdentifier(src);
+ return src;
+ }
+
+ private static void checkIdentifier(final String src) {
+ if (!TsFileConstant.IDENTIFIER_PATTERN.matcher(src).matches()
+ || PathVisitor.isRealNumber(src)) {
+ throw new SubscriptionIdentifierSemanticException(
+ String.format(
+ "%s is illegal, identifier not enclosed with backticks can only consist of digits, characters and underscore.",
+ src));
+ }
+ }
+}
diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
index 29c36e881e7dc..c9cfc400dcee7 100644
--- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
+++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
@@ -63,6 +63,7 @@ keyWords
| CONDITION
| CONFIGNODES
| CONFIGURATION
+ | CONNECTION
| CONNECTOR
| CONTAIN
| CONTAINS
diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index 6d3ffe0b837d8..4cff4e12b8cb6 100644
--- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -47,7 +47,7 @@ ddlStatement
| setSchemaTemplate | unsetSchemaTemplate
| alterSchemaTemplate
// TTL
- | setTTL | unsetTTL | showAllTTL
+ | setTTL | unsetTTL | showTTL | showAllTTL
// Function
| createFunction | dropFunction | showFunctions
// Trigger
@@ -64,7 +64,7 @@ ddlStatement
| createContinuousQuery | dropContinuousQuery | showContinuousQueries
// Cluster
| showVariables | showCluster | showRegions | showDataNodes | showConfigNodes | showClusterId
- | getRegionId | getTimeSlotList | countTimeSlotList | getSeriesSlotList | migrateRegion
+ | getRegionId | getTimeSlotList | countTimeSlotList | getSeriesSlotList | migrateRegion | verifyConnection
// Quota
| setSpaceQuota | showSpaceQuota | setThrottleQuota | showThrottleQuota
// View
@@ -325,6 +325,11 @@ unsetTTL
: UNSET TTL TO path=prefixPath
;
+// ---- Show TTL
+showTTL
+ : SHOW TTL ON prefixPath (COMMA prefixPath)*
+ ;
+
// ---- Show All TTL
showAllTTL
: SHOW ALL TTL
@@ -524,6 +529,10 @@ migrateRegion
: MIGRATE REGION regionId=INTEGER_LITERAL FROM fromId=INTEGER_LITERAL TO toId=INTEGER_LITERAL
;
+verifyConnection
+ : VERIFY CONNECTION (DETAILS)?
+ ;
+
// Pipe Task =========================================================================================
createPipe
: CREATE PIPE pipeName=identifier
diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
index 29cbcdcd17dfe..d1865a1e20486 100644
--- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
+++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
@@ -165,6 +165,10 @@ CONFIGURATION
: C O N F I G U R A T I O N
;
+CONNECTION
+ : C O N N E C T I O N
+ ;
+
CONNECTOR
: C O N N E C T O R
;
diff --git a/iotdb-core/confignode/src/assembly/resources/sbin/stop-confignode.sh b/iotdb-core/confignode/src/assembly/resources/sbin/stop-confignode.sh
index 5604afd3d32fa..5b2ccef01a514 100644
--- a/iotdb-core/confignode/src/assembly/resources/sbin/stop-confignode.sh
+++ b/iotdb-core/confignode/src/assembly/resources/sbin/stop-confignode.sh
@@ -18,6 +18,7 @@
# under the License.
#
+source "$(dirname "$0")/iotdb-common.sh"
CONFIGNODE_CONF="$(dirname "$0")/../conf"
if [ -f "${CONFIGNODE_CONF}/iotdb-system.properties" ]; then
@@ -26,6 +27,7 @@ else
cn_internal_port=$(sed '/^cn_internal_port=/!d;s/.*=//' "${CONFIGNODE_CONF}"/iotdb-confignode.properties)
fi
+check_config_unique "cn_internal_port" "$cn_internal_port"
echo Check whether the internal_port is used..., port is "$cn_internal_port"
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/ConfigNodeRequestType.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/CnToCnNodeRequestType.java
similarity index 92%
rename from iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/ConfigNodeRequestType.java
rename to iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/CnToCnNodeRequestType.java
index 5f3064b4eed73..3864f26cbc8e1 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/ConfigNodeRequestType.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/CnToCnNodeRequestType.java
@@ -19,7 +19,7 @@
package org.apache.iotdb.confignode.client;
-public enum ConfigNodeRequestType {
+public enum CnToCnNodeRequestType {
ADD_CONSENSUS_GROUP,
NOTIFY_REGISTER_SUCCESS,
REGISTER_CONFIG_NODE,
@@ -30,4 +30,6 @@ public enum ConfigNodeRequestType {
STOP_CONFIG_NODE,
SET_CONFIGURATION,
SHOW_CONFIGURATION,
+ SUBMIT_TEST_CONNECTION_TASK,
+ TEST_CONNECTION,
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/DataNodeRequestType.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/CnToDnRequestType.java
similarity index 97%
rename from iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/DataNodeRequestType.java
rename to iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/CnToDnRequestType.java
index b53035b29d5a6..82e5974f3c80e 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/DataNodeRequestType.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/CnToDnRequestType.java
@@ -19,7 +19,7 @@
package org.apache.iotdb.confignode.client;
-public enum DataNodeRequestType {
+public enum CnToDnRequestType {
// Node Maintenance
DISABLE_DATA_NODE,
@@ -35,6 +35,9 @@ public enum DataNodeRequestType {
SET_CONFIGURATION,
SHOW_CONFIGURATION,
+ SUBMIT_TEST_CONNECTION_TASK,
+ TEST_CONNECTION,
+
// Region Maintenance
CREATE_DATA_REGION,
CREATE_SCHEMA_REGION,
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/AsyncConfigNodeHeartbeatClientPool.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/AsyncConfigNodeHeartbeatClientPool.java
index fdcd3b0d1e299..7b6bca5d0d9e7 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/AsyncConfigNodeHeartbeatClientPool.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/AsyncConfigNodeHeartbeatClientPool.java
@@ -22,17 +22,17 @@
import org.apache.iotdb.common.rpc.thrift.TEndPoint;
import org.apache.iotdb.commons.client.ClientPoolFactory;
import org.apache.iotdb.commons.client.IClientManager;
-import org.apache.iotdb.commons.client.async.AsyncConfigNodeIServiceClient;
+import org.apache.iotdb.commons.client.async.AsyncConfigNodeInternalServiceClient;
import org.apache.iotdb.confignode.client.async.handlers.heartbeat.ConfigNodeHeartbeatHandler;
import org.apache.iotdb.confignode.rpc.thrift.TConfigNodeHeartbeatReq;
public class AsyncConfigNodeHeartbeatClientPool {
- private final IClientManager clientManager;
+ private final IClientManager clientManager;
private AsyncConfigNodeHeartbeatClientPool() {
clientManager =
- new IClientManager.Factory()
+ new IClientManager.Factory()
.createClientManager(
new ClientPoolFactory.AsyncConfigNodeHeartbeatServiceClientPoolFactory());
}
@@ -53,7 +53,6 @@ public void getConfigNodeHeartBeat(
}
}
- // TODO: Is the ClientPool must be a singleton?
private static class AsyncConfigNodeHeartbeatClientPoolHolder {
private static final AsyncConfigNodeHeartbeatClientPool INSTANCE =
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/AsyncDataNodeClientPool.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/AsyncDataNodeClientPool.java
deleted file mode 100644
index 31bc4074701c6..0000000000000
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/AsyncDataNodeClientPool.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.iotdb.confignode.client.async;
-
-import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId;
-import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
-import org.apache.iotdb.common.rpc.thrift.TEndPoint;
-import org.apache.iotdb.common.rpc.thrift.TFlushReq;
-import org.apache.iotdb.common.rpc.thrift.TSetConfigurationReq;
-import org.apache.iotdb.common.rpc.thrift.TSetSpaceQuotaReq;
-import org.apache.iotdb.common.rpc.thrift.TSetTTLReq;
-import org.apache.iotdb.common.rpc.thrift.TSetThrottleQuotaReq;
-import org.apache.iotdb.commons.client.ClientPoolFactory;
-import org.apache.iotdb.commons.client.IClientManager;
-import org.apache.iotdb.commons.client.async.AsyncDataNodeInternalServiceClient;
-import org.apache.iotdb.commons.client.exception.ClientManagerException;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
-import org.apache.iotdb.confignode.client.async.handlers.AsyncClientHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.AsyncTSStatusRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.CheckTimeSeriesExistenceRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.CountPathsUsingTemplateRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.FetchSchemaBlackListRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.PipeHeartbeatRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.PipePushMetaRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.SchemaUpdateRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.TransferLeaderRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.CheckSchemaRegionUsingTemplateRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.ConsumerGroupPushMetaRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.TopicPushMetaRPCHandler;
-import org.apache.iotdb.mpp.rpc.thrift.TActiveTriggerInstanceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TAlterViewReq;
-import org.apache.iotdb.mpp.rpc.thrift.TCheckSchemaRegionUsingTemplateReq;
-import org.apache.iotdb.mpp.rpc.thrift.TCheckTimeSeriesExistenceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TConstructSchemaBlackListReq;
-import org.apache.iotdb.mpp.rpc.thrift.TConstructSchemaBlackListWithTemplateReq;
-import org.apache.iotdb.mpp.rpc.thrift.TConstructViewSchemaBlackListReq;
-import org.apache.iotdb.mpp.rpc.thrift.TCountPathsUsingTemplateReq;
-import org.apache.iotdb.mpp.rpc.thrift.TCreateDataRegionReq;
-import org.apache.iotdb.mpp.rpc.thrift.TCreateFunctionInstanceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TCreatePipePluginInstanceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TCreateSchemaRegionReq;
-import org.apache.iotdb.mpp.rpc.thrift.TCreateTriggerInstanceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TDeactivateTemplateReq;
-import org.apache.iotdb.mpp.rpc.thrift.TDeleteDataForDeleteSchemaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TDeleteTimeSeriesReq;
-import org.apache.iotdb.mpp.rpc.thrift.TDeleteViewSchemaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TDropFunctionInstanceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TDropPipePluginInstanceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TDropTriggerInstanceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TFetchSchemaBlackListReq;
-import org.apache.iotdb.mpp.rpc.thrift.TInactiveTriggerInstanceReq;
-import org.apache.iotdb.mpp.rpc.thrift.TInvalidateMatchedSchemaCacheReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPipeHeartbeatReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPushConsumerGroupMetaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPushMultiPipeMetaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPushMultiTopicMetaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPushPipeMetaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPushSingleConsumerGroupMetaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPushSinglePipeMetaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPushSingleTopicMetaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TPushTopicMetaReq;
-import org.apache.iotdb.mpp.rpc.thrift.TRegionLeaderChangeReq;
-import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
-import org.apache.iotdb.mpp.rpc.thrift.TResetPeerListReq;
-import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListReq;
-import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListWithTemplateReq;
-import org.apache.iotdb.mpp.rpc.thrift.TRollbackViewSchemaBlackListReq;
-import org.apache.iotdb.mpp.rpc.thrift.TUpdateTableReq;
-import org.apache.iotdb.mpp.rpc.thrift.TUpdateTemplateReq;
-import org.apache.iotdb.mpp.rpc.thrift.TUpdateTriggerLocationReq;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.TimeUnit;
-
-/** Asynchronously send RPC requests to DataNodes. See queryengine.thrift for more details. */
-public class AsyncDataNodeClientPool {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(AsyncDataNodeClientPool.class);
-
- private final IClientManager clientManager;
-
- private static final int MAX_RETRY_NUM = 6;
-
- private AsyncDataNodeClientPool() {
- clientManager =
- new IClientManager.Factory()
- .createClientManager(
- new ClientPoolFactory.AsyncDataNodeInternalServiceClientPoolFactory());
- }
-
- /**
- * Send asynchronous requests to the specified DataNodes with default retry num
- *
- *
Notice: The DataNodes that failed to receive the requests will be reconnected
- *
- * @param clientHandler which will also contain the result
- * @param timeoutInMs timeout in milliseconds
- */
- public void sendAsyncRequestToDataNodeWithRetryAndTimeoutInMs(
- AsyncClientHandler, ?> clientHandler, long timeoutInMs) {
- sendAsyncRequest(clientHandler, MAX_RETRY_NUM, timeoutInMs);
- }
-
- /**
- * Send asynchronous requests to the specified DataNodes with default retry num
- *
- *
Notice: The DataNodes that failed to receive the requests will be reconnected
- *
- * @param clientHandler which will also contain the result
- */
- public void sendAsyncRequestToDataNodeWithRetry(AsyncClientHandler, ?> clientHandler) {
- sendAsyncRequest(clientHandler, MAX_RETRY_NUM, null);
- }
-
- public void sendAsyncRequestToDataNode(AsyncClientHandler, ?> clientHandler) {
- sendAsyncRequest(clientHandler, 1, null);
- }
-
- private void sendAsyncRequest(
- AsyncClientHandler, ?> clientHandler, int retryNum, Long timeoutInMs) {
- if (clientHandler.getRequestIndices().isEmpty()) {
- return;
- }
-
- DataNodeRequestType requestType = clientHandler.getRequestType();
- for (int retry = 0; retry < retryNum; retry++) {
- // Always Reset CountDownLatch first
- clientHandler.resetCountDownLatch();
-
- // Send requests to all targetDataNodes
- for (int requestId : clientHandler.getRequestIndices()) {
- TDataNodeLocation targetDataNode = clientHandler.getDataNodeLocation(requestId);
- sendAsyncRequestToDataNode(clientHandler, requestId, targetDataNode, retry);
- }
-
- // Wait for this batch of asynchronous RPC requests finish
- try {
- if (timeoutInMs == null) {
- clientHandler.getCountDownLatch().await();
- } else {
- if (!clientHandler.getCountDownLatch().await(timeoutInMs, TimeUnit.MILLISECONDS)) {
- LOGGER.warn(
- "Timeout during {} on ConfigNode. Retry: {}/{}", requestType, retry, retryNum);
- }
- }
- } catch (InterruptedException e) {
- LOGGER.error(
- "Interrupted during {} on ConfigNode. Retry: {}/{}", requestType, retry, retryNum);
- Thread.currentThread().interrupt();
- }
-
- // Check if there is a DataNode that fails to execute the request, and retry if there exists
- if (clientHandler.getRequestIndices().isEmpty()) {
- return;
- }
- }
-
- if (!clientHandler.getRequestIndices().isEmpty()) {
- LOGGER.warn(
- "Failed to {} on ConfigNode after {} retries, requestIndices: {}",
- requestType,
- retryNum,
- clientHandler.getRequestIndices());
- }
- }
-
- private void sendAsyncRequestToDataNode(
- AsyncClientHandler, ?> clientHandler,
- int requestId,
- TDataNodeLocation targetDataNode,
- int retryCount) {
-
- try {
- AsyncDataNodeInternalServiceClient client;
- client = clientManager.borrowClient(targetDataNode.getInternalEndPoint());
-
- switch (clientHandler.getRequestType()) {
- case SET_TTL:
- client.setTTL(
- (TSetTTLReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CREATE_DATA_REGION:
- client.createDataRegion(
- (TCreateDataRegionReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case DELETE_REGION:
- client.deleteRegion(
- (TConsensusGroupId) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CREATE_SCHEMA_REGION:
- client.createSchemaRegion(
- (TCreateSchemaRegionReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CREATE_FUNCTION:
- client.createFunction(
- (TCreateFunctionInstanceReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case DROP_FUNCTION:
- client.dropFunction(
- (TDropFunctionInstanceReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CREATE_TRIGGER_INSTANCE:
- client.createTriggerInstance(
- (TCreateTriggerInstanceReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case DROP_TRIGGER_INSTANCE:
- client.dropTriggerInstance(
- (TDropTriggerInstanceReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case ACTIVE_TRIGGER_INSTANCE:
- client.activeTriggerInstance(
- (TActiveTriggerInstanceReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case INACTIVE_TRIGGER_INSTANCE:
- client.inactiveTriggerInstance(
- (TInactiveTriggerInstanceReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case UPDATE_TRIGGER_LOCATION:
- client.updateTriggerLocation(
- (TUpdateTriggerLocationReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CREATE_PIPE_PLUGIN:
- client.createPipePlugin(
- (TCreatePipePluginInstanceReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case DROP_PIPE_PLUGIN:
- client.dropPipePlugin(
- (TDropPipePluginInstanceReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case PIPE_PUSH_ALL_META:
- client.pushPipeMeta(
- (TPushPipeMetaReq) clientHandler.getRequest(requestId),
- (PipePushMetaRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case PIPE_PUSH_SINGLE_META:
- client.pushSinglePipeMeta(
- (TPushSinglePipeMetaReq) clientHandler.getRequest(requestId),
- (PipePushMetaRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case PIPE_PUSH_MULTI_META:
- client.pushMultiPipeMeta(
- (TPushMultiPipeMetaReq) clientHandler.getRequest(requestId),
- (PipePushMetaRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case TOPIC_PUSH_ALL_META:
- client.pushTopicMeta(
- (TPushTopicMetaReq) clientHandler.getRequest(requestId),
- (TopicPushMetaRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case TOPIC_PUSH_SINGLE_META:
- client.pushSingleTopicMeta(
- (TPushSingleTopicMetaReq) clientHandler.getRequest(requestId),
- (TopicPushMetaRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case TOPIC_PUSH_MULTI_META:
- client.pushMultiTopicMeta(
- (TPushMultiTopicMetaReq) clientHandler.getRequest(requestId),
- (TopicPushMetaRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CONSUMER_GROUP_PUSH_ALL_META:
- client.pushConsumerGroupMeta(
- (TPushConsumerGroupMetaReq) clientHandler.getRequest(requestId),
- (ConsumerGroupPushMetaRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CONSUMER_GROUP_PUSH_SINGLE_META:
- client.pushSingleConsumerGroupMeta(
- (TPushSingleConsumerGroupMetaReq) clientHandler.getRequest(requestId),
- (ConsumerGroupPushMetaRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case PIPE_HEARTBEAT:
- client.pipeHeartbeat(
- (TPipeHeartbeatReq) clientHandler.getRequest(requestId),
- (PipeHeartbeatRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case MERGE:
- case FULL_MERGE:
- client.merge(
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case FLUSH:
- client.flush(
- (TFlushReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CLEAR_CACHE:
- client.clearCache(
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case SET_CONFIGURATION:
- client.setConfiguration(
- (TSetConfigurationReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case START_REPAIR_DATA:
- client.startRepairData(
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case STOP_REPAIR_DATA:
- client.stopRepairData(
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case LOAD_CONFIGURATION:
- client.loadConfiguration(
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case SET_SYSTEM_STATUS:
- client.setSystemStatus(
- (String) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case UPDATE_REGION_ROUTE_MAP:
- client.updateRegionCache(
- (TRegionRouteReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CHANGE_REGION_LEADER:
- client.changeRegionLeader(
- (TRegionLeaderChangeReq) clientHandler.getRequest(requestId),
- (TransferLeaderRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CONSTRUCT_SCHEMA_BLACK_LIST:
- client.constructSchemaBlackList(
- (TConstructSchemaBlackListReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case ROLLBACK_SCHEMA_BLACK_LIST:
- client.rollbackSchemaBlackList(
- (TRollbackSchemaBlackListReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case FETCH_SCHEMA_BLACK_LIST:
- client.fetchSchemaBlackList(
- (TFetchSchemaBlackListReq) clientHandler.getRequest(requestId),
- (FetchSchemaBlackListRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case INVALIDATE_MATCHED_SCHEMA_CACHE:
- client.invalidateMatchedSchemaCache(
- (TInvalidateMatchedSchemaCacheReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case DELETE_DATA_FOR_DELETE_SCHEMA:
- client.deleteDataForDeleteSchema(
- (TDeleteDataForDeleteSchemaReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case DELETE_TIMESERIES:
- client.deleteTimeSeries(
- (TDeleteTimeSeriesReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CONSTRUCT_SCHEMA_BLACK_LIST_WITH_TEMPLATE:
- client.constructSchemaBlackListWithTemplate(
- (TConstructSchemaBlackListWithTemplateReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case ROLLBACK_SCHEMA_BLACK_LIST_WITH_TEMPLATE:
- client.rollbackSchemaBlackListWithTemplate(
- (TRollbackSchemaBlackListWithTemplateReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case DEACTIVATE_TEMPLATE:
- client.deactivateTemplate(
- (TDeactivateTemplateReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case UPDATE_TEMPLATE:
- client.updateTemplate(
- (TUpdateTemplateReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case COUNT_PATHS_USING_TEMPLATE:
- client.countPathsUsingTemplate(
- (TCountPathsUsingTemplateReq) clientHandler.getRequest(requestId),
- (CountPathsUsingTemplateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CHECK_SCHEMA_REGION_USING_TEMPLATE:
- client.checkSchemaRegionUsingTemplate(
- (TCheckSchemaRegionUsingTemplateReq) clientHandler.getRequest(requestId),
- (CheckSchemaRegionUsingTemplateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CHECK_TIMESERIES_EXISTENCE:
- client.checkTimeSeriesExistence(
- (TCheckTimeSeriesExistenceReq) clientHandler.getRequest(requestId),
- (CheckTimeSeriesExistenceRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case CONSTRUCT_VIEW_SCHEMA_BLACK_LIST:
- client.constructViewSchemaBlackList(
- (TConstructViewSchemaBlackListReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case ROLLBACK_VIEW_SCHEMA_BLACK_LIST:
- client.rollbackViewSchemaBlackList(
- (TRollbackViewSchemaBlackListReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case DELETE_VIEW:
- client.deleteViewSchema(
- (TDeleteViewSchemaReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case ALTER_VIEW:
- client.alterView(
- (TAlterViewReq) clientHandler.getRequest(requestId),
- (SchemaUpdateRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case KILL_QUERY_INSTANCE:
- client.killQueryInstance(
- (String) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case SET_SPACE_QUOTA:
- client.setSpaceQuota(
- (TSetSpaceQuotaReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case SET_THROTTLE_QUOTA:
- client.setThrottleQuota(
- (TSetThrottleQuotaReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case RESET_PEER_LIST:
- client.resetPeerList(
- (TResetPeerListReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- case UPDATE_TABLE:
- client.updateTable(
- (TUpdateTableReq) clientHandler.getRequest(requestId),
- (AsyncTSStatusRPCHandler)
- clientHandler.createAsyncRPCHandler(requestId, targetDataNode));
- break;
- default:
- LOGGER.error(
- "Unexpected DataNode Request Type: {} when sendAsyncRequestToDataNode",
- clientHandler.getRequestType());
- }
- } catch (Exception e) {
- LOGGER.warn(
- "{} failed on DataNode {}, because {}, retrying {}...",
- clientHandler.getRequestType(),
- targetDataNode.getInternalEndPoint(),
- e.getMessage(),
- retryCount);
- }
- }
-
- /**
- * Always call this interface when a DataNode is restarted or removed.
- *
- * @param endPoint The specific DataNode
- */
- public void resetClient(TEndPoint endPoint) {
- clientManager.clear(endPoint);
- }
-
- public AsyncDataNodeInternalServiceClient getAsyncClient(TDataNodeLocation targetDataNode)
- throws ClientManagerException {
- return clientManager.borrowClient(targetDataNode.getInternalEndPoint());
- }
-
- // TODO: Is the ClientPool must be a singleton?
- private static class ClientPoolHolder {
-
- private static final AsyncDataNodeClientPool INSTANCE = new AsyncDataNodeClientPool();
-
- private ClientPoolHolder() {
- // Empty constructor
- }
- }
-
- public static AsyncDataNodeClientPool getInstance() {
- return ClientPoolHolder.INSTANCE;
- }
-}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToCnInternalServiceAsyncRequestManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToCnInternalServiceAsyncRequestManager.java
new file mode 100644
index 0000000000000..bd5ee3fe4995f
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToCnInternalServiceAsyncRequestManager.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async;
+
+import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TNodeLocations;
+import org.apache.iotdb.commons.client.request.AsyncRequestContext;
+import org.apache.iotdb.commons.client.request.AsyncRequestRPCHandler;
+import org.apache.iotdb.commons.client.request.ConfigNodeInternalServiceAsyncRequestManager;
+import org.apache.iotdb.confignode.client.CnToCnNodeRequestType;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.ConfigNodeAsyncRequestRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.ConfigNodeTSStatusRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.SubmitTestConnectionTaskToConfigNodeRPCHandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnToCnInternalServiceAsyncRequestManager
+ extends ConfigNodeInternalServiceAsyncRequestManager {
+
+ private static final Logger LOGGER =
+ LoggerFactory.getLogger(CnToCnInternalServiceAsyncRequestManager.class);
+
+ @Override
+ protected void initActionMapBuilder() {
+ actionMapBuilder.put(
+ CnToCnNodeRequestType.SUBMIT_TEST_CONNECTION_TASK,
+ (req, client, handler) ->
+ client.submitTestConnectionTask(
+ (TNodeLocations) req, (SubmitTestConnectionTaskToConfigNodeRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToCnNodeRequestType.TEST_CONNECTION,
+ (req, client, handler) ->
+ client.testConnectionEmptyRPC((ConfigNodeTSStatusRPCHandler) handler));
+ }
+
+ @Override
+ protected AsyncRequestRPCHandler, CnToCnNodeRequestType, TConfigNodeLocation> buildHandler(
+ AsyncRequestContext, ?, CnToCnNodeRequestType, TConfigNodeLocation> requestContext,
+ int requestId,
+ TConfigNodeLocation targetNode) {
+ return ConfigNodeAsyncRequestRPCHandler.buildHandler(requestContext, requestId, targetNode);
+ }
+
+ private static class ClientPoolHolder {
+ private static final CnToCnInternalServiceAsyncRequestManager INSTANCE =
+ new CnToCnInternalServiceAsyncRequestManager();
+
+ private ClientPoolHolder() {
+ // Empty constructor
+ }
+ }
+
+ public static CnToCnInternalServiceAsyncRequestManager getInstance() {
+ return ClientPoolHolder.INSTANCE;
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
new file mode 100644
index 0000000000000..8f3e7c720fc63
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
@@ -0,0 +1,376 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async;
+
+import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId;
+import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TFlushReq;
+import org.apache.iotdb.common.rpc.thrift.TNodeLocations;
+import org.apache.iotdb.common.rpc.thrift.TSetConfigurationReq;
+import org.apache.iotdb.common.rpc.thrift.TSetSpaceQuotaReq;
+import org.apache.iotdb.common.rpc.thrift.TSetTTLReq;
+import org.apache.iotdb.common.rpc.thrift.TSetThrottleQuotaReq;
+import org.apache.iotdb.commons.client.request.AsyncRequestContext;
+import org.apache.iotdb.commons.client.request.AsyncRequestRPCHandler;
+import org.apache.iotdb.commons.client.request.DataNodeInternalServiceRequestManager;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.CheckTimeSeriesExistenceRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.CountPathsUsingTemplateRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.DataNodeAsyncRequestRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.DataNodeTSStatusRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.FetchSchemaBlackListRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.PipeHeartbeatRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.PipePushMetaRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.SchemaUpdateRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.SubmitTestConnectionTaskRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.TransferLeaderRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.CheckSchemaRegionUsingTemplateRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.ConsumerGroupPushMetaRPCHandler;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.TopicPushMetaRPCHandler;
+import org.apache.iotdb.mpp.rpc.thrift.TActiveTriggerInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TAlterViewReq;
+import org.apache.iotdb.mpp.rpc.thrift.TCheckSchemaRegionUsingTemplateReq;
+import org.apache.iotdb.mpp.rpc.thrift.TCheckTimeSeriesExistenceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TConstructSchemaBlackListReq;
+import org.apache.iotdb.mpp.rpc.thrift.TConstructSchemaBlackListWithTemplateReq;
+import org.apache.iotdb.mpp.rpc.thrift.TConstructViewSchemaBlackListReq;
+import org.apache.iotdb.mpp.rpc.thrift.TCountPathsUsingTemplateReq;
+import org.apache.iotdb.mpp.rpc.thrift.TCreateDataRegionReq;
+import org.apache.iotdb.mpp.rpc.thrift.TCreateFunctionInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TCreatePipePluginInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TCreateSchemaRegionReq;
+import org.apache.iotdb.mpp.rpc.thrift.TCreateTriggerInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TDeactivateTemplateReq;
+import org.apache.iotdb.mpp.rpc.thrift.TDeleteDataForDeleteSchemaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TDeleteTimeSeriesReq;
+import org.apache.iotdb.mpp.rpc.thrift.TDeleteViewSchemaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TDropFunctionInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TDropPipePluginInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TDropTriggerInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TFetchSchemaBlackListReq;
+import org.apache.iotdb.mpp.rpc.thrift.TInactiveTriggerInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TInvalidateMatchedSchemaCacheReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPipeHeartbeatReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPushConsumerGroupMetaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPushMultiPipeMetaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPushMultiTopicMetaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPushPipeMetaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPushSingleConsumerGroupMetaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPushSinglePipeMetaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPushSingleTopicMetaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TPushTopicMetaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TRegionLeaderChangeReq;
+import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
+import org.apache.iotdb.mpp.rpc.thrift.TResetPeerListReq;
+import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListReq;
+import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListWithTemplateReq;
+import org.apache.iotdb.mpp.rpc.thrift.TRollbackViewSchemaBlackListReq;
+import org.apache.iotdb.mpp.rpc.thrift.TUpdateTemplateReq;
+import org.apache.iotdb.mpp.rpc.thrift.TUpdateTriggerLocationReq;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Asynchronously send RPC requests to DataNodes. See queryengine.thrift for more details. */
+public class CnToDnInternalServiceAsyncRequestManager
+ extends DataNodeInternalServiceRequestManager {
+
+ private static final Logger LOGGER =
+ LoggerFactory.getLogger(CnToDnInternalServiceAsyncRequestManager.class);
+
+ @Override
+ protected void initActionMapBuilder() {
+ actionMapBuilder.put(
+ CnToDnRequestType.SET_TTL,
+ (req, client, handler) ->
+ client.setTTL((TSetTTLReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CREATE_DATA_REGION,
+ (req, client, handler) ->
+ client.createDataRegion(
+ (TCreateDataRegionReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.DELETE_REGION,
+ (req, client, handler) ->
+ client.deleteRegion((TConsensusGroupId) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CREATE_SCHEMA_REGION,
+ (req, client, handler) ->
+ client.createSchemaRegion(
+ (TCreateSchemaRegionReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CREATE_FUNCTION,
+ (req, client, handler) ->
+ client.createFunction(
+ (TCreateFunctionInstanceReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.DROP_FUNCTION,
+ (req, client, handler) ->
+ client.dropFunction(
+ (TDropFunctionInstanceReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CREATE_TRIGGER_INSTANCE,
+ (req, client, handler) ->
+ client.createTriggerInstance(
+ (TCreateTriggerInstanceReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.DROP_TRIGGER_INSTANCE,
+ (req, client, handler) ->
+ client.dropTriggerInstance(
+ (TDropTriggerInstanceReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.ACTIVE_TRIGGER_INSTANCE,
+ (req, client, handler) ->
+ client.activeTriggerInstance(
+ (TActiveTriggerInstanceReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.INACTIVE_TRIGGER_INSTANCE,
+ (req, client, handler) ->
+ client.inactiveTriggerInstance(
+ (TInactiveTriggerInstanceReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.UPDATE_TRIGGER_LOCATION,
+ (req, client, handler) ->
+ client.updateTriggerLocation(
+ (TUpdateTriggerLocationReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CREATE_PIPE_PLUGIN,
+ (req, client, handler) ->
+ client.createPipePlugin(
+ (TCreatePipePluginInstanceReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.DROP_PIPE_PLUGIN,
+ (req, client, handler) ->
+ client.dropPipePlugin(
+ (TDropPipePluginInstanceReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.PIPE_PUSH_ALL_META,
+ (req, client, handler) ->
+ client.pushPipeMeta((TPushPipeMetaReq) req, (PipePushMetaRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.PIPE_PUSH_SINGLE_META,
+ (req, client, handler) ->
+ client.pushSinglePipeMeta(
+ (TPushSinglePipeMetaReq) req, (PipePushMetaRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.PIPE_PUSH_MULTI_META,
+ (req, client, handler) ->
+ client.pushMultiPipeMeta(
+ (TPushMultiPipeMetaReq) req, (PipePushMetaRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.TOPIC_PUSH_ALL_META,
+ (req, client, handler) ->
+ client.pushTopicMeta((TPushTopicMetaReq) req, (TopicPushMetaRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.TOPIC_PUSH_SINGLE_META,
+ (req, client, handler) ->
+ client.pushSingleTopicMeta(
+ (TPushSingleTopicMetaReq) req, (TopicPushMetaRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.TOPIC_PUSH_MULTI_META,
+ (req, client, handler) ->
+ client.pushMultiTopicMeta(
+ (TPushMultiTopicMetaReq) req, (TopicPushMetaRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CONSUMER_GROUP_PUSH_ALL_META,
+ (req, client, handler) ->
+ client.pushConsumerGroupMeta(
+ (TPushConsumerGroupMetaReq) req, (ConsumerGroupPushMetaRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CONSUMER_GROUP_PUSH_SINGLE_META,
+ (req, client, handler) ->
+ client.pushSingleConsumerGroupMeta(
+ (TPushSingleConsumerGroupMetaReq) req, (ConsumerGroupPushMetaRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.PIPE_HEARTBEAT,
+ (req, client, handler) ->
+ client.pipeHeartbeat((TPipeHeartbeatReq) req, (PipeHeartbeatRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.MERGE,
+ (req, client, handler) -> client.merge((DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.FULL_MERGE,
+ (req, client, handler) -> client.merge((DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.FLUSH,
+ (req, client, handler) ->
+ client.flush((TFlushReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CLEAR_CACHE,
+ (req, client, handler) -> client.clearCache((DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.START_REPAIR_DATA,
+ (req, client, handler) -> client.startRepairData((DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.STOP_REPAIR_DATA,
+ (req, client, handler) -> client.stopRepairData((DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.LOAD_CONFIGURATION,
+ (req, client, handler) -> client.loadConfiguration((DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.SET_SYSTEM_STATUS,
+ (req, client, handler) ->
+ client.setSystemStatus((String) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.SET_CONFIGURATION,
+ (req, client, handler) ->
+ client.setConfiguration(
+ (TSetConfigurationReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.UPDATE_REGION_ROUTE_MAP,
+ (req, client, handler) ->
+ client.updateRegionCache((TRegionRouteReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CHANGE_REGION_LEADER,
+ (req, client, handler) ->
+ client.changeRegionLeader(
+ (TRegionLeaderChangeReq) req, (TransferLeaderRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CONSTRUCT_SCHEMA_BLACK_LIST,
+ (req, client, handler) ->
+ client.constructSchemaBlackList(
+ (TConstructSchemaBlackListReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.ROLLBACK_SCHEMA_BLACK_LIST,
+ (req, client, handler) ->
+ client.rollbackSchemaBlackList(
+ (TRollbackSchemaBlackListReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.FETCH_SCHEMA_BLACK_LIST,
+ (req, client, handler) ->
+ client.fetchSchemaBlackList(
+ (TFetchSchemaBlackListReq) req, (FetchSchemaBlackListRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.INVALIDATE_MATCHED_SCHEMA_CACHE,
+ (req, client, handler) ->
+ client.invalidateMatchedSchemaCache(
+ (TInvalidateMatchedSchemaCacheReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.DELETE_DATA_FOR_DELETE_SCHEMA,
+ (req, client, handler) ->
+ client.deleteDataForDeleteSchema(
+ (TDeleteDataForDeleteSchemaReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.DELETE_TIMESERIES,
+ (req, client, handler) ->
+ client.deleteTimeSeries((TDeleteTimeSeriesReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CONSTRUCT_SCHEMA_BLACK_LIST_WITH_TEMPLATE,
+ (req, client, handler) ->
+ client.constructSchemaBlackListWithTemplate(
+ (TConstructSchemaBlackListWithTemplateReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.ROLLBACK_SCHEMA_BLACK_LIST_WITH_TEMPLATE,
+ (req, client, handler) ->
+ client.rollbackSchemaBlackListWithTemplate(
+ (TRollbackSchemaBlackListWithTemplateReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.DEACTIVATE_TEMPLATE,
+ (req, client, handler) ->
+ client.deactivateTemplate(
+ (TDeactivateTemplateReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.UPDATE_TEMPLATE,
+ (req, client, handler) ->
+ client.updateTemplate((TUpdateTemplateReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.COUNT_PATHS_USING_TEMPLATE,
+ (req, client, handler) ->
+ client.countPathsUsingTemplate(
+ (TCountPathsUsingTemplateReq) req, (CountPathsUsingTemplateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CHECK_SCHEMA_REGION_USING_TEMPLATE,
+ (req, client, handler) ->
+ client.checkSchemaRegionUsingTemplate(
+ (TCheckSchemaRegionUsingTemplateReq) req,
+ (CheckSchemaRegionUsingTemplateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CHECK_TIMESERIES_EXISTENCE,
+ (req, client, handler) ->
+ client.checkTimeSeriesExistence(
+ (TCheckTimeSeriesExistenceReq) req, (CheckTimeSeriesExistenceRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.CONSTRUCT_VIEW_SCHEMA_BLACK_LIST,
+ (req, client, handler) ->
+ client.constructViewSchemaBlackList(
+ (TConstructViewSchemaBlackListReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.ROLLBACK_VIEW_SCHEMA_BLACK_LIST,
+ (req, client, handler) ->
+ client.rollbackViewSchemaBlackList(
+ (TRollbackViewSchemaBlackListReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.DELETE_VIEW,
+ (req, client, handler) ->
+ client.deleteViewSchema((TDeleteViewSchemaReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.ALTER_VIEW,
+ (req, client, handler) ->
+ client.alterView((TAlterViewReq) req, (SchemaUpdateRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.KILL_QUERY_INSTANCE,
+ (req, client, handler) ->
+ client.killQueryInstance((String) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.SET_SPACE_QUOTA,
+ (req, client, handler) ->
+ client.setSpaceQuota((TSetSpaceQuotaReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.SET_THROTTLE_QUOTA,
+ (req, client, handler) ->
+ client.setThrottleQuota(
+ (TSetThrottleQuotaReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.RESET_PEER_LIST,
+ (req, client, handler) ->
+ client.resetPeerList((TResetPeerListReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.SUBMIT_TEST_CONNECTION_TASK,
+ (req, client, handler) ->
+ client.submitTestConnectionTask(
+ (TNodeLocations) req, (SubmitTestConnectionTaskRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnRequestType.TEST_CONNECTION,
+ (req, client, handler) ->
+ client.testConnectionEmptyRPC((DataNodeTSStatusRPCHandler) handler));
+ }
+
+ @Override
+ protected AsyncRequestRPCHandler, CnToDnRequestType, TDataNodeLocation> buildHandler(
+ AsyncRequestContext, ?, CnToDnRequestType, TDataNodeLocation> requestContext,
+ int requestId,
+ TDataNodeLocation targetNode) {
+ return DataNodeAsyncRequestRPCHandler.buildHandler(requestContext, requestId, targetNode);
+ }
+
+ private static class ClientPoolHolder {
+
+ private static final CnToDnInternalServiceAsyncRequestManager INSTANCE =
+ new CnToDnInternalServiceAsyncRequestManager();
+
+ private ClientPoolHolder() {
+ // Empty constructor
+ }
+ }
+
+ public static CnToDnInternalServiceAsyncRequestManager getInstance() {
+ return ClientPoolHolder.INSTANCE;
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/ConfigNodeAsyncRequestContext.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/ConfigNodeAsyncRequestContext.java
new file mode 100644
index 0000000000000..cde2cf1c8ec2f
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/ConfigNodeAsyncRequestContext.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async.handlers;
+
+import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
+import org.apache.iotdb.commons.client.request.AsyncRequestContext;
+import org.apache.iotdb.confignode.client.CnToCnNodeRequestType;
+
+import java.util.Map;
+
+/**
+ * Asynchronous Client handler.
+ *
+ * @param ClassName of RPC request
+ * @param ClassName of RPC response
+ */
+public class ConfigNodeAsyncRequestContext
+ extends AsyncRequestContext {
+
+ public ConfigNodeAsyncRequestContext(
+ CnToCnNodeRequestType configNodeRequestType,
+ Q q,
+ Map integerTConfigNodeLocationMap) {
+ super(configNodeRequestType, q, integerTConfigNodeLocationMap);
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/DataNodeAsyncRequestContext.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/DataNodeAsyncRequestContext.java
new file mode 100644
index 0000000000000..2b813c081d7e7
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/DataNodeAsyncRequestContext.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async.handlers;
+
+import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.commons.client.request.AsyncRequestContext;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
+
+import java.util.Map;
+
+/**
+ * Asynchronous Client handler.
+ *
+ * @param ClassName of RPC request
+ * @param ClassName of RPC response
+ */
+public class DataNodeAsyncRequestContext
+ extends AsyncRequestContext {
+
+ public DataNodeAsyncRequestContext(CnToDnRequestType requestType) {
+ super(requestType);
+ }
+
+ public DataNodeAsyncRequestContext(
+ CnToDnRequestType requestType, Map dataNodeLocationMap) {
+ super(requestType, dataNodeLocationMap);
+ }
+
+ public DataNodeAsyncRequestContext(
+ CnToDnRequestType requestType, Q q, Map dataNodeLocationMap) {
+ super(requestType, q, dataNodeLocationMap);
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/CheckTimeSeriesExistenceRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/CheckTimeSeriesExistenceRPCHandler.java
index 150947f1b97b1..b12ba289f1c2a 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/CheckTimeSeriesExistenceRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/CheckTimeSeriesExistenceRPCHandler.java
@@ -21,7 +21,7 @@
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.mpp.rpc.thrift.TCheckTimeSeriesExistenceResp;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -33,13 +33,13 @@
import java.util.concurrent.CountDownLatch;
public class CheckTimeSeriesExistenceRPCHandler
- extends AbstractAsyncRPCHandler {
+ extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER =
LoggerFactory.getLogger(CheckTimeSeriesExistenceRPCHandler.class);
public CheckTimeSeriesExistenceRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -53,15 +53,13 @@ public void onComplete(TCheckTimeSeriesExistenceResp response) {
TSStatus tsStatus = response.getStatus();
responseMap.put(requestId, response);
if (tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
- LOGGER.info("Successfully check timeseries existence on DataNode: {}", targetDataNode);
+ nodeLocationMap.remove(requestId);
+ LOGGER.info("Successfully check timeseries existence on DataNode: {}", targetNode);
} else if (tsStatus.getCode() == TSStatusCode.MULTIPLE_ERROR.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
- LOGGER.error(
- "Failed to check timeseries existence on DataNode {}, {}", targetDataNode, tsStatus);
+ nodeLocationMap.remove(requestId);
+ LOGGER.error("Failed to check timeseries existence on DataNode {}, {}", targetNode, tsStatus);
} else {
- LOGGER.error(
- "Failed to check timeseries existence on DataNode {}, {}", targetDataNode, tsStatus);
+ LOGGER.error("Failed to check timeseries existence on DataNode {}, {}", targetNode, tsStatus);
}
countDownLatch.countDown();
}
@@ -70,9 +68,9 @@ public void onComplete(TCheckTimeSeriesExistenceResp response) {
public void onError(Exception e) {
String errorMsg =
"Check timeseries existence error on DataNode: {id="
- + targetDataNode.getDataNodeId()
+ + targetNode.getDataNodeId()
+ ", internalEndPoint="
- + targetDataNode.getInternalEndPoint()
+ + targetNode.getInternalEndPoint()
+ "}"
+ e.getMessage();
LOGGER.error(errorMsg);
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/ConfigNodeAsyncRequestRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/ConfigNodeAsyncRequestRPCHandler.java
new file mode 100644
index 0000000000000..4825629ee5591
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/ConfigNodeAsyncRequestRPCHandler.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async.handlers.rpc;
+
+import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.common.rpc.thrift.TTestConnectionResp;
+import org.apache.iotdb.commons.client.request.AsyncRequestContext;
+import org.apache.iotdb.commons.client.request.AsyncRequestRPCHandler;
+import org.apache.iotdb.confignode.client.CnToCnNodeRequestType;
+
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+public abstract class ConfigNodeAsyncRequestRPCHandler
+ extends AsyncRequestRPCHandler {
+
+ protected ConfigNodeAsyncRequestRPCHandler(
+ CnToCnNodeRequestType configNodeRequestType,
+ int requestId,
+ TConfigNodeLocation targetNode,
+ Map integerTConfigNodeLocationMap,
+ Map integerResponseMap,
+ CountDownLatch countDownLatch) {
+ super(
+ configNodeRequestType,
+ requestId,
+ targetNode,
+ integerTConfigNodeLocationMap,
+ integerResponseMap,
+ countDownLatch);
+ }
+
+ @Override
+ protected String generateFormattedTargetLocation(TConfigNodeLocation configNodeLocation) {
+ return "{id="
+ + targetNode.getConfigNodeId()
+ + ", internalEndPoint="
+ + targetNode.getInternalEndPoint()
+ + "}";
+ }
+
+ public static ConfigNodeAsyncRequestRPCHandler> buildHandler(
+ AsyncRequestContext, ?, CnToCnNodeRequestType, TConfigNodeLocation> context,
+ int requestId,
+ TConfigNodeLocation targetConfigNode) {
+ CnToCnNodeRequestType requestType = context.getRequestType();
+ Map nodeLocationMap = context.getNodeLocationMap();
+ Map responseMap = context.getResponseMap();
+ CountDownLatch countDownLatch = context.getCountDownLatch();
+ switch (requestType) {
+ case SUBMIT_TEST_CONNECTION_TASK:
+ return new SubmitTestConnectionTaskToConfigNodeRPCHandler(
+ requestType,
+ requestId,
+ targetConfigNode,
+ nodeLocationMap,
+ (Map) responseMap,
+ countDownLatch);
+ case TEST_CONNECTION:
+ default:
+ return new ConfigNodeTSStatusRPCHandler(
+ requestType,
+ requestId,
+ targetConfigNode,
+ nodeLocationMap,
+ (Map) responseMap,
+ countDownLatch);
+ }
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/ConfigNodeTSStatusRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/ConfigNodeTSStatusRPCHandler.java
new file mode 100644
index 0000000000000..a28acb3496267
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/ConfigNodeTSStatusRPCHandler.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async.handlers.rpc;
+
+import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.confignode.client.CnToCnNodeRequestType;
+import org.apache.iotdb.rpc.RpcUtils;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/** General RPC handler for TSStatus response type. */
+public class ConfigNodeTSStatusRPCHandler extends ConfigNodeAsyncRequestRPCHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ConfigNodeTSStatusRPCHandler.class);
+
+ public ConfigNodeTSStatusRPCHandler(
+ CnToCnNodeRequestType requestType,
+ int requestId,
+ TConfigNodeLocation targetConfigNode,
+ Map configNodeLocationMap,
+ Map responseMap,
+ CountDownLatch countDownLatch) {
+ super(
+ requestType,
+ requestId,
+ targetConfigNode,
+ configNodeLocationMap,
+ responseMap,
+ countDownLatch);
+ }
+
+ @Override
+ public void onComplete(TSStatus response) {
+ // Put response
+ responseMap.put(requestId, response);
+
+ if (response.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ // Remove only if success
+ nodeLocationMap.remove(requestId);
+ LOGGER.info("Successfully {} on ConfigNode: {}", requestType, formattedTargetLocation);
+ } else {
+ LOGGER.error(
+ "Failed to {} on ConfigNode: {}, response: {}",
+ requestType,
+ formattedTargetLocation,
+ response);
+ }
+
+ // Always CountDown
+ countDownLatch.countDown();
+ }
+
+ @Override
+ public void onError(Exception e) {
+ String errorMsg =
+ "Failed to "
+ + requestType
+ + " on ConfigNode: "
+ + formattedTargetLocation
+ + ", exception: "
+ + e.getMessage();
+ LOGGER.error(errorMsg);
+
+ responseMap.put(
+ requestId,
+ new TSStatus(
+ RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode(), errorMsg)));
+
+ // Always CountDown
+ countDownLatch.countDown();
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/CountPathsUsingTemplateRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/CountPathsUsingTemplateRPCHandler.java
index 168208d86b976..f2ed0cc425c57 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/CountPathsUsingTemplateRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/CountPathsUsingTemplateRPCHandler.java
@@ -21,7 +21,7 @@
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.mpp.rpc.thrift.TCountPathsUsingTemplateResp;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -33,13 +33,13 @@
import java.util.concurrent.CountDownLatch;
public class CountPathsUsingTemplateRPCHandler
- extends AbstractAsyncRPCHandler {
+ extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER =
LoggerFactory.getLogger(CountPathsUsingTemplateRPCHandler.class);
public CountPathsUsingTemplateRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -53,15 +53,13 @@ public void onComplete(TCountPathsUsingTemplateResp response) {
TSStatus tsStatus = response.getStatus();
responseMap.put(requestId, response);
if (tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
- LOGGER.info("Successfully count paths using template on DataNode: {}", targetDataNode);
+ nodeLocationMap.remove(requestId);
+ LOGGER.info("Successfully count paths using template on DataNode: {}", targetNode);
} else if (tsStatus.getCode() == TSStatusCode.MULTIPLE_ERROR.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
- LOGGER.error(
- "Failed to count paths using template on DataNode {}, {}", targetDataNode, tsStatus);
+ nodeLocationMap.remove(requestId);
+ LOGGER.error("Failed to count paths using template on DataNode {}, {}", targetNode, tsStatus);
} else {
- LOGGER.error(
- "Failed to count paths using template on DataNode {}, {}", targetDataNode, tsStatus);
+ LOGGER.error("Failed to count paths using template on DataNode {}, {}", targetNode, tsStatus);
}
countDownLatch.countDown();
}
@@ -70,9 +68,9 @@ public void onComplete(TCountPathsUsingTemplateResp response) {
public void onError(Exception e) {
String errorMsg =
"Count paths using template error on DataNode: {id="
- + targetDataNode.getDataNodeId()
+ + targetNode.getDataNodeId()
+ ", internalEndPoint="
- + targetDataNode.getInternalEndPoint()
+ + targetNode.getInternalEndPoint()
+ "}"
+ e.getMessage();
LOGGER.error(errorMsg);
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/AsyncClientHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeAsyncRequestRPCHandler.java
similarity index 58%
rename from iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/AsyncClientHandler.java
rename to iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeAsyncRequestRPCHandler.java
index 1d5183fed5d59..5b26f4800b1e7 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/AsyncClientHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeAsyncRequestRPCHandler.java
@@ -17,20 +17,14 @@
* under the License.
*/
-package org.apache.iotdb.confignode.client.async.handlers;
+package org.apache.iotdb.confignode.client.async.handlers.rpc;
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.AbstractAsyncRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.AsyncTSStatusRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.CheckTimeSeriesExistenceRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.CountPathsUsingTemplateRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.FetchSchemaBlackListRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.PipeHeartbeatRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.PipePushMetaRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.SchemaUpdateRPCHandler;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.TransferLeaderRPCHandler;
+import org.apache.iotdb.common.rpc.thrift.TTestConnectionResp;
+import org.apache.iotdb.commons.client.request.AsyncRequestContext;
+import org.apache.iotdb.commons.client.request.AsyncRequestRPCHandler;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.CheckSchemaRegionUsingTemplateRPCHandler;
import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.ConsumerGroupPushMetaRPCHandler;
import org.apache.iotdb.confignode.client.async.handlers.rpc.subscription.TopicPushMetaRPCHandler;
@@ -44,129 +38,45 @@
import org.apache.iotdb.mpp.rpc.thrift.TPushTopicMetaResp;
import org.apache.iotdb.mpp.rpc.thrift.TRegionLeaderChangeResp;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
-/**
- * Asynchronous Client handler.
- *
- * @param ClassName of RPC request
- * @param ClassName of RPC response
- */
-public class AsyncClientHandler {
-
- // Type of RPC request
- protected final DataNodeRequestType requestType;
-
- /**
- * Map key: The indices of asynchronous RPC requests.
- *
- *
Map value: The corresponding RPC request
- */
- private final Map requestMap;
-
- /**
- * Map key: The indices of asynchronous RPC requests.
- *
- *
Map value: The target DataNodes of corresponding indices
- *
- *
All kinds of AsyncHandler will remove its targetDataNode from the dataNodeLocationMap only
- * if its corresponding RPC request success
- */
- private final Map dataNodeLocationMap;
-
- /**
- * Map key: The indices(targetDataNode's ID) of asynchronous RPC requests.
- *
- *
Map value: The response of corresponding indices
- *
- *
All kinds of AsyncHandler will add response to the responseMap after its corresponding RPC
- * request finished
- */
- private final Map responseMap;
-
- private CountDownLatch countDownLatch;
-
- /** Custom constructor. */
- public AsyncClientHandler(DataNodeRequestType requestType) {
- this.requestType = requestType;
- this.requestMap = new ConcurrentHashMap<>();
- this.dataNodeLocationMap = new ConcurrentHashMap<>();
- this.responseMap = new ConcurrentHashMap<>();
- }
-
- public void putRequest(int requestId, Q request) {
- requestMap.put(requestId, request);
- }
-
- public void putDataNodeLocation(int requestId, TDataNodeLocation dataNodeLocation) {
- dataNodeLocationMap.put(requestId, dataNodeLocation);
- }
-
- /** Constructor for null requests. */
- public AsyncClientHandler(
- DataNodeRequestType requestType, Map dataNodeLocationMap) {
- this.requestType = requestType;
- this.dataNodeLocationMap = dataNodeLocationMap;
-
- this.requestMap = new ConcurrentHashMap<>();
- this.responseMap = new ConcurrentHashMap<>();
- }
-
- /** Constructor for unique request. */
- public AsyncClientHandler(
- DataNodeRequestType requestType,
- Q request,
- Map dataNodeLocationMap) {
- this.requestType = requestType;
- this.dataNodeLocationMap = dataNodeLocationMap;
-
- this.requestMap = new ConcurrentHashMap<>();
- this.dataNodeLocationMap
- .keySet()
- .forEach(dataNodeId -> this.requestMap.put(dataNodeId, request));
-
- this.responseMap = new ConcurrentHashMap<>();
+public abstract class DataNodeAsyncRequestRPCHandler
+ extends AsyncRequestRPCHandler {
+
+ protected DataNodeAsyncRequestRPCHandler(
+ CnToDnRequestType requestType,
+ int requestId,
+ TDataNodeLocation targetNode,
+ Map dataNodeLocationMap,
+ Map integerResponseMap,
+ CountDownLatch countDownLatch) {
+ super(
+ requestType,
+ requestId,
+ targetNode,
+ dataNodeLocationMap,
+ integerResponseMap,
+ countDownLatch);
}
- public DataNodeRequestType getRequestType() {
- return requestType;
+ @Override
+ protected String generateFormattedTargetLocation(TDataNodeLocation dataNodeLocation) {
+ return "{id="
+ + targetNode.getDataNodeId()
+ + ", internalEndPoint="
+ + targetNode.getInternalEndPoint()
+ + "}";
}
- public List getRequestIndices() {
- return new ArrayList<>(dataNodeLocationMap.keySet());
- }
-
- public Q getRequest(int requestId) {
- return requestMap.get(requestId);
- }
-
- public TDataNodeLocation getDataNodeLocation(int requestId) {
- return dataNodeLocationMap.get(requestId);
- }
-
- public List getResponseList() {
- return new ArrayList<>(responseMap.values());
- }
-
- public Map getResponseMap() {
- return responseMap;
- }
-
- /** Always reset CountDownLatch before retry. */
- public void resetCountDownLatch() {
- countDownLatch = new CountDownLatch(dataNodeLocationMap.size());
- }
-
- public CountDownLatch getCountDownLatch() {
- return countDownLatch;
- }
-
- public AbstractAsyncRPCHandler> createAsyncRPCHandler(
- int requestId, TDataNodeLocation targetDataNode) {
+ public static DataNodeAsyncRequestRPCHandler> buildHandler(
+ AsyncRequestContext, ?, CnToDnRequestType, TDataNodeLocation> context,
+ int requestId,
+ TDataNodeLocation targetDataNode) {
+ CnToDnRequestType requestType = context.getRequestType();
+ Map dataNodeLocationMap = context.getNodeLocationMap();
+ Map responseMap = context.getResponseMap();
+ CountDownLatch countDownLatch = context.getCountDownLatch();
switch (requestType) {
case CONSTRUCT_SCHEMA_BLACK_LIST:
case ROLLBACK_SCHEMA_BLACK_LIST:
@@ -263,6 +173,14 @@ public AbstractAsyncRPCHandler> createAsyncRPCHandler(
dataNodeLocationMap,
(Map) responseMap,
countDownLatch);
+ case SUBMIT_TEST_CONNECTION_TASK:
+ return new SubmitTestConnectionTaskRPCHandler(
+ requestType,
+ requestId,
+ targetDataNode,
+ dataNodeLocationMap,
+ (Map) responseMap,
+ countDownLatch);
case SET_TTL:
case CREATE_DATA_REGION:
case CREATE_SCHEMA_REGION:
@@ -287,8 +205,9 @@ public AbstractAsyncRPCHandler> createAsyncRPCHandler(
case UPDATE_TABLE:
case KILL_QUERY_INSTANCE:
case RESET_PEER_LIST:
+ case TEST_CONNECTION:
default:
- return new AsyncTSStatusRPCHandler(
+ return new DataNodeTSStatusRPCHandler(
requestType,
requestId,
targetDataNode,
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeTSStatusRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeTSStatusRPCHandler.java
new file mode 100644
index 0000000000000..19d451eb671fb
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeTSStatusRPCHandler.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async.handlers.rpc;
+
+import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
+import org.apache.iotdb.rpc.RpcUtils;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/** General RPC handler for TSStatus response type. */
+public class DataNodeTSStatusRPCHandler extends DataNodeAsyncRequestRPCHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DataNodeTSStatusRPCHandler.class);
+
+ public DataNodeTSStatusRPCHandler(
+ CnToDnRequestType requestType,
+ int requestId,
+ TDataNodeLocation targetDataNode,
+ Map dataNodeLocationMap,
+ Map responseMap,
+ CountDownLatch countDownLatch) {
+ super(requestType, requestId, targetDataNode, dataNodeLocationMap, responseMap, countDownLatch);
+ }
+
+ @Override
+ public void onComplete(TSStatus response) {
+ // Put response
+ responseMap.put(requestId, response);
+
+ if (response.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ // Remove only if success
+ nodeLocationMap.remove(requestId);
+ LOGGER.info("Successfully {} on DataNode: {}", requestType, formattedTargetLocation);
+ } else {
+ LOGGER.error(
+ "Failed to {} on DataNode: {}, response: {}",
+ requestType,
+ formattedTargetLocation,
+ response);
+ }
+
+ // Always CountDown
+ countDownLatch.countDown();
+ }
+
+ @Override
+ public void onError(Exception e) {
+ String errorMsg =
+ "Failed to "
+ + requestType
+ + " on DataNode: "
+ + formattedTargetLocation
+ + ", exception: "
+ + e.getMessage();
+ LOGGER.error(errorMsg);
+
+ responseMap.put(
+ requestId,
+ new TSStatus(
+ RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode(), errorMsg)));
+
+ // Always CountDown
+ countDownLatch.countDown();
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/FetchSchemaBlackListRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/FetchSchemaBlackListRPCHandler.java
index e73e41322065f..45c659298ca30 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/FetchSchemaBlackListRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/FetchSchemaBlackListRPCHandler.java
@@ -21,7 +21,7 @@
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.mpp.rpc.thrift.TFetchSchemaBlackListResp;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -33,13 +33,13 @@
import java.util.concurrent.CountDownLatch;
public class FetchSchemaBlackListRPCHandler
- extends AbstractAsyncRPCHandler {
+ extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER =
LoggerFactory.getLogger(FetchSchemaBlackListRPCHandler.class);
public FetchSchemaBlackListRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -53,15 +53,15 @@ public void onComplete(TFetchSchemaBlackListResp tFetchSchemaBlackListResp) {
TSStatus tsStatus = tFetchSchemaBlackListResp.getStatus();
responseMap.put(requestId, tFetchSchemaBlackListResp);
if (tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
- LOGGER.info("Successfully fetch schemaengine black list on DataNode: {}", targetDataNode);
+ nodeLocationMap.remove(requestId);
+ LOGGER.info("Successfully fetch schemaengine black list on DataNode: {}", targetNode);
} else if (tsStatus.getCode() == TSStatusCode.MULTIPLE_ERROR.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
LOGGER.error(
- "Failed to fetch schemaengine black list on DataNode {}, {}", targetDataNode, tsStatus);
+ "Failed to fetch schemaengine black list on DataNode {}, {}", targetNode, tsStatus);
} else {
LOGGER.error(
- "Failed to fetch schemaengine black list on DataNode {}, {}", targetDataNode, tsStatus);
+ "Failed to fetch schemaengine black list on DataNode {}, {}", targetNode, tsStatus);
}
countDownLatch.countDown();
}
@@ -70,9 +70,9 @@ public void onComplete(TFetchSchemaBlackListResp tFetchSchemaBlackListResp) {
public void onError(Exception e) {
String errorMsg =
"Fetch schemaengine black list error on DataNode: {id="
- + targetDataNode.getDataNodeId()
+ + targetNode.getDataNodeId()
+ ", internalEndPoint="
- + targetDataNode.getInternalEndPoint()
+ + targetNode.getInternalEndPoint()
+ "}"
+ e.getMessage();
LOGGER.error(errorMsg);
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/PipeHeartbeatRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/PipeHeartbeatRPCHandler.java
index ff235a38bd084..ec4968cfa06dd 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/PipeHeartbeatRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/PipeHeartbeatRPCHandler.java
@@ -20,7 +20,7 @@
package org.apache.iotdb.confignode.client.async.handlers.rpc;
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.mpp.rpc.thrift.TPipeHeartbeatResp;
import org.slf4j.Logger;
@@ -29,12 +29,12 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
-public class PipeHeartbeatRPCHandler extends AbstractAsyncRPCHandler {
+public class PipeHeartbeatRPCHandler extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(PipeHeartbeatRPCHandler.class);
public PipeHeartbeatRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -47,7 +47,7 @@ public PipeHeartbeatRPCHandler(
public void onComplete(TPipeHeartbeatResp response) {
// Put response
responseMap.put(requestId, response);
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
LOGGER.info("Successfully {} on DataNode: {}", requestType, formattedTargetLocation);
// Always CountDown
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/PipePushMetaRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/PipePushMetaRPCHandler.java
index 774e914de367e..3517bbeb93ea3 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/PipePushMetaRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/PipePushMetaRPCHandler.java
@@ -20,7 +20,7 @@
package org.apache.iotdb.confignode.client.async.handlers.rpc;
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.mpp.rpc.thrift.TPushPipeMetaResp;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -31,11 +31,11 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
-public class PipePushMetaRPCHandler extends AbstractAsyncRPCHandler {
+public class PipePushMetaRPCHandler extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(PipePushMetaRPCHandler.class);
public PipePushMetaRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -60,7 +60,7 @@ public void onComplete(TPushPipeMetaResp response) {
}
// Always remove to avoid retrying
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
// Always CountDown
countDownLatch.countDown();
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SchemaUpdateRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SchemaUpdateRPCHandler.java
index 3980e6e0c1b52..db8458a948ce3 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SchemaUpdateRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SchemaUpdateRPCHandler.java
@@ -21,7 +21,7 @@
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -31,12 +31,12 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
-public class SchemaUpdateRPCHandler extends AsyncTSStatusRPCHandler {
+public class SchemaUpdateRPCHandler extends DataNodeTSStatusRPCHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(SchemaUpdateRPCHandler.class);
public SchemaUpdateRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -50,10 +50,10 @@ public void onComplete(TSStatus tsStatus) {
responseMap.put(requestId, tsStatus);
LOGGER.info("{} for {} receives: {}", requestType, requestId, tsStatus);
if (tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
LOGGER.info("Successfully {} on DataNode: {}", requestType, formattedTargetLocation);
} else if (tsStatus.getCode() == TSStatusCode.MULTIPLE_ERROR.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
LOGGER.warn(
"Failed to {} on DataNode {}, {}", requestType, formattedTargetLocation, tsStatus);
} else {
@@ -68,9 +68,9 @@ public void onError(Exception e) {
String errorMsg =
requestType
+ " error on DataNode: {id="
- + targetDataNode.getDataNodeId()
+ + targetNode.getDataNodeId()
+ ", internalEndPoint="
- + targetDataNode.getInternalEndPoint()
+ + targetNode.getInternalEndPoint()
+ "}"
+ e.getMessage();
LOGGER.warn(errorMsg);
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SubmitTestConnectionTaskRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SubmitTestConnectionTaskRPCHandler.java
new file mode 100644
index 0000000000000..4abf0a0eca114
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SubmitTestConnectionTaskRPCHandler.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async.handlers.rpc;
+
+import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.common.rpc.thrift.TTestConnectionResp;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+public class SubmitTestConnectionTaskRPCHandler
+ extends DataNodeAsyncRequestRPCHandler {
+
+ private static final Logger LOGGER =
+ LoggerFactory.getLogger(SubmitTestConnectionTaskRPCHandler.class);
+
+ public SubmitTestConnectionTaskRPCHandler(
+ CnToDnRequestType requestType,
+ int requestId,
+ TDataNodeLocation targetDataNode,
+ Map dataNodeLocationMap,
+ Map responseMap,
+ CountDownLatch countDownLatch) {
+ super(requestType, requestId, targetDataNode, dataNodeLocationMap, responseMap, countDownLatch);
+ }
+
+ @Override
+ public void onComplete(TTestConnectionResp resp) {
+ responseMap.put(requestId, resp);
+ nodeLocationMap.remove(requestId);
+ countDownLatch.countDown();
+ }
+
+ @Override
+ public void onError(Exception e) {
+ responseMap.put(
+ requestId,
+ new TTestConnectionResp()
+ .setStatus(
+ new TSStatus(TSStatusCode.CAN_NOT_CONNECT_DATANODE.getStatusCode())
+ .setMessage(e.getMessage())));
+ nodeLocationMap.remove(requestId);
+ countDownLatch.countDown();
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SubmitTestConnectionTaskToConfigNodeRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SubmitTestConnectionTaskToConfigNodeRPCHandler.java
new file mode 100644
index 0000000000000..d26984fd0a70d
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/SubmitTestConnectionTaskToConfigNodeRPCHandler.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.client.async.handlers.rpc;
+
+import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.common.rpc.thrift.TTestConnectionResp;
+import org.apache.iotdb.confignode.client.CnToCnNodeRequestType;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+public class SubmitTestConnectionTaskToConfigNodeRPCHandler
+ extends ConfigNodeAsyncRequestRPCHandler {
+
+ private static final Logger LOGGER =
+ LoggerFactory.getLogger(SubmitTestConnectionTaskToConfigNodeRPCHandler.class);
+
+ public SubmitTestConnectionTaskToConfigNodeRPCHandler(
+ CnToCnNodeRequestType requestType,
+ int requestId,
+ TConfigNodeLocation targetConfigNode,
+ Map configNodeLocationMap,
+ Map responseMap,
+ CountDownLatch countDownLatch) {
+ super(
+ requestType,
+ requestId,
+ targetConfigNode,
+ configNodeLocationMap,
+ responseMap,
+ countDownLatch);
+ }
+
+ @Override
+ public void onComplete(TTestConnectionResp resp) {
+ responseMap.put(requestId, resp);
+ nodeLocationMap.remove(requestId);
+ countDownLatch.countDown();
+ }
+
+ @Override
+ public void onError(Exception e) {
+ responseMap.put(
+ requestId,
+ new TTestConnectionResp()
+ .setStatus(
+ new TSStatus(TSStatusCode.CAN_NOT_CONNECT_CONFIGNODE.getStatusCode())
+ .setMessage(e.getMessage())));
+ nodeLocationMap.remove(requestId);
+ countDownLatch.countDown();
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/TransferLeaderRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/TransferLeaderRPCHandler.java
index d5107e315cf19..352cc0694e2bf 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/TransferLeaderRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/TransferLeaderRPCHandler.java
@@ -20,7 +20,7 @@
package org.apache.iotdb.confignode.client.async.handlers.rpc;
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.mpp.rpc.thrift.TRegionLeaderChangeResp;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -31,12 +31,13 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
-public class TransferLeaderRPCHandler extends AbstractAsyncRPCHandler {
+public class TransferLeaderRPCHandler
+ extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(TransferLeaderRPCHandler.class);
public TransferLeaderRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -52,7 +53,7 @@ public void onComplete(TRegionLeaderChangeResp response) {
if (response.getStatus().getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
// Remove only if success
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
LOGGER.info("Successfully {} on DataNode: {}", requestType, formattedTargetLocation);
} else {
LOGGER.error(
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/CheckSchemaRegionUsingTemplateRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/CheckSchemaRegionUsingTemplateRPCHandler.java
index ad69516299219..14898dcdc6c9c 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/CheckSchemaRegionUsingTemplateRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/CheckSchemaRegionUsingTemplateRPCHandler.java
@@ -21,8 +21,8 @@
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.AbstractAsyncRPCHandler;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.DataNodeAsyncRequestRPCHandler;
import org.apache.iotdb.mpp.rpc.thrift.TCheckSchemaRegionUsingTemplateResp;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -34,13 +34,13 @@
import java.util.concurrent.CountDownLatch;
public class CheckSchemaRegionUsingTemplateRPCHandler
- extends AbstractAsyncRPCHandler {
+ extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER =
LoggerFactory.getLogger(CheckSchemaRegionUsingTemplateRPCHandler.class);
public CheckSchemaRegionUsingTemplateRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -54,20 +54,15 @@ public void onComplete(TCheckSchemaRegionUsingTemplateResp response) {
TSStatus tsStatus = response.getStatus();
responseMap.put(requestId, response);
if (tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
- LOGGER.info(
- "Successfully check schema region using template on DataNode: {}", targetDataNode);
+ nodeLocationMap.remove(requestId);
+ LOGGER.info("Successfully check schema region using template on DataNode: {}", targetNode);
} else if (tsStatus.getCode() == TSStatusCode.MULTIPLE_ERROR.getStatusCode()) {
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
LOGGER.error(
- "Failed to check schema region using template on DataNode {}, {}",
- targetDataNode,
- tsStatus);
+ "Failed to check schema region using template on DataNode {}, {}", targetNode, tsStatus);
} else {
LOGGER.error(
- "Failed to check schema region using template on DataNode {}, {}",
- targetDataNode,
- tsStatus);
+ "Failed to check schema region using template on DataNode {}, {}", targetNode, tsStatus);
}
countDownLatch.countDown();
}
@@ -76,9 +71,9 @@ public void onComplete(TCheckSchemaRegionUsingTemplateResp response) {
public void onError(Exception e) {
String errorMsg =
"Count paths using template error on DataNode: {id="
- + targetDataNode.getDataNodeId()
+ + targetNode.getDataNodeId()
+ ", internalEndPoint="
- + targetDataNode.getInternalEndPoint()
+ + targetNode.getInternalEndPoint()
+ "}"
+ e.getMessage();
LOGGER.error(errorMsg);
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/ConsumerGroupPushMetaRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/ConsumerGroupPushMetaRPCHandler.java
index 52f5063101f2d..ee3c11eeb427b 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/ConsumerGroupPushMetaRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/ConsumerGroupPushMetaRPCHandler.java
@@ -20,8 +20,8 @@
package org.apache.iotdb.confignode.client.async.handlers.rpc.subscription;
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.AbstractAsyncRPCHandler;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.DataNodeAsyncRequestRPCHandler;
import org.apache.iotdb.mpp.rpc.thrift.TPushConsumerGroupMetaResp;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -33,12 +33,12 @@
import java.util.concurrent.CountDownLatch;
public class ConsumerGroupPushMetaRPCHandler
- extends AbstractAsyncRPCHandler {
+ extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER =
LoggerFactory.getLogger(ConsumerGroupPushMetaRPCHandler.class);
public ConsumerGroupPushMetaRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -63,7 +63,7 @@ public void onComplete(TPushConsumerGroupMetaResp response) {
}
// Always remove to avoid retrying
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
// Always CountDown
countDownLatch.countDown();
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/TopicPushMetaRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/TopicPushMetaRPCHandler.java
index 39cb9cd23e975..cf8451feaacad 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/TopicPushMetaRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/subscription/TopicPushMetaRPCHandler.java
@@ -20,8 +20,8 @@
package org.apache.iotdb.confignode.client.async.handlers.rpc.subscription;
import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
-import org.apache.iotdb.confignode.client.async.handlers.rpc.AbstractAsyncRPCHandler;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
+import org.apache.iotdb.confignode.client.async.handlers.rpc.DataNodeAsyncRequestRPCHandler;
import org.apache.iotdb.mpp.rpc.thrift.TPushTopicMetaResp;
import org.apache.iotdb.rpc.RpcUtils;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -32,12 +32,12 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
-public class TopicPushMetaRPCHandler extends AbstractAsyncRPCHandler {
+public class TopicPushMetaRPCHandler extends DataNodeAsyncRequestRPCHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(TopicPushMetaRPCHandler.class);
public TopicPushMetaRPCHandler(
- DataNodeRequestType requestType,
+ CnToDnRequestType requestType,
int requestId,
TDataNodeLocation targetDataNode,
Map dataNodeLocationMap,
@@ -62,7 +62,7 @@ public void onComplete(TPushTopicMetaResp response) {
}
// Always remove to avoid retrying
- dataNodeLocationMap.remove(requestId);
+ nodeLocationMap.remove(requestId);
// Always CountDown
countDownLatch.countDown();
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncConfigNodeClientPool.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncConfigNodeClientPool.java
index ab85a9badcb9e..cc26be000a8eb 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncConfigNodeClientPool.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncConfigNodeClientPool.java
@@ -21,13 +21,14 @@
import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TEndPoint;
+import org.apache.iotdb.common.rpc.thrift.TNodeLocations;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.common.rpc.thrift.TSetConfigurationReq;
import org.apache.iotdb.commons.client.ClientPoolFactory;
import org.apache.iotdb.commons.client.IClientManager;
import org.apache.iotdb.commons.client.exception.ClientManagerException;
import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient;
-import org.apache.iotdb.confignode.client.ConfigNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToCnNodeRequestType;
import org.apache.iotdb.confignode.rpc.thrift.TAddConsensusGroupReq;
import org.apache.iotdb.confignode.rpc.thrift.TConfigNodeRegisterReq;
import org.apache.iotdb.rpc.RpcUtils;
@@ -66,7 +67,7 @@ private void updateConfigNodeLeader(TSStatus status) {
}
public Object sendSyncRequestToConfigNodeWithRetry(
- TEndPoint endPoint, Object req, ConfigNodeRequestType requestType) {
+ TEndPoint endPoint, Object req, CnToCnNodeRequestType requestType) {
Throwable lastException = null;
for (int retry = 0; retry < MAX_RETRY_NUM; retry++) {
@@ -91,6 +92,12 @@ public Object sendSyncRequestToConfigNodeWithRetry(
return client.stopConfigNode((TConfigNodeLocation) req);
case SET_CONFIGURATION:
return client.setConfiguration((TSetConfigurationReq) req);
+ case SHOW_CONFIGURATION:
+ return client.showConfiguration((int) req);
+ case SUBMIT_TEST_CONNECTION_TASK:
+ return client.submitTestConnectionTask((TNodeLocations) req);
+ case TEST_CONNECTION:
+ return client.testConnectionEmptyRPC();
default:
return RpcUtils.getStatus(
TSStatusCode.EXECUTE_STATEMENT_ERROR, "Unknown request type: " + requestType);
@@ -145,7 +152,6 @@ private void doRetryWait(int retryNum) {
}
}
- // TODO: Is the ClientPool must be a singleton?
private static class SyncConfigNodeClientPoolHolder {
private static final SyncConfigNodeClientPool INSTANCE = new SyncConfigNodeClientPool();
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncDataNodeClientPool.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncDataNodeClientPool.java
index 86afa20d6acc2..be366b5772bc4 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncDataNodeClientPool.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncDataNodeClientPool.java
@@ -27,7 +27,7 @@
import org.apache.iotdb.commons.client.IClientManager;
import org.apache.iotdb.commons.client.exception.ClientManagerException;
import org.apache.iotdb.commons.client.sync.SyncDataNodeInternalServiceClient;
-import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
import org.apache.iotdb.mpp.rpc.thrift.TCreateDataRegionReq;
import org.apache.iotdb.mpp.rpc.thrift.TCreatePeerReq;
import org.apache.iotdb.mpp.rpc.thrift.TCreateSchemaRegionReq;
@@ -66,7 +66,7 @@ private SyncDataNodeClientPool() {
}
public Object sendSyncRequestToDataNodeWithRetry(
- TEndPoint endPoint, Object req, DataNodeRequestType requestType) {
+ TEndPoint endPoint, Object req, CnToDnRequestType requestType) {
Throwable lastException = new TException();
for (int retry = 0; retry < DEFAULT_RETRY_NUM; retry++) {
try (SyncDataNodeInternalServiceClient client = clientManager.borrowClient(endPoint)) {
@@ -85,7 +85,7 @@ public Object sendSyncRequestToDataNodeWithRetry(
}
public Object sendSyncRequestToDataNodeWithGivenRetry(
- TEndPoint endPoint, Object req, DataNodeRequestType requestType, int retryNum) {
+ TEndPoint endPoint, Object req, CnToDnRequestType requestType, int retryNum) {
Throwable lastException = new TException();
for (int retry = 0; retry < retryNum; retry++) {
try (SyncDataNodeInternalServiceClient client = clientManager.borrowClient(endPoint)) {
@@ -104,7 +104,7 @@ public Object sendSyncRequestToDataNodeWithGivenRetry(
}
private Object executeSyncRequest(
- DataNodeRequestType requestType, SyncDataNodeInternalServiceClient client, Object req)
+ CnToDnRequestType requestType, SyncDataNodeInternalServiceClient client, Object req)
throws TException {
switch (requestType) {
case INVALIDATE_PARTITION_CACHE:
@@ -192,7 +192,6 @@ public TRegionLeaderChangeResp changeRegionLeader(
return new TRegionLeaderChangeResp(status, -1L);
}
- // TODO: Is the ClientPool must be a singleton?
private static class ClientPoolHolder {
private static final SyncDataNodeClientPool INSTANCE = new SyncDataNodeClientPool();
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeConfig.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeConfig.java
index 99017b4f10c8d..603892e368114 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeConfig.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeConfig.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.confignode.conf;
+import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TEndPoint;
import org.apache.iotdb.commons.client.property.ClientPoolProperty.DefaultProperty;
import org.apache.iotdb.commons.conf.IoTDBConstant;
@@ -1196,4 +1197,18 @@ public void setDataRegionRatisPeriodicSnapshotInterval(
long dataRegionRatisPeriodicSnapshotInterval) {
this.dataRegionRatisPeriodicSnapshotInterval = dataRegionRatisPeriodicSnapshotInterval;
}
+
+ public TConfigNodeLocation generateLocalConfigNodeLocationWithSpecifiedNodeId(int configNodeId) {
+ return new TConfigNodeLocation(
+ configNodeId,
+ new TEndPoint(getInternalAddress(), getInternalPort()),
+ new TEndPoint(getInternalAddress(), getConsensusPort()));
+ }
+
+ public TConfigNodeLocation generateLocalConfigNodeLocation() {
+ return new TConfigNodeLocation(
+ getConfigNodeId(),
+ new TEndPoint(getInternalAddress(), getInternalPort()),
+ new TEndPoint(getInternalAddress(), getConsensusPort()));
+ }
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeRemoveCheck.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeRemoveCheck.java
index bdbbdc43c7a96..9c4c480b02cea 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeRemoveCheck.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeRemoveCheck.java
@@ -25,7 +25,7 @@
import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.commons.exception.BadNodeUrlException;
import org.apache.iotdb.commons.utils.NodeUrlUtils;
-import org.apache.iotdb.confignode.client.ConfigNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToCnNodeRequestType;
import org.apache.iotdb.confignode.client.sync.SyncConfigNodeClientPool;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -112,7 +112,7 @@ public void removeConfigNode(TConfigNodeLocation removedNode)
.sendSyncRequestToConfigNodeWithRetry(
configNodeLocation.getInternalEndPoint(),
removedNode,
- ConfigNodeRequestType.REMOVE_CONFIG_NODE);
+ CnToCnNodeRequestType.REMOVE_CONFIG_NODE);
if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
break;
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeStartupCheck.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeStartupCheck.java
index 88be42eb417f0..9a42264ed937e 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeStartupCheck.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeStartupCheck.java
@@ -146,7 +146,7 @@ private void checkGlobalConfig() throws ConfigurationException {
// When the schemaengine region consensus protocol is set to PipeConsensus,
// we should report an error
if (CONF.getSchemaRegionConsensusProtocolClass().equals(ConsensusFactory.FAST_IOT_CONSENSUS)
- || CONF.getSchemaRegionConsensusProtocolClass().equals(ConsensusFactory.IOTV2_CONSENSUS)) {
+ || CONF.getSchemaRegionConsensusProtocolClass().equals(ConsensusFactory.IOT_CONSENSUS_V2)) {
throw new ConfigurationException(
"schema_region_consensus_protocol_class",
String.valueOf(CONF.getSchemaRegionConsensusProtocolClass()),
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeSystemPropertiesHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeSystemPropertiesHandler.java
new file mode 100644
index 0000000000000..b92e2e57e05d6
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/ConfigNodeSystemPropertiesHandler.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.confignode.conf;
+
+import org.apache.iotdb.commons.file.SystemPropertiesHandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+public class ConfigNodeSystemPropertiesHandler extends SystemPropertiesHandler {
+ private static final Logger LOGGER =
+ LoggerFactory.getLogger(ConfigNodeSystemPropertiesHandler.class);
+
+ private static ConfigNodeSystemPropertiesHandler INSTANCE;
+
+ private ConfigNodeSystemPropertiesHandler(String filePath) {
+ super(filePath);
+ }
+
+ public static synchronized SystemPropertiesHandler getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE =
+ new ConfigNodeSystemPropertiesHandler(
+ ConfigNodeDescriptor.getInstance().getConf().getSystemDir()
+ + File.separator
+ + ConfigNodeConstant.SYSTEM_FILE_NAME);
+ INSTANCE.recover();
+ }
+ return INSTANCE;
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/SystemPropertiesUtils.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/SystemPropertiesUtils.java
index ba9d74a641cd4..a56f4a63f7296 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/SystemPropertiesUtils.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/conf/SystemPropertiesUtils.java
@@ -24,18 +24,14 @@
import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.commons.exception.BadNodeUrlException;
+import org.apache.iotdb.commons.file.SystemPropertiesHandler;
import org.apache.iotdb.commons.utils.NodeUrlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -48,11 +44,8 @@ public class SystemPropertiesUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(SystemPropertiesUtils.class);
- private static File systemPropertiesFile =
- new File(
- ConfigNodeDescriptor.getInstance().getConf().getSystemDir()
- + File.separator
- + ConfigNodeConstant.SYSTEM_FILE_NAME);
+ private static SystemPropertiesHandler systemPropertiesHandler =
+ ConfigNodeSystemPropertiesHandler.getInstance();
private static final ConfigNodeConfig conf = ConfigNodeDescriptor.getInstance().getConf();
private static final CommonConfig COMMON_CONFIG = CommonDescriptor.getInstance().getConfig();
@@ -74,11 +67,10 @@ private SystemPropertiesUtils() {
// TODO: This needs removal of statics ...
public static void reinitializeStatics() {
- systemPropertiesFile =
- new File(
- ConfigNodeDescriptor.getInstance().getConf().getSystemDir()
- + File.separator
- + ConfigNodeConstant.SYSTEM_FILE_NAME);
+ systemPropertiesHandler.resetFilePath(
+ ConfigNodeDescriptor.getInstance().getConf().getSystemDir()
+ + File.separator
+ + ConfigNodeConstant.SYSTEM_FILE_NAME);
}
/**
@@ -87,7 +79,7 @@ public static void reinitializeStatics() {
* @return True if confignode-system.properties file exist.
*/
public static boolean isRestarted() {
- return systemPropertiesFile.exists();
+ return !systemPropertiesHandler.isFirstStart();
}
/**
@@ -97,7 +89,7 @@ public static boolean isRestarted() {
* @throws IOException When read the confignode-system.properties file failed
*/
public static void checkSystemProperties() throws IOException {
- Properties systemProperties = getSystemProperties();
+ Properties systemProperties = systemPropertiesHandler.read();
boolean needReWrite = false;
final String format =
"[SystemProperties] The parameter \"{}\" can't be modified after first startup."
@@ -234,11 +226,6 @@ public static void checkSystemProperties() throws IOException {
COMMON_CONFIG.setTimePartitionInterval(timePartitionInterval);
}
}
-
- if (needReWrite) {
- // Re-write special parameters if necessary
- storeSystemParameters();
- }
}
/**
@@ -251,7 +238,7 @@ public static void checkSystemProperties() throws IOException {
*/
public static List loadConfigNodeList()
throws IOException, BadNodeUrlException {
- Properties systemProperties = getSystemProperties();
+ Properties systemProperties = systemPropertiesHandler.read();
String addresses = systemProperties.getProperty("config_node_list", null);
if (addresses != null && !addresses.isEmpty()) {
@@ -265,10 +252,10 @@ public static List loadConfigNodeList()
* The system parameters can't be changed after the ConfigNode first started. Therefore, store
* them in confignode-system.properties during the first startup.
*
- * @throws IOException getSystemProperties()
+ * @throws IOException systemPropertiesHandler.read()
*/
public static void storeSystemParameters() throws IOException {
- Properties systemProperties = getSystemProperties();
+ Properties systemProperties = systemPropertiesHandler.read();
systemProperties.setProperty("iotdb_version", IoTDBConstant.VERSION);
systemProperties.setProperty("commit_id", IoTDBConstant.BUILD_INFO);
@@ -311,7 +298,7 @@ public static void storeSystemParameters() throws IOException {
systemProperties.setProperty(
"tag_attribute_total_size", String.valueOf(COMMON_CONFIG.getTagAttributeTotalSize()));
- storeSystemProperties(systemProperties);
+ systemPropertiesHandler.overwrite(systemProperties);
}
/**
@@ -321,7 +308,7 @@ public static void storeSystemParameters() throws IOException {
* @throws IOException When store confignode-system.properties file failed
*/
public static void storeConfigNodeList(List configNodes) throws IOException {
- if (!systemPropertiesFile.exists()) {
+ if (!systemPropertiesHandler.fileExist()) {
// Avoid creating confignode-system.properties files during
// synchronizing the ApplyConfigNode logs from the ConsensusLayer.
// 1. For the Non-Seed-ConfigNode, We don't need to create confignode-system.properties file
@@ -330,12 +317,8 @@ public static void storeConfigNodeList(List configNodes) th
// in which case the latest config_node_list will be updated.
return;
}
-
- Properties systemProperties = getSystemProperties();
- systemProperties.setProperty(
+ systemPropertiesHandler.put(
"config_node_list", NodeUrlUtils.convertTConfigNodeUrls(configNodes));
-
- storeSystemProperties(systemProperties);
}
/**
@@ -346,7 +329,7 @@ public static void storeConfigNodeList(List configNodes) th
* @throws IOException When load confignode-system.properties file failed
*/
public static String loadClusterNameWhenRestarted() throws IOException {
- Properties systemProperties = getSystemProperties();
+ Properties systemProperties = systemPropertiesHandler.read();
String clusterName = systemProperties.getProperty(CLUSTER_NAME, null);
if (clusterName == null) {
LOGGER.warn(
@@ -366,7 +349,7 @@ public static String loadClusterNameWhenRestarted() throws IOException {
* @throws IOException When load confignode-system.properties file failed
*/
public static int loadConfigNodeIdWhenRestarted() throws IOException {
- Properties systemProperties = getSystemProperties();
+ Properties systemProperties = systemPropertiesHandler.read();
try {
return Integer.parseInt(systemProperties.getProperty("config_node_id", null));
} catch (NumberFormatException e) {
@@ -387,7 +370,7 @@ public static int loadConfigNodeIdWhenRestarted() throws IOException {
*/
public static boolean isSeedConfigNode() {
try {
- Properties systemProperties = getSystemProperties();
+ Properties systemProperties = systemPropertiesHandler.read();
boolean isSeedConfigNode =
Boolean.parseBoolean(systemProperties.getProperty("is_seed_config_node", null));
if (isSeedConfigNode) {
@@ -399,37 +382,4 @@ public static boolean isSeedConfigNode() {
return false;
}
}
-
- private static synchronized Properties getSystemProperties() throws IOException {
- // Create confignode-system.properties file if necessary
- if (!systemPropertiesFile.exists()) {
- if (systemPropertiesFile.createNewFile()) {
- LOGGER.info(
- "System properties file {} for ConfigNode is created.",
- systemPropertiesFile.getAbsolutePath());
- } else {
- LOGGER.error(
- "Can't create the system properties file {} for ConfigNode. "
- + "IoTDB-ConfigNode is shutdown.",
- systemPropertiesFile.getAbsolutePath());
- throw new IOException("Can't create system properties file");
- }
- }
-
- Properties systemProperties = new Properties();
- try (FileInputStream inputStream = new FileInputStream(systemPropertiesFile)) {
- systemProperties.load(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
- }
- return systemProperties;
- }
-
- private static synchronized void storeSystemProperties(Properties systemProperties)
- throws IOException {
- try (FileOutputStream fileOutputStream = new FileOutputStream(systemPropertiesFile)) {
- systemProperties.store(
- new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8),
- " THIS FILE IS AUTOMATICALLY GENERATED. PLEASE DO NOT MODIFY THIS FILE !!!");
- fileOutputStream.getFD().sync();
- }
- }
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/ttl/ShowTTLPlan.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/ttl/ShowTTLPlan.java
index c37c93a907659..9dd9eded31eb8 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/ttl/ShowTTLPlan.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/read/ttl/ShowTTLPlan.java
@@ -20,14 +20,27 @@
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import org.apache.iotdb.db.utils.constant.SqlConstant;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class ShowTTLPlan extends ConfigPhysicalPlan {
+ private String[] pathPattern;
+
+ public String[] getPathPattern() {
+ return pathPattern;
+ }
+
public ShowTTLPlan() {
super(ConfigPhysicalPlanType.ShowTTL);
+ this.pathPattern = SqlConstant.getSingleRootArray();
+ }
+
+ public ShowTTLPlan(String[] pathPattern) {
+ super(ConfigPhysicalPlanType.ShowTTL);
+ this.pathPattern = pathPattern;
}
@Override
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/datanode/DataNodeRegisterResp.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/datanode/DataNodeRegisterResp.java
index ef7d4f212b261..2cbcb15a90129 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/datanode/DataNodeRegisterResp.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/datanode/DataNodeRegisterResp.java
@@ -32,13 +32,13 @@
import java.io.IOException;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
public class DataNodeRegisterResp implements DataSet {
private TSStatus status;
private List configNodeList;
private Integer dataNodeId;
-
private TRuntimeConfiguration runtimeConfiguration;
public DataNodeRegisterResp() {
@@ -85,8 +85,8 @@ public TDataNodeRegisterResp convertToRpcDataNodeRegisterResp() {
resp.setConfigNodeList(configNodeList);
if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
- resp.setDataNodeId(dataNodeId);
- resp.setRuntimeConfiguration(runtimeConfiguration);
+ Optional.ofNullable(dataNodeId).ifPresent(resp::setDataNodeId);
+ Optional.ofNullable(runtimeConfiguration).ifPresent(resp::setRuntimeConfiguration);
}
return resp;
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ClusterManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ClusterManager.java
index 9781f77c02448..808112cff4cd4 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ClusterManager.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ClusterManager.java
@@ -19,14 +19,41 @@
package org.apache.iotdb.confignode.manager;
+import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TDataNodeConfiguration;
+import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TEndPoint;
+import org.apache.iotdb.common.rpc.thrift.TNodeLocations;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.common.rpc.thrift.TSender;
+import org.apache.iotdb.common.rpc.thrift.TServiceProvider;
+import org.apache.iotdb.common.rpc.thrift.TServiceType;
+import org.apache.iotdb.common.rpc.thrift.TTestConnectionResp;
+import org.apache.iotdb.common.rpc.thrift.TTestConnectionResult;
+import org.apache.iotdb.commons.client.request.AsyncRequestContext;
+import org.apache.iotdb.commons.client.request.Utils;
+import org.apache.iotdb.confignode.client.CnToCnNodeRequestType;
+import org.apache.iotdb.confignode.client.CnToDnRequestType;
+import org.apache.iotdb.confignode.client.async.CnToCnInternalServiceAsyncRequestManager;
+import org.apache.iotdb.confignode.client.async.CnToDnInternalServiceAsyncRequestManager;
+import org.apache.iotdb.confignode.client.async.handlers.ConfigNodeAsyncRequestContext;
+import org.apache.iotdb.confignode.client.async.handlers.DataNodeAsyncRequestContext;
+import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
import org.apache.iotdb.confignode.consensus.request.write.confignode.UpdateClusterIdPlan;
import org.apache.iotdb.confignode.persistence.ClusterInfo;
import org.apache.iotdb.consensus.exception.ConsensusException;
+import org.apache.iotdb.rpc.TSStatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
public class ClusterManager {
@@ -79,4 +106,198 @@ private void generateClusterId() {
LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
}
}
+
+ // TODO: Parallel test ConfigNode and DataNode
+ public TTestConnectionResp submitTestConnectionTaskToEveryNode() {
+ TTestConnectionResp resp = new TTestConnectionResp();
+ resp.resultList = new ArrayList<>();
+ resp.setStatus(new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()));
+ TNodeLocations nodeLocations = new TNodeLocations();
+ nodeLocations.setConfigNodeLocations(configManager.getNodeManager().getRegisteredConfigNodes());
+ nodeLocations.setDataNodeLocations(
+ configManager.getNodeManager().getRegisteredDataNodes().stream()
+ .map(TDataNodeConfiguration::getLocation)
+ .collect(Collectors.toList()));
+ // For ConfigNode
+ Map configNodeLocationMap =
+ configManager.getNodeManager().getRegisteredConfigNodes().stream()
+ .collect(Collectors.toMap(TConfigNodeLocation::getConfigNodeId, location -> location));
+ ConfigNodeAsyncRequestContext
+ configNodeAsyncRequestContext =
+ new ConfigNodeAsyncRequestContext<>(
+ CnToCnNodeRequestType.SUBMIT_TEST_CONNECTION_TASK,
+ nodeLocations,
+ configNodeLocationMap);
+ CnToCnInternalServiceAsyncRequestManager.getInstance()
+ .sendAsyncRequest(configNodeAsyncRequestContext);
+ Map anotherConfigNodeLocationMap =
+ configManager.getNodeManager().getRegisteredConfigNodes().stream()
+ .collect(Collectors.toMap(TConfigNodeLocation::getConfigNodeId, location -> location));
+ configNodeAsyncRequestContext
+ .getResponseMap()
+ .forEach(
+ (nodeId, configNodeResp) -> {
+ if (configNodeResp.isSetResultList()) {
+ resp.getResultList().addAll(configNodeResp.getResultList());
+ } else {
+ resp.getResultList()
+ .addAll(
+ badConfigNodeConnectionResult(
+ configNodeResp.getStatus(),
+ anotherConfigNodeLocationMap.get(nodeId),
+ nodeLocations));
+ }
+ });
+ // For DataNode
+ Map dataNodeLocationMap =
+ configManager.getNodeManager().getRegisteredDataNodes().stream()
+ .map(TDataNodeConfiguration::getLocation)
+ .collect(Collectors.toMap(TDataNodeLocation::getDataNodeId, location -> location));
+ DataNodeAsyncRequestContext dataNodeAsyncRequestContext =
+ new DataNodeAsyncRequestContext<>(
+ CnToDnRequestType.SUBMIT_TEST_CONNECTION_TASK, nodeLocations, dataNodeLocationMap);
+ CnToDnInternalServiceAsyncRequestManager.getInstance()
+ .sendAsyncRequest(dataNodeAsyncRequestContext);
+ Map anotherDataNodeLocationMap =
+ configManager.getNodeManager().getRegisteredDataNodes().stream()
+ .map(TDataNodeConfiguration::getLocation)
+ .collect(Collectors.toMap(TDataNodeLocation::getDataNodeId, location -> location));
+ dataNodeAsyncRequestContext
+ .getResponseMap()
+ .forEach(
+ (nodeId, dataNodeResp) -> {
+ if (dataNodeResp.isSetResultList()) {
+ resp.getResultList().addAll(dataNodeResp.getResultList());
+ } else {
+ resp.getResultList()
+ .addAll(
+ badDataNodeConnectionResult(
+ dataNodeResp.getStatus(),
+ anotherDataNodeLocationMap.get(nodeId),
+ nodeLocations));
+ }
+ });
+ return resp;
+ }
+
+ public TTestConnectionResp doConnectionTest(TNodeLocations nodeLocations) {
+ return new TTestConnectionResp(
+ new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()),
+ Stream.of(
+ testAllConfigNodeConnection(nodeLocations.getConfigNodeLocations()),
+ testAllDataNodeConnection(nodeLocations.getDataNodeLocations()))
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList()));
+ }
+
+ private List testAllConfigNodeConnection(
+ List configNodeLocations) {
+ final TSender sender =
+ new TSender()
+ .setConfigNodeLocation(
+ ConfigNodeDescriptor.getInstance().getConf().generateLocalConfigNodeLocation());
+ return Utils.testConnectionsImpl(
+ configNodeLocations,
+ sender,
+ TConfigNodeLocation::getConfigNodeId,
+ TConfigNodeLocation::getInternalEndPoint,
+ TServiceType.ConfigNodeInternalService,
+ CnToCnNodeRequestType.TEST_CONNECTION,
+ (AsyncRequestContext