This is an automated email from the ASF dual-hosted git repository.
jt2594838 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 7ffb1364b84 Add mutual SSL support for pipe sinks (#18080)
7ffb1364b84 is described below
commit 7ffb1364b843cfe13aaa57d693922adf333155eb
Author: Caideyipi <[email protected]>
AuthorDate: Mon Jul 13 17:28:31 2026 +0800
Add mutual SSL support for pipe sinks (#18080)
* Add mutual SSL support for pipe sinks
* Fix JDBC default user handling
* Update IoTDBPipeMutualSSLIT.java
* Validate SSL store aliases consistently
* Clarify SSL alias validation messages
* Move pipe SSL validation messages to i18n bundles
---
.../treemodel/auto/basic/IoTDBPipeMutualSSLIT.java | 176 +++++++++++++++++++
.../api/customizer/parameter/PipeParameters.java | 1 +
.../customizer/parameter/PipeParametersTest.java | 12 ++
.../org/apache/iotdb/jdbc/IoTDBConnection.java | 2 +-
.../client/IoTDBConfigNodeSyncClientManager.java | 4 +
.../pipe/sink/protocol/IoTDBConfigRegionSink.java | 4 +
.../pipe/sink/IoTDBConfigRegionSinkTest.java | 46 +++++
.../apache/iotdb/db/i18n/DataNodePipeMessages.java | 6 +
.../apache/iotdb/db/i18n/DataNodePipeMessages.java | 6 +-
.../client/IoTDBDataNodeSyncClientManager.java | 4 +
.../sink/protocol/legacy/IoTDBLegacyPipeSink.java | 123 +++++++++++--
.../thrift/async/IoTDBDataRegionAsyncSink.java | 27 ++-
.../thrift/sync/IoTDBDataNodeSyncSink.java | 4 +
.../apache/iotdb/db/pipe/sink/PipeSinkTest.java | 193 +++++++++++++++++++++
.../apache/iotdb/commons/i18n/PipeMessages.java | 6 +
.../apache/iotdb/commons/i18n/PipeMessages.java | 4 +
.../pipe/config/constant/PipeSinkConstant.java | 10 ++
.../commons/pipe/sink/client/IoTDBSyncClient.java | 17 +-
.../pipe/sink/client/IoTDBSyncClientManager.java | 10 +-
.../pipe/sink/protocol/IoTDBSslSyncSink.java | 125 +++++++++++--
20 files changed, 748 insertions(+), 32 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/basic/IoTDBPipeMutualSSLIT.java
b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/basic/IoTDBPipeMutualSSLIT.java
new file mode 100644
index 00000000000..6362cca567c
--- /dev/null
+++
b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/basic/IoTDBPipeMutualSSLIT.java
@@ -0,0 +1,176 @@
+/*
+ * 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.pipe.it.dual.treemodel.auto.basic;
+
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient;
+import org.apache.iotdb.confignode.rpc.thrift.TCreatePipeReq;
+import org.apache.iotdb.db.it.utils.TestUtils;
+import org.apache.iotdb.isession.SessionConfig;
+import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.MultiClusterIT2DualTreeAutoBasic;
+import org.apache.iotdb.jdbc.Config;
+import
org.apache.iotdb.pipe.it.dual.treemodel.auto.AbstractPipeDualTreeModelAutoIT;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+import org.awaitility.Awaitility;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({MultiClusterIT2DualTreeAutoBasic.class})
+public class IoTDBPipeMutualSSLIT extends AbstractPipeDualTreeModelAutoIT {
+
+ private static final String STORE_PASSWORD = "thrift";
+
+ @Override
+ protected void setupConfig() {
+ super.setupConfig();
+
+ senderEnv
+ .getConfig()
+ .getCommonConfig()
+ .setTrustStorePath(trustStorePath())
+ .setTrustStorePwd(STORE_PASSWORD)
+ .setSslProtocol(SessionConfig.DEFAULT_SSL_PROTOCOL);
+ receiverEnv
+ .getConfig()
+ .getCommonConfig()
+ .setEnableThriftClientSSL(true)
+ .setThriftSSLClientAuth(true)
+ .setKeyStorePath(keyStorePath())
+ .setKeyStorePwd(STORE_PASSWORD)
+ .setTrustStorePath(trustStorePath())
+ .setTrustStorePwd(STORE_PASSWORD)
+ .setSslProtocol(SessionConfig.DEFAULT_SSL_PROTOCOL);
+ }
+
+ @Test
+ public void testPipeCanTransferWithMutualSSL() throws Exception {
+ final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
+
+ try (final SyncConfigNodeIServiceClient client =
+ (SyncConfigNodeIServiceClient)
senderEnv.getLeaderConfigNodeConnection()) {
+ TestUtils.executeNonQueries(
+ senderEnv,
+ Arrays.asList(
+ "insert into root.pipe_mtls.d1(time, s1) values (1, 11)",
+ "insert into root.pipe_mtls.d1(time, s1) values (2, 22)",
+ "flush"),
+ null);
+
+ final Map<String, String> sourceAttributes = new HashMap<>();
+ final Map<String, String> sinkAttributes = new HashMap<>();
+
+ sourceAttributes.put("source.realtime.mode", "log");
+ sourceAttributes.put("source.user", "root");
+
+ sinkAttributes.put("sink", "iotdb-thrift-ssl-sink");
+ sinkAttributes.put("sink.batch.enable", "false");
+ sinkAttributes.put("sink.ip", receiverDataNode.getIp());
+ sinkAttributes.put("sink.port",
Integer.toString(receiverDataNode.getPort()));
+ sinkAttributes.put("sink.ssl.trust-store-path", trustStorePath());
+ sinkAttributes.put("sink.ssl.trust-store-pwd", STORE_PASSWORD);
+ sinkAttributes.put("sink.ssl.key-store-path", keyStorePath());
+ sinkAttributes.put("sink.ssl.key-store-pwd", STORE_PASSWORD);
+
+ final TSStatus status =
+ client.createPipe(
+ new TCreatePipeReq("testPipe", sinkAttributes)
+ .setExtractorAttributes(sourceAttributes));
+ Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
status.getCode());
+
+ TestUtils.executeNonQueries(
+ senderEnv,
+ Arrays.asList("insert into root.pipe_mtls.d1(time, s1) values (3,
33)", "flush"),
+ null);
+
+ try (final Connection connection =
+ DriverManager.getConnection(
+ Config.IOTDB_URL_PREFIX
+ + receiverDataNode.getIpAndPortString()
+ + "?"
+ + Config.USE_SSL
+ + "=true&"
+ + Config.TRUST_STORE
+ + "="
+ + trustStorePath()
+ + "&"
+ + Config.TRUST_STORE_PWD
+ + "="
+ + STORE_PASSWORD
+ + "&"
+ + Config.KEY_STORE
+ + "="
+ + keyStorePath()
+ + "&"
+ + Config.KEY_STORE_PWD
+ + "="
+ + STORE_PASSWORD,
+ SessionConfig.DEFAULT_USER,
+ SessionConfig.DEFAULT_PASSWORD);
+ final Statement statement = connection.createStatement()) {
+ Awaitility.await()
+ .pollInSameThread()
+ .pollDelay(1L, TimeUnit.SECONDS)
+ .pollInterval(1L, TimeUnit.SECONDS)
+ .atMost(600, TimeUnit.SECONDS)
+ .untilAsserted(
+ () ->
+ TestUtils.assertResultSetEqual(
+ statement.executeQuery("select s1 from
root.pipe_mtls.d1"),
+ "Time,root.pipe_mtls.d1.s1,",
+ Collections.unmodifiableSet(
+ new HashSet<>(Arrays.asList("1,11.0,", "2,22.0,",
"3,33.0,")))));
+ }
+ }
+ }
+
+ private static String keyStorePath() {
+ return keyDir() + "test-keystore";
+ }
+
+ private static String trustStorePath() {
+ return keyDir() + "test-truststore";
+ }
+
+ private static String keyDir() {
+ return System.getProperty("user.dir")
+ + File.separator
+ + "target"
+ + File.separator
+ + "test-classes"
+ + File.separator;
+ }
+}
diff --git
a/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/customizer/parameter/PipeParameters.java
b/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/customizer/parameter/PipeParameters.java
index 7286d120991..16a1329a6bf 100644
---
a/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/customizer/parameter/PipeParameters.java
+++
b/iotdb-api/pipe-api/src/main/java/org/apache/iotdb/pipe/api/customizer/parameter/PipeParameters.java
@@ -430,6 +430,7 @@ public class PipeParameters {
static {
KEYS.add("ssl.trust-store-pwd");
+ KEYS.add("ssl.key-store-pwd");
KEYS.add("scp.password");
KEYS.add("password");
}
diff --git
a/iotdb-api/pipe-api/src/test/java/org/apache/iotdb/pipe/api/customizer/parameter/PipeParametersTest.java
b/iotdb-api/pipe-api/src/test/java/org/apache/iotdb/pipe/api/customizer/parameter/PipeParametersTest.java
index d16b8e2879d..98eed48eace 100644
---
a/iotdb-api/pipe-api/src/test/java/org/apache/iotdb/pipe/api/customizer/parameter/PipeParametersTest.java
+++
b/iotdb-api/pipe-api/src/test/java/org/apache/iotdb/pipe/api/customizer/parameter/PipeParametersTest.java
@@ -39,4 +39,16 @@ public class PipeParametersTest {
parameters.addAttribute("opcua.sink.value-name", "false");
Assert.assertNull(parameters.getString("value-name"));
}
+
+ @Test
+ public void valueHiderShouldHideSslKeyStorePassword() {
+ Assert.assertEquals(
+ "******", PipeParameters.ValueHider.hide("sink.ssl.key-store-pwd",
"secret"));
+ Assert.assertEquals(
+ "******",
PipeParameters.ValueHider.hide("connector.ssl.key-store-pwd", "secret"));
+ Assert.assertEquals("******",
PipeParameters.ValueHider.hide("ssl.key-store-pwd", "secret"));
+ Assert.assertEquals(
+ "******",
PipeParameters.ValueHider.hide("connector.ssl.trust-store-pwd", "secret"));
+ Assert.assertEquals("secret",
PipeParameters.ValueHider.hide("ssl.key-store-path", "secret"));
+ }
}
diff --git
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
index 1192ceff25e..bf04cf69355 100644
--- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
+++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
@@ -129,7 +129,7 @@ public class IoTDBConnection implements Connection {
}
params = Utils.parseUrl(url, info);
this.url = url;
- this.userName = info.get("user").toString();
+ this.userName = params.getUsername();
this.networkTimeout = params.getNetworkTimeout();
this.zoneId = ZoneId.of(params.getTimeZone());
this.charset = params.getCharset();
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/sink/client/IoTDBConfigNodeSyncClientManager.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/sink/client/IoTDBConfigNodeSyncClientManager.java
index c579fad73c1..25c0bc58b61 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/sink/client/IoTDBConfigNodeSyncClientManager.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/sink/client/IoTDBConfigNodeSyncClientManager.java
@@ -39,6 +39,8 @@ public class IoTDBConfigNodeSyncClientManager extends
IoTDBSyncClientManager {
boolean useSSL,
String trustStorePath,
String trustStorePwd,
+ String keyStorePath,
+ String keyStorePwd,
/* The following parameters are used locally. */
String loadBalanceStrategy,
/* The following parameters are used to handshake with the receiver. */
@@ -54,6 +56,8 @@ public class IoTDBConfigNodeSyncClientManager extends
IoTDBSyncClientManager {
useSSL,
trustStorePath,
trustStorePwd,
+ keyStorePath,
+ keyStorePwd,
false,
loadBalanceStrategy,
userEntity,
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/sink/protocol/IoTDBConfigRegionSink.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/sink/protocol/IoTDBConfigRegionSink.java
index 07e64321de7..636e28a455e 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/sink/protocol/IoTDBConfigRegionSink.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/sink/protocol/IoTDBConfigRegionSink.java
@@ -68,6 +68,8 @@ public class IoTDBConfigRegionSink extends IoTDBSslSyncSink {
final boolean useSSL,
final String trustStorePath,
final String trustStorePwd,
+ final String keyStorePath,
+ final String keyStorePwd,
/* The following parameters are used locally. */
final boolean useLeaderCache,
final String loadBalanceStrategy,
@@ -84,6 +86,8 @@ public class IoTDBConfigRegionSink extends IoTDBSslSyncSink {
useSSL,
Objects.nonNull(trustStorePath) ?
ConfigNodeConfig.addHomeDir(trustStorePath) : null,
trustStorePwd,
+ Objects.nonNull(keyStorePath) ?
ConfigNodeConfig.addHomeDir(keyStorePath) : null,
+ keyStorePwd,
loadBalanceStrategy,
userEntity,
password,
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/sink/IoTDBConfigRegionSinkTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/sink/IoTDBConfigRegionSinkTest.java
index b88862c4cae..01b7c1de668 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/sink/IoTDBConfigRegionSinkTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/sink/IoTDBConfigRegionSinkTest.java
@@ -51,4 +51,50 @@ public class IoTDBConfigRegionSinkTest {
Assert.fail();
}
}
+
+ @Test
+ public void testIoTDBConfigRegionSinkAcceptsMutualSslParameters() {
+ try (IoTDBConfigRegionSink connector = new IoTDBConfigRegionSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.CONNECTOR_KEY,
+
BuiltinPipePlugin.IOTDB_THRIFT_SSL_CONNECTOR.getPipePluginName());
+ put(PipeSinkConstant.CONNECTOR_IOTDB_NODE_URLS_KEY,
"127.0.0.1:6668");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY, "trustpwd");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY, "keystore");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY, "keypwd");
+ }
+ })));
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testIoTDBConfigRegionSinkRejectsIncompleteKeyStoreParameters() {
+ try (IoTDBConfigRegionSink connector = new IoTDBConfigRegionSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.CONNECTOR_KEY,
+
BuiltinPipePlugin.IOTDB_THRIFT_SSL_CONNECTOR.getPipePluginName());
+ put(PipeSinkConstant.CONNECTOR_IOTDB_NODE_URLS_KEY,
"127.0.0.1:6668");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY, "trustpwd");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY, "keystore");
+ }
+ })));
+ Assert.fail();
+ } catch (Exception e) {
+
Assert.assertTrue(e.getMessage().contains(PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PWD_KEY));
+ }
+ }
}
diff --git
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodePipeMessages.java
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodePipeMessages.java
index 4dbdbd8803f..4297e241712 100644
---
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodePipeMessages.java
+++
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodePipeMessages.java
@@ -945,6 +945,12 @@ public final class DataNodePipeMessages {
"Network failed to receive tsFile %s, status: %s";
public static final String SECURITY_DIR = "security dir: {}";
public static final String SECURITY_PKI_DIR = "security pki dir: {}";
+ public static final String SSL_TRUST_STORE_PAIR_REQUIRED_WHEN_SSL_ENABLED =
+ "When %s or %s is true, specify a complete trust-store pair under the
same "
+ + "alias: %s and %s, %s and %s, or %s and %s";
+ public static final String
SSL_KEY_STORE_PATH_AND_PASSWORD_MUST_BE_SPECIFIED_TOGETHER =
+ "SSL key-store path and password must be specified together under the
same "
+ + "alias: %s and %s, %s and %s, or %s and %s";
public static final String SUCCESSFULLY_ADDED_ITEM = "Successfully added
item {}.";
public static final String SUCCESSFULLY_CONVERTED_PROGID_TO_CLSID =
"Successfully converted progID {} to CLSID: {{}}";
diff --git
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodePipeMessages.java
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodePipeMessages.java
index f97169709a7..1b38041791d 100644
---
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodePipeMessages.java
+++
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodePipeMessages.java
@@ -887,11 +887,15 @@ public final class DataNodePipeMessages {
public static final String RECEIVED_A_BIND_MESSAGE_FROM = "从 {}:{} 收到 bind
消息";
public static final String REDIRECT_FILE_POSITION_TO = "重定向 file position 到
{}。";
public static final String REDIRECT_TO_POSITION_IN_TRANSFERRING_TSFILE =
- "正在传输的 tsFile {} 中重定向到 position {}。";
+ "重定向到 position {},正在传输的 TsFile 为 {}。";
public static final String NETWORK_FAILED_TO_RECEIVE_TSFILE_STATUS =
"网络接收 TsFile %s 失败,状态:%s";
public static final String SECURITY_DIR = "security 目录:{}";
public static final String SECURITY_PKI_DIR = "security pki 目录:{}";
+ public static final String SSL_TRUST_STORE_PAIR_REQUIRED_WHEN_SSL_ENABLED =
+ "当 %s 或 %s 为 true 时,请在同一别名下指定完整的 trust-store 参数对:%s 和 %s、%s 和 %s,或 %s 和
%s";
+ public static final String
SSL_KEY_STORE_PATH_AND_PASSWORD_MUST_BE_SPECIFIED_TOGETHER =
+ "SSL key-store 路径和密码必须在同一别名下同时指定:%s 和 %s、%s 和 %s,或 %s 和 %s";
public static final String SUCCESSFULLY_ADDED_ITEM = "成功添加 item {}。";
public static final String SUCCESSFULLY_CONVERTED_PROGID_TO_CLSID =
"成功将 progID {} 转换为 CLSID: {{}}";
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/client/IoTDBDataNodeSyncClientManager.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/client/IoTDBDataNodeSyncClientManager.java
index 841982accd3..df966c78acc 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/client/IoTDBDataNodeSyncClientManager.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/client/IoTDBDataNodeSyncClientManager.java
@@ -49,6 +49,8 @@ public class IoTDBDataNodeSyncClientManager extends
IoTDBSyncClientManager
final boolean useSSL,
final String trustStorePath,
final String trustStorePwd,
+ final String keyStorePath,
+ final String keyStorePwd,
/* The following parameters are used locally. */
final boolean useLeaderCache,
final String loadBalanceStrategy,
@@ -65,6 +67,8 @@ public class IoTDBDataNodeSyncClientManager extends
IoTDBSyncClientManager
useSSL,
trustStorePath,
trustStorePwd,
+ keyStorePath,
+ keyStorePwd,
useLeaderCache,
loadBalanceStrategy,
userEntity,
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/legacy/IoTDBLegacyPipeSink.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/legacy/IoTDBLegacyPipeSink.java
index bf37e02c8d5..a74cfcbd2d8 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/legacy/IoTDBLegacyPipeSink.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/legacy/IoTDBLegacyPipeSink.java
@@ -83,6 +83,11 @@ import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CON
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_PASSWORD_DEFAULT_VALUE;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_PASSWORD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_PORT_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_ENABLE_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SYNC_CONNECTOR_VERSION_DEFAULT_VALUE;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SYNC_CONNECTOR_VERSION_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_USERNAME_KEY;
@@ -92,6 +97,8 @@ import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SIN
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_PASSWORD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_PORT_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_ENABLE_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SYNC_CONNECTOR_VERSION_KEY;
@@ -112,6 +119,8 @@ public class IoTDBLegacyPipeSink implements PipeConnector {
private boolean useSSL;
private String trustStore;
private String trustStorePwd;
+ private String keyStore;
+ private String keyStorePwd;
private String user;
private String password;
@@ -149,13 +158,88 @@ public class IoTDBLegacyPipeSink implements PipeConnector
{
.validate(
args -> !((boolean) args[0]) || ((boolean) args[1] && (boolean)
args[2]),
String.format(
- "When %s is specified to true, %s and %s must be specified",
+
DataNodePipeMessages.SSL_TRUST_STORE_PAIR_REQUIRED_WHEN_SSL_ENABLED,
+ CONNECTOR_IOTDB_SSL_ENABLE_KEY,
SINK_IOTDB_SSL_ENABLE_KEY,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY,
+
PipeParameters.KeyReducer.reduce(CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY),
+
PipeParameters.KeyReducer.reduce(CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY)),
+ parameters.getBooleanOrDefault(
+ Arrays.asList(CONNECTOR_IOTDB_SSL_ENABLE_KEY,
SINK_IOTDB_SSL_ENABLE_KEY), false),
+ hasCompleteAttributePair(
+ parameters,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY),
- parameters.getBooleanOrDefault(SINK_IOTDB_SSL_ENABLE_KEY, false),
- parameters.hasAttribute(SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY),
- parameters.hasAttribute(SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY));
+ hasNoHalfAttributePair(
+ parameters,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY))
+ .validate(
+ args -> (boolean) args[0] == (boolean) args[1],
+ String.format(
+
DataNodePipeMessages.SSL_KEY_STORE_PATH_AND_PASSWORD_MUST_BE_SPECIFIED_TOGETHER,
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_KEY_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_KEY_STORE_PWD_KEY,
+
PipeParameters.KeyReducer.reduce(CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY),
+
PipeParameters.KeyReducer.reduce(CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY)),
+ true,
+ hasNoHalfAttributePair(
+ parameters,
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_KEY_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_KEY_STORE_PWD_KEY));
+ }
+
+ private static boolean hasCompleteAttributePair(
+ final PipeParameters parameters,
+ final String connectorLeftKey,
+ final String connectorRightKey,
+ final String sinkLeftKey,
+ final String sinkRightKey) {
+ return hasExactAttributePair(parameters, connectorLeftKey,
connectorRightKey)
+ || hasExactAttributePair(parameters, sinkLeftKey, sinkRightKey)
+ || hasExactAttributePair(
+ parameters,
+ PipeParameters.KeyReducer.reduce(connectorLeftKey),
+ PipeParameters.KeyReducer.reduce(connectorRightKey));
+ }
+
+ private static boolean hasNoHalfAttributePair(
+ final PipeParameters parameters,
+ final String connectorLeftKey,
+ final String connectorRightKey,
+ final String sinkLeftKey,
+ final String sinkRightKey) {
+ return hasBothOrNoneExactAttributes(parameters, connectorLeftKey,
connectorRightKey)
+ && hasBothOrNoneExactAttributes(parameters, sinkLeftKey, sinkRightKey)
+ && hasBothOrNoneExactAttributes(
+ parameters,
+ PipeParameters.KeyReducer.reduce(connectorLeftKey),
+ PipeParameters.KeyReducer.reduce(connectorRightKey));
+ }
+
+ private static boolean hasExactAttributePair(
+ final PipeParameters parameters, final String leftKey, final String
rightKey) {
+ return hasExactAttribute(parameters, leftKey) &&
hasExactAttribute(parameters, rightKey);
+ }
+
+ private static boolean hasBothOrNoneExactAttributes(
+ final PipeParameters parameters, final String leftKey, final String
rightKey) {
+ return hasExactAttribute(parameters, leftKey) ==
hasExactAttribute(parameters, rightKey);
+ }
+
+ private static boolean hasExactAttribute(final PipeParameters parameters,
final String key) {
+ return parameters.getAttribute().containsKey(key);
}
private Set<TEndPoint> parseNodeUrls(final PipeParameters parameters) {
@@ -208,9 +292,21 @@ public class IoTDBLegacyPipeSink implements PipeConnector {
pipeName = configuration.getRuntimeEnvironment().getPipeName();
- useSSL = parameters.getBooleanOrDefault(SINK_IOTDB_SSL_ENABLE_KEY, false);
- trustStore = parameters.getString(SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY);
- trustStorePwd = parameters.getString(SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY);
+ useSSL =
+ parameters.getBooleanOrDefault(
+ Arrays.asList(CONNECTOR_IOTDB_SSL_ENABLE_KEY,
SINK_IOTDB_SSL_ENABLE_KEY), false);
+ trustStore =
+ parameters.getStringByKeys(
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY);
+ trustStorePwd =
+ parameters.getStringByKeys(
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY);
+ keyStore =
+ parameters.getStringByKeys(
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY,
SINK_IOTDB_SSL_KEY_STORE_PATH_KEY);
+ keyStorePwd =
+ parameters.getStringByKeys(
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY,
SINK_IOTDB_SSL_KEY_STORE_PWD_KEY);
final DataRegion dataRegion =
StorageEngine.getInstance()
@@ -235,7 +331,9 @@ public class IoTDBLegacyPipeSink implements PipeConnector {
port,
useSSL,
trustStore,
- trustStorePwd);
+ trustStorePwd,
+ keyStore,
+ keyStorePwd);
openClientSession();
final TSyncIdentityInfo identityInfo =
new TSyncIdentityInfo(
@@ -254,7 +352,7 @@ public class IoTDBLegacyPipeSink implements PipeConnector {
String.format(PipeConnectionException.CONNECTION_ERROR_FORMATTER,
ipAddress, port), e);
}
- sessionPool =
+ final SessionPool.Builder builder =
new SessionPool.Builder()
.host(ipAddress)
.port(port)
@@ -263,8 +361,11 @@ public class IoTDBLegacyPipeSink implements PipeConnector {
.maxSize(1)
.useSSL(useSSL)
.trustStore(trustStore)
- .trustStorePwd(trustStorePwd)
- .build();
+ .trustStorePwd(trustStorePwd);
+ if (keyStore != null) {
+ builder.keyStore(keyStore).keyStorePwd(keyStorePwd);
+ }
+ sessionPool = builder.build();
}
private void openClientSession() throws TException {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/thrift/async/IoTDBDataRegionAsyncSink.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/thrift/async/IoTDBDataRegionAsyncSink.java
index 213e43ab0b8..90e602af511 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/thrift/async/IoTDBDataRegionAsyncSink.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/thrift/async/IoTDBDataRegionAsyncSink.java
@@ -93,10 +93,17 @@ import java.util.concurrent.atomic.AtomicLong;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_ENABLE_SEND_TSFILE_LIMIT;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_ENABLE_SEND_TSFILE_LIMIT_DEFAULT_VALUE;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_ENABLE_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_LEADER_CACHE_ENABLE_DEFAULT_VALUE;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_LEADER_CACHE_ENABLE_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_ENABLE_SEND_TSFILE_LIMIT;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_ENABLE_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_LEADER_CACHE_ENABLE_KEY;
@@ -151,11 +158,23 @@ public class IoTDBDataRegionAsyncSink extends IoTDBSink
implements PipeSinkWithS
final PipeParameters parameters = validator.getParameters();
validator.validate(
- args -> !((boolean) args[0] || (boolean) args[1] || (boolean) args[2]),
+ args ->
+ !((boolean) args[0]
+ || (boolean) args[1]
+ || (boolean) args[2]
+ || (boolean) args[3]
+ || (boolean) args[4]),
"Only 'iotdb-thrift-ssl-sink' supports SSL transmission currently.",
- parameters.getBooleanOrDefault(SINK_IOTDB_SSL_ENABLE_KEY, false),
- parameters.hasAttribute(SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY),
- parameters.hasAttribute(SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY));
+ parameters.getBooleanOrDefault(
+ Arrays.asList(CONNECTOR_IOTDB_SSL_ENABLE_KEY,
SINK_IOTDB_SSL_ENABLE_KEY), false),
+ parameters.hasAnyAttributes(
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY),
+ parameters.hasAnyAttributes(
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY),
+ parameters.hasAnyAttributes(
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY,
SINK_IOTDB_SSL_KEY_STORE_PATH_KEY),
+ parameters.hasAnyAttributes(
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY,
SINK_IOTDB_SSL_KEY_STORE_PWD_KEY));
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/thrift/sync/IoTDBDataNodeSyncSink.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/thrift/sync/IoTDBDataNodeSyncSink.java
index 72486d6c4e7..ff32bbbb06f 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/thrift/sync/IoTDBDataNodeSyncSink.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/protocol/thrift/sync/IoTDBDataNodeSyncSink.java
@@ -43,6 +43,8 @@ public abstract class IoTDBDataNodeSyncSink extends
IoTDBSslSyncSink {
final boolean useSSL,
final String trustStorePath,
final String trustStorePwd,
+ final String keyStorePath,
+ final String keyStorePwd,
/* The following parameters are used locally. */
final boolean useLeaderCache,
final String loadBalanceStrategy,
@@ -60,6 +62,8 @@ public abstract class IoTDBDataNodeSyncSink extends
IoTDBSslSyncSink {
useSSL,
Objects.nonNull(trustStorePath) ?
IoTDBConfig.addDataHomeDir(trustStorePath) : null,
trustStorePwd,
+ Objects.nonNull(keyStorePath) ?
IoTDBConfig.addDataHomeDir(keyStorePath) : null,
+ keyStorePwd,
useLeaderCache,
loadBalanceStrategy,
userEntity,
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/sink/PipeSinkTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/sink/PipeSinkTest.java
index fa18695ef1f..34bfc83763b 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/sink/PipeSinkTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/sink/PipeSinkTest.java
@@ -114,6 +114,199 @@ public class PipeSinkTest {
}
}
+ @Test
+ public void testIoTDBThriftSyncSslSinkAcceptsMutualSslParameters() {
+ try (final IoTDBDataRegionSyncSink connector = new
IoTDBDataRegionSyncSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.SINK_KEY,
+
BuiltinPipePlugin.IOTDB_THRIFT_SSL_SINK.getPipePluginName());
+ put(PipeSinkConstant.SINK_IOTDB_IP_KEY, "127.0.0.1");
+ put(PipeSinkConstant.SINK_IOTDB_PORT_KEY, "6668");
+
put(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY,
"trustpwd");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PATH_KEY,
"keystore");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PWD_KEY,
"keypwd");
+ }
+ })));
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void
testIoTDBThriftSyncSslConnectorAcceptsConnectorMutualSslAliases() {
+ try (final IoTDBDataRegionSyncSink connector = new
IoTDBDataRegionSyncSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.CONNECTOR_KEY,
+
BuiltinPipePlugin.IOTDB_THRIFT_SSL_CONNECTOR.getPipePluginName());
+ put(PipeSinkConstant.CONNECTOR_IOTDB_IP_KEY,
"127.0.0.1");
+ put(PipeSinkConstant.CONNECTOR_IOTDB_PORT_KEY, "6668");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY, "trustpwd");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY, "keystore");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY, "keypwd");
+ }
+ })));
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testIoTDBThriftSyncSslSinkRejectsIncompleteKeyStoreParameters() {
+ try (final IoTDBDataRegionSyncSink connector = new
IoTDBDataRegionSyncSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.SINK_KEY,
+
BuiltinPipePlugin.IOTDB_THRIFT_SSL_SINK.getPipePluginName());
+ put(PipeSinkConstant.SINK_IOTDB_IP_KEY, "127.0.0.1");
+ put(PipeSinkConstant.SINK_IOTDB_PORT_KEY, "6668");
+
put(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY,
"trustpwd");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PATH_KEY,
"keystore");
+ }
+ })));
+ Assert.fail();
+ } catch (Exception e) {
+
Assert.assertTrue(e.getMessage().contains(PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PWD_KEY));
+ }
+ }
+
+ @Test
+ public void
testIoTDBThriftSyncSslSinkRejectsCrossAliasTrustStoreParameters() {
+ try (final IoTDBDataRegionSyncSink connector = new
IoTDBDataRegionSyncSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.CONNECTOR_KEY,
+
BuiltinPipePlugin.IOTDB_THRIFT_SSL_CONNECTOR.getPipePluginName());
+ put(PipeSinkConstant.CONNECTOR_IOTDB_IP_KEY,
"127.0.0.1");
+ put(PipeSinkConstant.CONNECTOR_IOTDB_PORT_KEY, "6668");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY,
"trustpwd");
+ }
+ })));
+ Assert.fail();
+ } catch (Exception e) {
+ Assert.assertTrue(
+
e.getMessage().contains(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY));
+ }
+ }
+
+ @Test
+ public void testIoTDBThriftSyncSslSinkRejectsCrossAliasKeyStoreParameters() {
+ try (final IoTDBDataRegionSyncSink connector = new
IoTDBDataRegionSyncSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.SINK_KEY,
+
BuiltinPipePlugin.IOTDB_THRIFT_SSL_SINK.getPipePluginName());
+ put(PipeSinkConstant.SINK_IOTDB_IP_KEY, "127.0.0.1");
+ put(PipeSinkConstant.SINK_IOTDB_PORT_KEY, "6668");
+
put(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY,
"trustpwd");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY, "keystore");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PWD_KEY,
"keypwd");
+ }
+ })));
+ Assert.fail();
+ } catch (Exception e) {
+
Assert.assertTrue(e.getMessage().contains(PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PWD_KEY));
+ }
+ }
+
+ @Test
+ public void testIoTDBThriftAsyncSinkRejectsSslKeyStoreParameters() {
+ try (final IoTDBDataRegionAsyncSink connector = new
IoTDBDataRegionAsyncSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.CONNECTOR_KEY,
+
BuiltinPipePlugin.IOTDB_THRIFT_ASYNC_CONNECTOR.getPipePluginName());
+ put(PipeSinkConstant.CONNECTOR_IOTDB_NODE_URLS_KEY,
"127.0.0.1:6668");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY, "keystore");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY, "keypwd");
+ }
+ })));
+ Assert.fail();
+ } catch (Exception e) {
+ Assert.assertTrue(e.getMessage().contains("Only 'iotdb-thrift-ssl-sink'
supports SSL"));
+ }
+ }
+
+ @Test
+ public void testIoTDBLegacyPipeSinkAcceptsConnectorMutualSslAliases() {
+ try (final IoTDBLegacyPipeSink connector = new IoTDBLegacyPipeSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.CONNECTOR_KEY,
+
BuiltinPipePlugin.IOTDB_LEGACY_PIPE_CONNECTOR.getPipePluginName());
+ put(PipeSinkConstant.CONNECTOR_IOTDB_IP_KEY,
"127.0.0.1");
+ put(PipeSinkConstant.CONNECTOR_IOTDB_PORT_KEY, "6668");
+ put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_ENABLE_KEY,
Boolean.TRUE.toString());
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY, "trustpwd");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY, "keystore");
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY, "keypwd");
+ }
+ })));
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void testIoTDBLegacyPipeSinkRejectsCrossAliasSslParameters() {
+ try (final IoTDBLegacyPipeSink connector = new IoTDBLegacyPipeSink()) {
+ connector.validate(
+ new PipeParameterValidator(
+ new PipeParameters(
+ new HashMap<String, String>() {
+ {
+ put(
+ PipeSinkConstant.CONNECTOR_KEY,
+
BuiltinPipePlugin.IOTDB_LEGACY_PIPE_CONNECTOR.getPipePluginName());
+ put(PipeSinkConstant.CONNECTOR_IOTDB_IP_KEY,
"127.0.0.1");
+ put(PipeSinkConstant.CONNECTOR_IOTDB_PORT_KEY, "6668");
+ put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_ENABLE_KEY,
Boolean.TRUE.toString());
+
put(PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY, "truststore");
+ put(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY,
"trustpwd");
+ }
+ })));
+ Assert.fail();
+ } catch (Exception e) {
+ Assert.assertTrue(
+
e.getMessage().contains(PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY));
+ }
+ }
+
@Test
public void testAsyncSinkDropDoesNotRequeueDroppedPipeEvents() throws
Exception {
try (final IoTDBDataRegionAsyncSink connector = new
IoTDBDataRegionAsyncSink()) {
diff --git
a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/PipeMessages.java
b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/PipeMessages.java
index eb38e3524a2..696bb4485a9 100644
---
a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/PipeMessages.java
+++
b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/PipeMessages.java
@@ -484,6 +484,12 @@ public final class PipeMessages {
// ===================== IoTDBSslSyncSink =====================
+ public static final String SSL_TRUST_STORE_PAIR_REQUIRED_WHEN_SSL_ENABLED =
+ "When ssl transport is enabled, specify a complete trust-store pair
under the same "
+ + "alias: %s and %s, %s and %s, or %s and %s";
+ public static final String
SSL_KEY_STORE_PATH_AND_PASSWORD_MUST_BE_SPECIFIED_TOGETHER =
+ "SSL key-store path and password must be specified together under the
same "
+ + "alias: %s and %s, %s and %s, or %s and %s";
public static final String SYNC_CLIENT_MANAGER_CLOSED =
"IoTDB sync client manager has been closed";
public static final String REDIRECT_FILE_POSITION = "Redirect file position
to {}.";
diff --git
a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/PipeMessages.java
b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/PipeMessages.java
index 6914f4b1379..5126852bb6b 100644
---
a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/PipeMessages.java
+++
b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/PipeMessages.java
@@ -466,6 +466,10 @@ public final class PipeMessages {
// ===================== IoTDBSslSyncSink =====================
+ public static final String SSL_TRUST_STORE_PAIR_REQUIRED_WHEN_SSL_ENABLED =
+ "启用 SSL 传输时,请在同一别名下指定完整的 trust-store 参数对:%s 和 %s、%s 和 %s,或 %s 和 %s";
+ public static final String
SSL_KEY_STORE_PATH_AND_PASSWORD_MUST_BE_SPECIFIED_TOGETHER =
+ "SSL key-store 路径和密码必须在同一别名下同时指定:%s 和 %s、%s 和 %s,或 %s 和 %s";
public static final String SYNC_CLIENT_MANAGER_CLOSED =
"IoTDB sync 客户端管理器已关闭";
public static final String REDIRECT_FILE_POSITION = "重定向文件位置到 {}。";
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/constant/PipeSinkConstant.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/constant/PipeSinkConstant.java
index 39be064f09a..aa09b712d6e 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/constant/PipeSinkConstant.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/config/constant/PipeSinkConstant.java
@@ -50,9 +50,19 @@ public class PipeSinkConstant {
public static final String CONNECTOR_IOTDB_NODE_URLS_KEY =
"connector.node-urls";
public static final String SINK_IOTDB_NODE_URLS_KEY = "sink.node-urls";
+ public static final String CONNECTOR_IOTDB_SSL_ENABLE_KEY =
"connector.ssl.enable";
public static final String SINK_IOTDB_SSL_ENABLE_KEY = "sink.ssl.enable";
+ public static final String CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY =
+ "connector.ssl.trust-store-path";
public static final String SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY =
"sink.ssl.trust-store-path";
+ public static final String CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY =
+ "connector.ssl.trust-store-pwd";
public static final String SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY =
"sink.ssl.trust-store-pwd";
+ public static final String CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY =
+ "connector.ssl.key-store-path";
+ public static final String SINK_IOTDB_SSL_KEY_STORE_PATH_KEY =
"sink.ssl.key-store-path";
+ public static final String CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY =
"connector.ssl.key-store-pwd";
+ public static final String SINK_IOTDB_SSL_KEY_STORE_PWD_KEY =
"sink.ssl.key-store-pwd";
public static final String CONNECTOR_IOTDB_PARALLEL_TASKS_KEY =
"connector.parallel.tasks";
public static final String SINK_IOTDB_PARALLEL_TASKS_KEY =
"sink.parallel.tasks";
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/client/IoTDBSyncClient.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/client/IoTDBSyncClient.java
index b0407e0a7bf..296848629fd 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/client/IoTDBSyncClient.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/client/IoTDBSyncClient.java
@@ -55,6 +55,19 @@ public class IoTDBSyncClient extends IClientRPCService.Client
String trustStore,
String trustStorePwd)
throws TTransportException {
+ this(property, ipAddress, port, useSSL, trustStore, trustStorePwd, null,
null);
+ }
+
+ public IoTDBSyncClient(
+ ThriftClientProperty property,
+ String ipAddress,
+ int port,
+ boolean useSSL,
+ String trustStore,
+ String trustStorePwd,
+ String keyStore,
+ String keyStorePwd)
+ throws TTransportException {
super(
property
.getProtocolFactory()
@@ -65,7 +78,9 @@ public class IoTDBSyncClient extends IClientRPCService.Client
port,
property.getConnectionTimeoutMs(),
trustStore,
- trustStorePwd)
+ trustStorePwd,
+ keyStore,
+ keyStorePwd)
: DeepCopyRpcTransportFactory.INSTANCE.getTransport(
ipAddress, port, property.getConnectionTimeoutMs())));
this.ipAddress = ipAddress;
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/client/IoTDBSyncClientManager.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/client/IoTDBSyncClientManager.java
index c6ad14aac4d..83b85a6d583 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/client/IoTDBSyncClientManager.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/client/IoTDBSyncClientManager.java
@@ -57,6 +57,8 @@ public abstract class IoTDBSyncClientManager extends
IoTDBClientManager implemen
private final boolean useSSL;
private final String trustStorePath;
private final String trustStorePwd;
+ private final String keyStorePath;
+ private final String keyStorePwd;
protected final Map<TEndPoint, Pair<IoTDBSyncClient, Boolean>>
endPoint2ClientAndStatus =
new ConcurrentHashMap<>();
@@ -71,6 +73,8 @@ public abstract class IoTDBSyncClientManager extends
IoTDBClientManager implemen
boolean useSSL,
String trustStorePath,
String trustStorePwd,
+ String keyStorePath,
+ String keyStorePwd,
/* The following parameters are used locally. */
boolean useLeaderCache,
String loadBalanceStrategy,
@@ -96,6 +100,8 @@ public abstract class IoTDBSyncClientManager extends
IoTDBClientManager implemen
this.useSSL = useSSL;
this.trustStorePath = trustStorePath;
this.trustStorePwd = trustStorePwd;
+ this.keyStorePath = keyStorePath;
+ this.keyStorePwd = keyStorePwd;
for (final TEndPoint endPoint : endPoints) {
endPoint2ClientAndStatus.put(endPoint, new Pair<>(null, false));
@@ -205,7 +211,9 @@ public abstract class IoTDBSyncClientManager extends
IoTDBClientManager implemen
endPoint.getPort(),
useSSL,
trustStorePath,
- trustStorePwd));
+ trustStorePwd,
+ keyStorePath,
+ keyStorePwd));
return true;
} catch (Exception e) {
endPoint2HandshakeErrorMessage.put(endPoint, e.getMessage());
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/protocol/IoTDBSslSyncSink.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/protocol/IoTDBSslSyncSink.java
index e2dccccfd20..a045082b24e 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/protocol/IoTDBSslSyncSink.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/sink/protocol/IoTDBSslSyncSink.java
@@ -53,10 +53,17 @@ import java.util.Map;
import static
org.apache.iotdb.commons.pipe.agent.plugin.builtin.BuiltinPipePlugin.IOTDB_THRIFT_CONNECTOR;
import static
org.apache.iotdb.commons.pipe.agent.plugin.builtin.BuiltinPipePlugin.IOTDB_THRIFT_SSL_CONNECTOR;
import static
org.apache.iotdb.commons.pipe.agent.plugin.builtin.BuiltinPipePlugin.IOTDB_THRIFT_SSL_SINK;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_ENABLE_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_LEADER_CACHE_ENABLE_DEFAULT_VALUE;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.CONNECTOR_LEADER_CACHE_ENABLE_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_ENABLE_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PATH_KEY;
+import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_KEY_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY;
import static
org.apache.iotdb.commons.pipe.config.constant.PipeSinkConstant.SINK_KEY;
@@ -90,16 +97,93 @@ public abstract class IoTDBSslSyncSink extends IoTDBSink {
IOTDB_THRIFT_CONNECTOR.getPipePluginName())
.toLowerCase();
- validator.validate(
- args -> !((boolean) args[0]) || ((boolean) args[1] && (boolean)
args[2]),
- String.format(
- "When ssl transport is enabled, %s and %s must be specified",
- SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY),
-
IOTDB_THRIFT_SSL_CONNECTOR.getPipePluginName().equals(userSpecifiedConnectorName)
- ||
IOTDB_THRIFT_SSL_SINK.getPipePluginName().equals(userSpecifiedConnectorName)
- || parameters.getBooleanOrDefault(SINK_IOTDB_SSL_ENABLE_KEY,
false),
- parameters.hasAttribute(SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY),
- parameters.hasAttribute(SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY));
+ validator
+ .validate(
+ args -> !((boolean) args[0]) || ((boolean) args[1] && (boolean)
args[2]),
+ String.format(
+ PipeMessages.SSL_TRUST_STORE_PAIR_REQUIRED_WHEN_SSL_ENABLED,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY,
+
PipeParameters.KeyReducer.reduce(CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY),
+
PipeParameters.KeyReducer.reduce(CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY)),
+
IOTDB_THRIFT_SSL_CONNECTOR.getPipePluginName().equals(userSpecifiedConnectorName)
+ ||
IOTDB_THRIFT_SSL_SINK.getPipePluginName().equals(userSpecifiedConnectorName)
+ || parameters.getBooleanOrDefault(
+ Arrays.asList(CONNECTOR_IOTDB_SSL_ENABLE_KEY,
SINK_IOTDB_SSL_ENABLE_KEY),
+ false),
+ hasCompleteAttributePair(
+ parameters,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY),
+ hasNoHalfAttributePair(
+ parameters,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY))
+ .validate(
+ args -> (boolean) args[0] == (boolean) args[1],
+ String.format(
+
PipeMessages.SSL_KEY_STORE_PATH_AND_PASSWORD_MUST_BE_SPECIFIED_TOGETHER,
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_KEY_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_KEY_STORE_PWD_KEY,
+
PipeParameters.KeyReducer.reduce(CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY),
+
PipeParameters.KeyReducer.reduce(CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY)),
+ true,
+ hasNoHalfAttributePair(
+ parameters,
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY,
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY,
+ SINK_IOTDB_SSL_KEY_STORE_PATH_KEY,
+ SINK_IOTDB_SSL_KEY_STORE_PWD_KEY));
+ }
+
+ private static boolean hasCompleteAttributePair(
+ final PipeParameters parameters,
+ final String connectorLeftKey,
+ final String connectorRightKey,
+ final String sinkLeftKey,
+ final String sinkRightKey) {
+ return hasExactAttributePair(parameters, connectorLeftKey,
connectorRightKey)
+ || hasExactAttributePair(parameters, sinkLeftKey, sinkRightKey)
+ || hasExactAttributePair(
+ parameters,
+ PipeParameters.KeyReducer.reduce(connectorLeftKey),
+ PipeParameters.KeyReducer.reduce(connectorRightKey));
+ }
+
+ private static boolean hasNoHalfAttributePair(
+ final PipeParameters parameters,
+ final String connectorLeftKey,
+ final String connectorRightKey,
+ final String sinkLeftKey,
+ final String sinkRightKey) {
+ return hasBothOrNoneExactAttributes(parameters, connectorLeftKey,
connectorRightKey)
+ && hasBothOrNoneExactAttributes(parameters, sinkLeftKey, sinkRightKey)
+ && hasBothOrNoneExactAttributes(
+ parameters,
+ PipeParameters.KeyReducer.reduce(connectorLeftKey),
+ PipeParameters.KeyReducer.reduce(connectorRightKey));
+ }
+
+ private static boolean hasExactAttributePair(
+ final PipeParameters parameters, final String leftKey, final String
rightKey) {
+ return hasExactAttribute(parameters, leftKey) &&
hasExactAttribute(parameters, rightKey);
+ }
+
+ private static boolean hasBothOrNoneExactAttributes(
+ final PipeParameters parameters, final String leftKey, final String
rightKey) {
+ return hasExactAttribute(parameters, leftKey) ==
hasExactAttribute(parameters, rightKey);
+ }
+
+ private static boolean hasExactAttribute(final PipeParameters parameters,
final String key) {
+ return parameters.getAttribute().containsKey(key);
}
@Override
@@ -118,9 +202,20 @@ public abstract class IoTDBSslSyncSink extends IoTDBSink {
final boolean useSSL =
IOTDB_THRIFT_SSL_CONNECTOR.getPipePluginName().equals(userSpecifiedConnectorName)
||
IOTDB_THRIFT_SSL_SINK.getPipePluginName().equals(userSpecifiedConnectorName)
- || parameters.getBooleanOrDefault(SINK_IOTDB_SSL_ENABLE_KEY,
false);
- final String trustStorePath =
parameters.getString(SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY);
- final String trustStorePwd =
parameters.getString(SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY);
+ || parameters.getBooleanOrDefault(
+ Arrays.asList(CONNECTOR_IOTDB_SSL_ENABLE_KEY,
SINK_IOTDB_SSL_ENABLE_KEY), false);
+ final String trustStorePath =
+ parameters.getStringByKeys(
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PATH_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PATH_KEY);
+ final String trustStorePwd =
+ parameters.getStringByKeys(
+ CONNECTOR_IOTDB_SSL_TRUST_STORE_PWD_KEY,
SINK_IOTDB_SSL_TRUST_STORE_PWD_KEY);
+ final String keyStorePath =
+ parameters.getStringByKeys(
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PATH_KEY,
SINK_IOTDB_SSL_KEY_STORE_PATH_KEY);
+ final String keyStorePwd =
+ parameters.getStringByKeys(
+ CONNECTOR_IOTDB_SSL_KEY_STORE_PWD_KEY,
SINK_IOTDB_SSL_KEY_STORE_PWD_KEY);
// leader cache configuration
final boolean useLeaderCache =
@@ -134,6 +229,8 @@ public abstract class IoTDBSslSyncSink extends IoTDBSink {
useSSL,
trustStorePath,
trustStorePwd,
+ keyStorePath,
+ keyStorePwd,
useLeaderCache,
loadBalanceStrategy,
userEntity,
@@ -150,6 +247,8 @@ public abstract class IoTDBSslSyncSink extends IoTDBSink {
final boolean useSSL,
final String trustStorePath,
final String trustStorePwd,
+ final String keyStorePath,
+ final String keyStorePwd,
/* The following parameters are used locally. */
final boolean useLeaderCache,
final String loadBalanceStrategy,