You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ro...@apache.org on 2025/02/10 10:01:01 UTC
(iotdb) branch master updated: Pipe: Adapted pipe metadata sync for new permission (#14775)
This is an automated email from the ASF dual-hosted git repository.
rong 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 2c0f7ec033b Pipe: Adapted pipe metadata sync for new permission (#14775)
2c0f7ec033b is described below
commit 2c0f7ec033bbddea3af0fba3f877aee49fc5d14a
Author: Caideyipi <87...@users.noreply.github.com>
AuthorDate: Mon Feb 10 18:00:54 2025 +0800
Pipe: Adapted pipe metadata sync for new permission (#14775)
---
.../manual/enhanced/IoTDBPipeIdempotentIT.java | 197 ++++++++++++++++++
.../manual/enhanced/IoTDBPipeMetaIT.java} | 86 +++++++-
.../auto/enhanced/IoTDBPipeIdempotentIT.java | 91 ---------
.../request/ConfigPhysicalPlanVisitor.java | 221 ++++++++++++++++++---
.../confignode/manager/PermissionManager.java | 7 +-
.../pipe/event/PipeConfigRegionSnapshotEvent.java | 14 +-
.../extractor/ConfigRegionListeningFilter.java | 84 ++++++--
.../pipe/extractor/IoTDBConfigRegionExtractor.java | 23 ++-
...ConfigPhysicalPlanTablePatternParseVisitor.java | 62 ++++++
...peConfigPhysicalPlanTableScopeParseVisitor.java | 86 ++++++++
...eConfigPhysicalPlanTreePatternParseVisitor.java | 30 ++-
...ipeConfigPhysicalPlanTreeScopeParseVisitor.java | 80 ++++++++
.../receiver/protocol/IoTDBConfigNodeReceiver.java | 162 ++++++++++++++-
.../PipeConfigPhysicalPlanTSStatusVisitor.java | 207 +++++++++++++++++--
...ipeConfigPhysicalPlanScopeParseVisitorTest.java | 116 +++++++++++
...igPhysicalPlanTablePatternParseVisitorTest.java | 25 +++
.../schemaregion/SchemaRegionListeningFilter.java | 8 +-
.../options/PipeInclusionOptions.java | 15 +-
18 files changed, 1333 insertions(+), 181 deletions(-)
diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeIdempotentIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeIdempotentIT.java
new file mode 100644
index 00000000000..c80a67c4d4f
--- /dev/null
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeIdempotentIT.java
@@ -0,0 +1,197 @@
+/*
+ * 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.tablemodel.manual.enhanced;
+
+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.it.env.cluster.node.DataNodeWrapper;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.MultiClusterIT2DualTableManualEnhanced;
+import org.apache.iotdb.itbase.env.BaseEnv;
+import org.apache.iotdb.pipe.it.dual.tablemodel.TableModelUtils;
+import org.apache.iotdb.pipe.it.dual.tablemodel.manual.AbstractPipeTableModelDualManualIT;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({MultiClusterIT2DualTableManualEnhanced.class})
+public class IoTDBPipeIdempotentIT extends AbstractPipeTableModelDualManualIT {
+ @Test
+ public void testCreateTableIdempotent() throws Exception {
+ testTableConfigIdempotent(Collections.emptyList(), "create table test()");
+ }
+
+ @Test
+ public void testAlterTableAddColumnIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Collections.singletonList("create table test()"), "alter table test add column a id");
+ }
+
+ @Test
+ public void testAlterTableSetPropertiesIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Collections.singletonList("create table test()"),
+ "alter table test set properties ttl=100");
+ }
+
+ @Test
+ public void testAlterTableDropColumnIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Collections.singletonList("create table test(a id, b attribute, c int32)"),
+ "alter table test drop column b");
+ }
+
+ @Test
+ public void testDropTableIdempotent() throws Exception {
+ testTableConfigIdempotent(Collections.singletonList("create table test()"), "drop table test");
+ }
+
+ @Test
+ public void testTableCreateUserIdempotent() throws Exception {
+ testTableConfigIdempotent(Collections.emptyList(), "create user newUser 'password'");
+ }
+
+ @Test
+ public void testTableDropUserIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Collections.singletonList("create user newUser 'password'"), "drop user newUser");
+ }
+
+ @Test
+ public void testTableCreateRoleIdempotent() throws Exception {
+ testTableConfigIdempotent(Collections.emptyList(), "create role newRole");
+ }
+
+ @Test
+ public void testTableDropRoleIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Collections.singletonList("create role newRole"), "drop role newRole");
+ }
+
+ @Test
+ public void testTableAlterUserIdempotent3() throws Exception {
+ testTableConfigIdempotent(
+ Collections.singletonList("create user newUser 'password'"),
+ "alter user newUser set password 'passwd'");
+ }
+
+ @Test
+ public void testTableGrantRoleToUserIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Arrays.asList("create user newUser 'password'", "create role newRole"),
+ "grant role newRole to newUser");
+ }
+
+ @Test
+ public void testTableRevokeRoleFromUserIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Arrays.asList(
+ "create user newUser 'password'",
+ "create role newRole",
+ "grant role newRole to newUser"),
+ "revoke role newRole from newUser");
+ }
+
+ @Test
+ public void testTableGrantIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Collections.singletonList("create user newUser 'password'"),
+ "grant all to user newUser with grant option");
+ }
+
+ @Test
+ public void testTableRevokeIdempotent() throws Exception {
+ testTableConfigIdempotent(
+ Arrays.asList(
+ "create user newUser 'password'", "grant all to user newUser with grant option"),
+ "revoke all from user newUser");
+ }
+
+ private void testTableConfigIdempotent(final List<String> beforeSqlList, final String testSql)
+ throws Exception {
+ final String database = "test";
+ TableModelUtils.createDatabase(senderEnv, database);
+ 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<String, String> extractorAttributes = new HashMap<>();
+ final Map<String, String> processorAttributes = new HashMap<>();
+ final Map<String, String> connectorAttributes = new HashMap<>();
+
+ extractorAttributes.put("extractor.inclusion", "all");
+ extractorAttributes.put("extractor.inclusion.exclusion", "");
+ extractorAttributes.put("extractor.forwarding-pipe-requests", "false");
+ extractorAttributes.put("extractor.capture.table", "true");
+ extractorAttributes.put("extractor.capture.tree", "false");
+
+ connectorAttributes.put("connector", "iotdb-thrift-connector");
+ connectorAttributes.put("connector.ip", receiverIp);
+ connectorAttributes.put("connector.port", Integer.toString(receiverPort));
+ connectorAttributes.put("connector.batch.enable", "false");
+ connectorAttributes.put("connector.exception.conflict.resolve-strategy", "retry");
+ connectorAttributes.put("connector.exception.conflict.retry-max-time-seconds", "-1");
+
+ final TSStatus status =
+ client.createPipe(
+ new TCreatePipeReq("testPipe", connectorAttributes)
+ .setExtractorAttributes(extractorAttributes)
+ .setProcessorAttributes(processorAttributes));
+
+ Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
+ }
+
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ database, BaseEnv.TABLE_SQL_DIALECT, senderEnv, beforeSqlList)) {
+ return;
+ }
+
+ if (!TestUtils.tryExecuteNonQueryWithRetry(
+ database, BaseEnv.TABLE_SQL_DIALECT, receiverEnv, testSql)) {
+ return;
+ }
+
+ // Create an idempotent conflict
+ if (!TestUtils.tryExecuteNonQueryWithRetry(
+ database, BaseEnv.TABLE_SQL_DIALECT, senderEnv, testSql)) {
+ return;
+ }
+
+ TableModelUtils.createDatabase(senderEnv, "test2");
+
+ // Assume that the "database" is executed on receiverEnv
+ TestUtils.assertDataSizeEventuallyOnEnv(receiverEnv, "show databases", 3, null);
+ }
+}
diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeTableManualIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeMetaIT.java
similarity index 77%
rename from integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeTableManualIT.java
rename to integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeMetaIT.java
index 866f51e5840..4e33f8369d6 100644
--- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeTableManualIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/tablemodel/manual/enhanced/IoTDBPipeMetaIT.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.iotdb.pipe.it.dual.treemodel.auto.enhanced;
+package org.apache.iotdb.pipe.it.dual.tablemodel.manual.enhanced;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient;
@@ -25,10 +25,10 @@ import org.apache.iotdb.confignode.rpc.thrift.TCreatePipeReq;
import org.apache.iotdb.db.it.utils.TestUtils;
import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
import org.apache.iotdb.it.framework.IoTDBTestRunner;
-import org.apache.iotdb.itbase.category.MultiClusterIT2DualTreeAutoEnhanced;
+import org.apache.iotdb.itbase.category.MultiClusterIT2DualTableManualEnhanced;
import org.apache.iotdb.itbase.env.BaseEnv;
import org.apache.iotdb.pipe.it.dual.tablemodel.TableModelUtils;
-import org.apache.iotdb.pipe.it.dual.treemodel.manual.AbstractPipeDualTreeModelManualIT;
+import org.apache.iotdb.pipe.it.dual.tablemodel.manual.AbstractPipeTableModelDualManualIT;
import org.apache.iotdb.rpc.TSStatusCode;
import org.junit.Assert;
@@ -43,8 +43,8 @@ import java.util.HashSet;
import java.util.Map;
@RunWith(IoTDBTestRunner.class)
-@Category({MultiClusterIT2DualTreeAutoEnhanced.class})
-public class IoTDBPipeTableManualIT extends AbstractPipeDualTreeModelManualIT {
+@Category({MultiClusterIT2DualTableManualEnhanced.class})
+public class IoTDBPipeMetaIT extends AbstractPipeTableModelDualManualIT {
@Test
public void testTableSync() throws Exception {
final DataNodeWrapper receiverDataNode = receiverEnv.getDataNodeWrapper(0);
@@ -291,4 +291,80 @@ public class IoTDBPipeTableManualIT extends AbstractPipeDualTreeModelManualIT {
dbName);
}
}
+
+ @Test
+ public void testAuth() 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(
+ "create user testUser 'password'", "grant all on root.** to user testUser"))) {
+ return;
+ }
+
+ final String dbName = "test";
+ if (!TestUtils.tryExecuteNonQueriesWithRetry(
+ dbName,
+ BaseEnv.TABLE_SQL_DIALECT,
+ senderEnv,
+ Arrays.asList(
+ "grant create on db.tb to user testUser",
+ "grant drop on database test to user testUser"))) {
+ return;
+ }
+
+ final Map<String, String> extractorAttributes = new HashMap<>();
+ final Map<String, String> processorAttributes = new HashMap<>();
+ final Map<String, String> connectorAttributes = new HashMap<>();
+
+ extractorAttributes.put("extractor.inclusion", "all");
+ extractorAttributes.put("extractor.capture.tree", "false");
+ extractorAttributes.put("extractor.capture.table", "true");
+ extractorAttributes.put("extractor.database-name", "test");
+ extractorAttributes.put("extractor.table-name", "t.*[0-9]");
+
+ connectorAttributes.put("connector", "iotdb-thrift-connector");
+ connectorAttributes.put("connector.ip", receiverIp);
+ connectorAttributes.put("connector.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());
+
+ Assert.assertEquals(
+ TSStatusCode.SUCCESS_STATUS.getStatusCode(), client.startPipe("testPipe").getCode());
+
+ if (!TestUtils.tryExecuteNonQueryWithRetry(
+ dbName,
+ BaseEnv.TABLE_SQL_DIALECT,
+ senderEnv,
+ "grant alter on any to user testUser with grant option")) {
+ return;
+ }
+
+ TestUtils.assertDataAlwaysOnEnv(
+ receiverEnv,
+ "list privileges of user testUser",
+ "Role,Scope,Privileges,GrantOption,",
+ new HashSet<>(
+ Arrays.asList(
+ ",,MANAGE_USER,false,",
+ ",,MANAGE_ROLE,false,",
+ ",,MAINTAIN,false,",
+ ",*.*,ALTER,true,",
+ ",test.*,DROP,false,")),
+ dbName);
+ }
+ }
}
diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeIdempotentIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeIdempotentIT.java
index 979fd60098c..e741ab82f6d 100644
--- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeIdempotentIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/auto/enhanced/IoTDBPipeIdempotentIT.java
@@ -28,8 +28,6 @@ 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.MultiClusterIT2DualTreeAutoEnhanced;
-import org.apache.iotdb.itbase.env.BaseEnv;
-import org.apache.iotdb.pipe.it.dual.tablemodel.TableModelUtils;
import org.apache.iotdb.pipe.it.dual.treemodel.auto.AbstractPipeDualTreeModelAutoIT;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -397,36 +395,6 @@ public class IoTDBPipeIdempotentIT extends AbstractPipeDualTreeModelAutoIT {
// Table model
- @Test
- public void testCreateTableIdempotent() throws Exception {
- testTableConfigIdempotent(Collections.emptyList(), "create table test()");
- }
-
- @Test
- public void testAlterTableAddColumnIdempotent() throws Exception {
- testTableConfigIdempotent(
- Collections.singletonList("create table test()"), "alter table test add column a id");
- }
-
- @Test
- public void testAlterTableSetPropertiesIdempotent() throws Exception {
- testTableConfigIdempotent(
- Collections.singletonList("create table test()"),
- "alter table test set properties ttl=100");
- }
-
- @Test
- public void testAlterTableDropColumnIdempotent() throws Exception {
- testTableConfigIdempotent(
- Collections.singletonList("create table test(a id, b attribute, c int32)"),
- "alter table test drop column b");
- }
-
- @Test
- public void testDropTableIdempotent() throws Exception {
- testTableConfigIdempotent(Collections.singletonList("create table test()"), "drop table test");
- }
-
private void testIdempotent(
final List<String> beforeSqlList,
final String testSql,
@@ -484,63 +452,4 @@ public class IoTDBPipeIdempotentIT extends AbstractPipeDualTreeModelAutoIT {
// Assume that the afterSql is executed on receiverEnv
TestUtils.assertDataEventuallyOnEnv(receiverEnv, afterSqlQuery, expectedHeader, expectedResSet);
}
-
- private void testTableConfigIdempotent(final List<String> beforeSqlList, final String testSql)
- throws Exception {
- final String database = "test";
- TableModelUtils.createDatabase(senderEnv, database);
- 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<String, String> extractorAttributes = new HashMap<>();
- final Map<String, String> processorAttributes = new HashMap<>();
- final Map<String, String> connectorAttributes = new HashMap<>();
-
- extractorAttributes.put("extractor.inclusion", "all");
- extractorAttributes.put("extractor.inclusion.exclusion", "");
- extractorAttributes.put("extractor.forwarding-pipe-requests", "false");
- extractorAttributes.put("extractor.capture.table", "true");
- extractorAttributes.put("extractor.capture.tree", "false");
-
- connectorAttributes.put("connector", "iotdb-thrift-connector");
- connectorAttributes.put("connector.ip", receiverIp);
- connectorAttributes.put("connector.port", Integer.toString(receiverPort));
- connectorAttributes.put("connector.batch.enable", "false");
- connectorAttributes.put("connector.exception.conflict.resolve-strategy", "retry");
- connectorAttributes.put("connector.exception.conflict.retry-max-time-seconds", "-1");
-
- final TSStatus status =
- client.createPipe(
- new TCreatePipeReq("testPipe", connectorAttributes)
- .setExtractorAttributes(extractorAttributes)
- .setProcessorAttributes(processorAttributes));
-
- Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), status.getCode());
- }
-
- if (!TestUtils.tryExecuteNonQueriesWithRetry(
- database, BaseEnv.TABLE_SQL_DIALECT, senderEnv, beforeSqlList)) {
- return;
- }
-
- if (!TestUtils.tryExecuteNonQueryWithRetry(
- database, BaseEnv.TABLE_SQL_DIALECT, receiverEnv, testSql)) {
- return;
- }
-
- // Create an idempotent conflict
- if (!TestUtils.tryExecuteNonQueryWithRetry(
- database, BaseEnv.TABLE_SQL_DIALECT, senderEnv, testSql)) {
- return;
- }
-
- TableModelUtils.createDatabase(senderEnv, "test2");
-
- // Assume that the "database" is executed on receiverEnv
- TestUtils.assertDataSizeEventuallyOnEnv(receiverEnv, "show databases", 3, null);
- }
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java
index d2a46baf585..b5c1923ecca 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanVisitor.java
@@ -19,7 +19,8 @@
package org.apache.iotdb.confignode.consensus.request;
-import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
import org.apache.iotdb.confignode.consensus.request.write.database.SetTTLPlan;
@@ -65,29 +66,83 @@ public abstract class ConfigPhysicalPlanVisitor<R, C> {
case PipeDeactivateTemplate:
return visitPipeDeactivateTemplate((PipeDeactivateTemplatePlan) plan, context);
case CreateRole:
- return visitCreateRole((AuthorPlan) plan, context);
+ return visitCreateRole((AuthorTreePlan) plan, context);
case DropRole:
- return visitDropRole((AuthorPlan) plan, context);
+ return visitDropRole((AuthorTreePlan) plan, context);
case GrantRole:
- return visitGrantRole((AuthorPlan) plan, context);
+ return visitGrantRole((AuthorTreePlan) plan, context);
case RevokeRole:
- return visitRevokeRole((AuthorPlan) plan, context);
+ return visitRevokeRole((AuthorTreePlan) plan, context);
case CreateUser:
- return visitCreateUser((AuthorPlan) plan, context);
+ return visitCreateUser((AuthorTreePlan) plan, context);
case CreateUserWithRawPassword:
- return visitCreateRawUser((AuthorPlan) plan, context);
+ return visitCreateRawUser((AuthorTreePlan) plan, context);
case UpdateUser:
- return visitUpdateUser((AuthorPlan) plan, context);
+ return visitUpdateUser((AuthorTreePlan) plan, context);
case DropUser:
- return visitDropUser((AuthorPlan) plan, context);
+ return visitDropUser((AuthorTreePlan) plan, context);
case GrantUser:
- return visitGrantUser((AuthorPlan) plan, context);
+ return visitGrantUser((AuthorTreePlan) plan, context);
case RevokeUser:
- return visitRevokeUser((AuthorPlan) plan, context);
+ return visitRevokeUser((AuthorTreePlan) plan, context);
case GrantRoleToUser:
- return visitGrantRoleToUser((AuthorPlan) plan, context);
+ return visitGrantRoleToUser((AuthorTreePlan) plan, context);
case RevokeRoleFromUser:
- return visitRevokeRoleFromUser((AuthorPlan) plan, context);
+ return visitRevokeRoleFromUser((AuthorTreePlan) plan, context);
+ case RCreateUser:
+ return visitRCreateUser((AuthorRelationalPlan) plan, context);
+ case RCreateRole:
+ return visitRCreateRole((AuthorRelationalPlan) plan, context);
+ case RUpdateUser:
+ return visitRUpdateUser((AuthorRelationalPlan) plan, context);
+ case RDropUser:
+ return visitRDropUserPlan((AuthorRelationalPlan) plan, context);
+ case RDropRole:
+ return visitRDropRolePlan((AuthorRelationalPlan) plan, context);
+ case RGrantUserRole:
+ return visitRGrantUserRole((AuthorRelationalPlan) plan, context);
+ case RRevokeUserRole:
+ return visitRRevokeUserRole((AuthorRelationalPlan) plan, context);
+ case RGrantUserAny:
+ return visitRGrantUserAny((AuthorRelationalPlan) plan, context);
+ case RGrantRoleAny:
+ return visitRGrantRoleAny((AuthorRelationalPlan) plan, context);
+ case RGrantUserAll:
+ return visitRGrantUserAll((AuthorRelationalPlan) plan, context);
+ case RGrantRoleAll:
+ return visitRGrantRoleAll((AuthorRelationalPlan) plan, context);
+ case RGrantUserDBPriv:
+ return visitRGrantUserDB((AuthorRelationalPlan) plan, context);
+ case RGrantUserTBPriv:
+ return visitRGrantUserTB((AuthorRelationalPlan) plan, context);
+ case RGrantRoleDBPriv:
+ return visitRGrantRoleDB((AuthorRelationalPlan) plan, context);
+ case RGrantRoleTBPriv:
+ return visitRGrantRoleTB((AuthorRelationalPlan) plan, context);
+ case RRevokeUserAny:
+ return visitRRevokeUserAny((AuthorRelationalPlan) plan, context);
+ case RRevokeRoleAny:
+ return visitRRevokeRoleAny((AuthorRelationalPlan) plan, context);
+ case RRevokeUserAll:
+ return visitRRevokeUserAll((AuthorRelationalPlan) plan, context);
+ case RRevokeRoleAll:
+ return visitRRevokeRoleAll((AuthorRelationalPlan) plan, context);
+ case RRevokeUserDBPriv:
+ return visitRRevokeUserDBPrivilege((AuthorRelationalPlan) plan, context);
+ case RRevokeUserTBPriv:
+ return visitRRevokeUserTBPrivilege((AuthorRelationalPlan) plan, context);
+ case RRevokeRoleDBPriv:
+ return visitRRevokeRoleDBPrivilege((AuthorRelationalPlan) plan, context);
+ case RRevokeRoleTBPriv:
+ return visitRRevokeRoleTBPrivilege((AuthorRelationalPlan) plan, context);
+ case RGrantUserSysPri:
+ return visitRGrantUserSysPrivilege((AuthorRelationalPlan) plan, context);
+ case RGrantRoleSysPri:
+ return visitRGrantRoleSysPrivilege((AuthorRelationalPlan) plan, context);
+ case RRevokeUserSysPri:
+ return visitRRevokeUserSysPrivilege((AuthorRelationalPlan) plan, context);
+ case RRevokeRoleSysPri:
+ return visitRRevokeRoleSysPrivilege((AuthorRelationalPlan) plan, context);
case SetTTL:
return visitTTL((SetTTLPlan) plan, context);
case PipeCreateTable:
@@ -164,54 +219,170 @@ public abstract class ConfigPhysicalPlanVisitor<R, C> {
return visitPlan(pipeDeactivateTemplatePlan, context);
}
- public R visitCreateUser(final AuthorPlan createUserPlan, final C context) {
+ public R visitCreateUser(final AuthorTreePlan createUserPlan, final C context) {
return visitPlan(createUserPlan, context);
}
- public R visitCreateRawUser(final AuthorPlan createRawUserPlan, final C context) {
+ public R visitCreateRawUser(final AuthorTreePlan createRawUserPlan, final C context) {
return visitPlan(createRawUserPlan, context);
}
- public R visitUpdateUser(final AuthorPlan updateUserPlan, final C context) {
+ public R visitUpdateUser(final AuthorTreePlan updateUserPlan, final C context) {
return visitPlan(updateUserPlan, context);
}
- public R visitDropUser(final AuthorPlan dropUserPlan, final C context) {
+ public R visitDropUser(final AuthorTreePlan dropUserPlan, final C context) {
return visitPlan(dropUserPlan, context);
}
- public R visitGrantUser(final AuthorPlan grantUserPlan, final C context) {
+ public R visitGrantUser(final AuthorTreePlan grantUserPlan, final C context) {
return visitPlan(grantUserPlan, context);
}
- public R visitRevokeUser(final AuthorPlan revokeUserPlan, final C context) {
+ public R visitRevokeUser(final AuthorTreePlan revokeUserPlan, final C context) {
return visitPlan(revokeUserPlan, context);
}
- public R visitCreateRole(final AuthorPlan createRolePlan, final C context) {
+ public R visitCreateRole(final AuthorTreePlan createRolePlan, final C context) {
return visitPlan(createRolePlan, context);
}
- public R visitDropRole(final AuthorPlan dropRolePlan, final C context) {
+ public R visitDropRole(final AuthorTreePlan dropRolePlan, final C context) {
return visitPlan(dropRolePlan, context);
}
- public R visitGrantRole(final AuthorPlan grantRolePlan, final C context) {
+ public R visitGrantRole(final AuthorTreePlan grantRolePlan, final C context) {
return visitPlan(grantRolePlan, context);
}
- public R visitRevokeRole(final AuthorPlan revokeRolePlan, final C context) {
+ public R visitRevokeRole(final AuthorTreePlan revokeRolePlan, final C context) {
return visitPlan(revokeRolePlan, context);
}
- public R visitGrantRoleToUser(final AuthorPlan grantRoleToUserPlan, final C context) {
+ public R visitGrantRoleToUser(final AuthorTreePlan grantRoleToUserPlan, final C context) {
return visitPlan(grantRoleToUserPlan, context);
}
- public R visitRevokeRoleFromUser(final AuthorPlan revokeRoleFromUserPlan, final C context) {
+ public R visitRevokeRoleFromUser(final AuthorTreePlan revokeRoleFromUserPlan, final C context) {
return visitPlan(revokeRoleFromUserPlan, context);
}
+ public R visitRCreateUser(final AuthorRelationalPlan rCreateUserPlan, final C context) {
+ return visitPlan(rCreateUserPlan, context);
+ }
+
+ public R visitRCreateRole(final AuthorRelationalPlan rCreateRolePlan, final C context) {
+ return visitPlan(rCreateRolePlan, context);
+ }
+
+ public R visitRUpdateUser(final AuthorRelationalPlan rUpdateUserPlan, final C context) {
+ return visitPlan(rUpdateUserPlan, context);
+ }
+
+ public R visitRDropUserPlan(final AuthorRelationalPlan rDropUserPlan, final C context) {
+ return visitPlan(rDropUserPlan, context);
+ }
+
+ public R visitRDropRolePlan(final AuthorRelationalPlan rDropRolePlan, final C context) {
+ return visitPlan(rDropRolePlan, context);
+ }
+
+ public R visitRGrantUserRole(final AuthorRelationalPlan rGrantUserRolePlan, final C context) {
+ return visitPlan(rGrantUserRolePlan, context);
+ }
+
+ public R visitRRevokeUserRole(final AuthorRelationalPlan rRevokeUserRolePlan, final C context) {
+ return visitPlan(rRevokeUserRolePlan, context);
+ }
+
+ public R visitRGrantUserAny(final AuthorRelationalPlan rGrantUserAnyPlan, final C context) {
+ return visitPlan(rGrantUserAnyPlan, context);
+ }
+
+ public R visitRGrantRoleAny(final AuthorRelationalPlan rGrantRoleAnyPlan, final C context) {
+ return visitPlan(rGrantRoleAnyPlan, context);
+ }
+
+ public R visitRGrantUserAll(final AuthorRelationalPlan rGrantUserAllPlan, final C context) {
+ return visitPlan(rGrantUserAllPlan, context);
+ }
+
+ public R visitRGrantRoleAll(final AuthorRelationalPlan rGrantRoleAllPlan, final C context) {
+ return visitPlan(rGrantRoleAllPlan, context);
+ }
+
+ public R visitRGrantUserDB(final AuthorRelationalPlan rGrantUserDBPlan, final C context) {
+ return visitPlan(rGrantUserDBPlan, context);
+ }
+
+ public R visitRGrantUserTB(final AuthorRelationalPlan rGrantUserTBPlan, final C context) {
+ return visitPlan(rGrantUserTBPlan, context);
+ }
+
+ public R visitRGrantRoleDB(final AuthorRelationalPlan rGrantRoleDBPlan, final C context) {
+ return visitPlan(rGrantRoleDBPlan, context);
+ }
+
+ public R visitRGrantRoleTB(final AuthorRelationalPlan rGrantRoleTBPlan, final C context) {
+ return visitPlan(rGrantRoleTBPlan, context);
+ }
+
+ public R visitRRevokeUserAny(final AuthorRelationalPlan rRevokeUserAnyPlan, final C context) {
+ return visitPlan(rRevokeUserAnyPlan, context);
+ }
+
+ public R visitRRevokeRoleAny(final AuthorRelationalPlan rRevokeRoleAnyPlan, final C context) {
+ return visitPlan(rRevokeRoleAnyPlan, context);
+ }
+
+ public R visitRRevokeUserAll(final AuthorRelationalPlan rRevokeUserAllPlan, final C context) {
+ return visitPlan(rRevokeUserAllPlan, context);
+ }
+
+ public R visitRRevokeRoleAll(final AuthorRelationalPlan rRevokeRoleAllPlan, final C context) {
+ return visitPlan(rRevokeRoleAllPlan, context);
+ }
+
+ public R visitRRevokeUserDBPrivilege(
+ final AuthorRelationalPlan rRevokeUserDBPrivilegePlan, final C context) {
+ return visitPlan(rRevokeUserDBPrivilegePlan, context);
+ }
+
+ public R visitRRevokeUserTBPrivilege(
+ final AuthorRelationalPlan rRevokeUserTBPrivilegePlan, final C context) {
+ return visitPlan(rRevokeUserTBPrivilegePlan, context);
+ }
+
+ public R visitRRevokeRoleDBPrivilege(
+ final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final C context) {
+ return visitPlan(rRevokeRoleTBPrivilegePlan, context);
+ }
+
+ public R visitRRevokeRoleTBPrivilege(
+ final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final C context) {
+ return visitPlan(rRevokeRoleTBPrivilegePlan, context);
+ }
+
+ public R visitRGrantUserSysPrivilege(
+ final AuthorRelationalPlan rGrantUserSysPrivilegePlan, final C context) {
+ return visitPlan(rGrantUserSysPrivilegePlan, context);
+ }
+
+ public R visitRGrantRoleSysPrivilege(
+ final AuthorRelationalPlan rGrantRoleSysPrivilegePlan, final C context) {
+ return visitPlan(rGrantRoleSysPrivilegePlan, context);
+ }
+
+ public R visitRRevokeUserSysPrivilege(
+ final AuthorRelationalPlan rRevokeUserSysPrivilegePlan, final C context) {
+ return visitPlan(rRevokeUserSysPrivilegePlan, context);
+ }
+
+ public R visitRRevokeRoleSysPrivilege(
+ final AuthorRelationalPlan rRevokeRoleSysPrivilegePlan, final C context) {
+ return visitPlan(rRevokeRoleSysPrivilegePlan, context);
+ }
+
public R visitTTL(final SetTTLPlan setTTLPlan, final C context) {
return visitPlan(setTTLPlan, context);
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
index 4d31ae8961e..bab7b08c25e 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/PermissionManager.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.commons.auth.AuthException;
import org.apache.iotdb.commons.auth.entity.PrivilegeUnion;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
+import org.apache.iotdb.confignode.consensus.request.write.pipe.payload.PipeEnrichedPlan;
import org.apache.iotdb.confignode.consensus.response.auth.PermissionInfoResp;
import org.apache.iotdb.confignode.manager.consensus.ConsensusManager;
import org.apache.iotdb.confignode.persistence.AuthorInfo;
@@ -66,7 +67,9 @@ public class PermissionManager {
if (authorPlan.getAuthorType() == ConfigPhysicalPlanType.CreateUser
|| authorPlan.getAuthorType() == ConfigPhysicalPlanType.CreateRole
|| authorPlan.getAuthorType() == ConfigPhysicalPlanType.CreateUserWithRawPassword) {
- tsStatus = getConsensusManager().write(authorPlan);
+ tsStatus =
+ getConsensusManager()
+ .write(isGeneratedByPipe ? new PipeEnrichedPlan(authorPlan) : authorPlan);
} else {
List<TDataNodeConfiguration> allDataNodes =
configManager.getNodeManager().getRegisteredDataNodes();
@@ -76,7 +79,7 @@ public class PermissionManager {
.operateAuthPlan(authorPlan, allDataNodes, isGeneratedByPipe);
}
return tsStatus;
- } catch (ConsensusException e) {
+ } catch (final ConsensusException e) {
LOGGER.warn("Failed in the write API executing the consensus layer due to: ", e);
TSStatus res = new TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
res.setMessage(e.getMessage());
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/event/PipeConfigRegionSnapshotEvent.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/event/PipeConfigRegionSnapshotEvent.java
index b37bfde0baa..eda703f6e51 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/event/PipeConfigRegionSnapshotEvent.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/event/PipeConfigRegionSnapshotEvent.java
@@ -67,14 +67,24 @@ public class PipeConfigRegionSnapshotEvent extends PipeSnapshotEvent
new HashSet<>(
Arrays.asList(
ConfigPhysicalPlanType.CreateRole.getPlanType(),
- ConfigPhysicalPlanType.GrantRole.getPlanType()))));
+ ConfigPhysicalPlanType.GrantRole.getPlanType(),
+ ConfigPhysicalPlanType.RGrantRoleDBPriv.getPlanType(),
+ ConfigPhysicalPlanType.RGrantRoleTBPriv.getPlanType(),
+ ConfigPhysicalPlanType.RGrantRoleAny.getPlanType(),
+ ConfigPhysicalPlanType.RGrantRoleSysPri.getPlanType(),
+ ConfigPhysicalPlanType.RGrantRoleAll.getPlanType()))));
SNAPSHOT_FILE_TYPE_2_CONFIG_PHYSICAL_PLAN_TYPE_MAP.put(
CNSnapshotFileType.USER,
Collections.unmodifiableSet(
new HashSet<>(
Arrays.asList(
ConfigPhysicalPlanType.CreateUserWithRawPassword.getPlanType(),
- ConfigPhysicalPlanType.GrantUser.getPlanType()))));
+ ConfigPhysicalPlanType.GrantUser.getPlanType(),
+ ConfigPhysicalPlanType.RGrantUserDBPriv.getPlanType(),
+ ConfigPhysicalPlanType.RGrantUserTBPriv.getPlanType(),
+ ConfigPhysicalPlanType.RGrantUserAny.getPlanType(),
+ ConfigPhysicalPlanType.RGrantUserSysPri.getPlanType(),
+ ConfigPhysicalPlanType.RGrantUserAll.getPlanType()))));
SNAPSHOT_FILE_TYPE_2_CONFIG_PHYSICAL_PLAN_TYPE_MAP.put(
CNSnapshotFileType.USER_ROLE,
Collections.singleton(ConfigPhysicalPlanType.GrantRoleToUser.getPlanType()));
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/ConfigRegionListeningFilter.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/ConfigRegionListeningFilter.java
index 0c87b8d60e7..5f0e2889d9f 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/ConfigRegionListeningFilter.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/ConfigRegionListeningFilter.java
@@ -41,8 +41,8 @@ import java.util.stream.Collectors;
import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.getExclusionString;
import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.getInclusionString;
import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.parseOptions;
-import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.tableOnlySyncPrefix;
-import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.treeOnlySyncPrefix;
+import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.tableOnlySyncPrefixes;
+import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.treeOnlySyncPrefixes;
/**
* {@link ConfigRegionListeningFilter} is to classify the {@link ConfigPhysicalPlan}s to help {@link
@@ -122,16 +122,45 @@ public class ConfigRegionListeningFilter {
OPTION_PLAN_MAP.put(
new PartialPath("auth.role.create"),
- Collections.singletonList(ConfigPhysicalPlanType.CreateRole));
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ConfigPhysicalPlanType.CreateRole, ConfigPhysicalPlanType.RCreateRole)));
OPTION_PLAN_MAP.put(
new PartialPath("auth.role.drop"),
- Collections.singletonList(ConfigPhysicalPlanType.DropRole));
+ Collections.unmodifiableList(
+ Arrays.asList(ConfigPhysicalPlanType.DropRole, ConfigPhysicalPlanType.RDropRole)));
+
+ // Both
OPTION_PLAN_MAP.put(
new PartialPath("auth.role.grant"),
- Collections.singletonList(ConfigPhysicalPlanType.GrantRole));
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ConfigPhysicalPlanType.GrantRole,
+ ConfigPhysicalPlanType.RGrantRoleAll,
+ ConfigPhysicalPlanType.RGrantRoleSysPri)));
OPTION_PLAN_MAP.put(
new PartialPath("auth.role.revoke"),
- Collections.singletonList(ConfigPhysicalPlanType.RevokeRole));
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ConfigPhysicalPlanType.RevokeRole,
+ ConfigPhysicalPlanType.RRevokeRoleAll,
+ ConfigPhysicalPlanType.RRevokeRoleSysPri)));
+
+ // Table
+ OPTION_PLAN_MAP.put(
+ new PartialPath("auth.role.grant.table"),
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ConfigPhysicalPlanType.RGrantRoleAny,
+ ConfigPhysicalPlanType.RGrantRoleDBPriv,
+ ConfigPhysicalPlanType.RGrantRoleTBPriv)));
+ OPTION_PLAN_MAP.put(
+ new PartialPath("auth.role.revoke.table"),
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ConfigPhysicalPlanType.RRevokeRoleAny,
+ ConfigPhysicalPlanType.RRevokeRoleDBPriv,
+ ConfigPhysicalPlanType.RRevokeRoleTBPriv)));
OPTION_PLAN_MAP.put(
new PartialPath("auth.user.create"),
@@ -141,20 +170,49 @@ public class ConfigRegionListeningFilter {
ConfigPhysicalPlanType.CreateUserWithRawPassword)));
OPTION_PLAN_MAP.put(
new PartialPath("auth.user.alter"),
- Collections.singletonList(ConfigPhysicalPlanType.UpdateUser));
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ConfigPhysicalPlanType.UpdateUser, ConfigPhysicalPlanType.RUpdateUser)));
OPTION_PLAN_MAP.put(
new PartialPath("auth.user.drop"),
- Collections.singletonList(ConfigPhysicalPlanType.DropUser));
+ Collections.unmodifiableList(
+ Arrays.asList(ConfigPhysicalPlanType.DropUser, ConfigPhysicalPlanType.RUpdateUser)));
+
+ // Both
OPTION_PLAN_MAP.put(
new PartialPath("auth.user.grant"),
Collections.unmodifiableList(
Arrays.asList(
- ConfigPhysicalPlanType.GrantUser, ConfigPhysicalPlanType.GrantRoleToUser)));
+ ConfigPhysicalPlanType.GrantUser,
+ ConfigPhysicalPlanType.GrantRoleToUser,
+ ConfigPhysicalPlanType.RGrantUserRole,
+ ConfigPhysicalPlanType.RGrantUserAll,
+ ConfigPhysicalPlanType.RGrantUserSysPri)));
OPTION_PLAN_MAP.put(
new PartialPath("auth.user.revoke"),
Collections.unmodifiableList(
Arrays.asList(
- ConfigPhysicalPlanType.RevokeUser, ConfigPhysicalPlanType.RevokeRoleFromUser)));
+ ConfigPhysicalPlanType.RevokeUser,
+ ConfigPhysicalPlanType.RevokeRoleFromUser,
+ ConfigPhysicalPlanType.RRevokeUserRole,
+ ConfigPhysicalPlanType.RGrantUserAll,
+ ConfigPhysicalPlanType.RGrantUserSysPri)));
+
+ // Table
+ OPTION_PLAN_MAP.put(
+ new PartialPath("auth.user.grant.table"),
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ConfigPhysicalPlanType.RGrantUserAny,
+ ConfigPhysicalPlanType.RGrantUserDBPriv,
+ ConfigPhysicalPlanType.RGrantUserTBPriv)));
+ OPTION_PLAN_MAP.put(
+ new PartialPath("auth.user.revoke.table"),
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ConfigPhysicalPlanType.RRevokeUserAny,
+ ConfigPhysicalPlanType.RRevokeUserDBPriv,
+ ConfigPhysicalPlanType.RRevokeUserTBPriv)));
} catch (final IllegalPathException ignore) {
// There won't be any exceptions here
}
@@ -185,11 +243,11 @@ public class ConfigRegionListeningFilter {
exclusionOptions.forEach(exclusion -> planTypes.removeAll(getOptionsByPrefix(exclusion)));
if (!TreePattern.isTreeModelDataAllowToBeCaptured(parameters)) {
- planTypes.removeAll(getOptionsByPrefix(treeOnlySyncPrefix));
+ treeOnlySyncPrefixes.forEach(prefix -> planTypes.removeAll(getOptionsByPrefix(prefix)));
}
if (!TablePattern.isTableModelDataAllowToBeCaptured(parameters)) {
- planTypes.removeAll(getOptionsByPrefix(tableOnlySyncPrefix));
+ tableOnlySyncPrefixes.forEach(prefix -> planTypes.removeAll(getOptionsByPrefix(prefix)));
}
return planTypes;
@@ -197,7 +255,7 @@ public class ConfigRegionListeningFilter {
private static Set<ConfigPhysicalPlanType> getOptionsByPrefix(final PartialPath prefix) {
return OPTION_PLAN_MAP.keySet().stream()
- .filter(path -> path.overlapWithFullPathPrefix(prefix))
+ .filter(path -> path.matchPrefixPath(prefix))
.map(OPTION_PLAN_MAP::get)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/IoTDBConfigRegionExtractor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/IoTDBConfigRegionExtractor.java
index 9387d67bebe..2795879dcce 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/IoTDBConfigRegionExtractor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/IoTDBConfigRegionExtractor.java
@@ -62,6 +62,10 @@ public class IoTDBConfigRegionExtractor extends IoTDBNonDataRegionExtractor {
new PipeConfigPhysicalPlanTreePatternParseVisitor();
public static final PipeConfigPhysicalPlanTablePatternParseVisitor TABLE_PATTERN_PARSE_VISITOR =
new PipeConfigPhysicalPlanTablePatternParseVisitor();
+ public static final PipeConfigPhysicalPlanTreeScopeParseVisitor TREE_SCOPE_PARSE_VISITOR =
+ new PipeConfigPhysicalPlanTreeScopeParseVisitor();
+ public static final PipeConfigPhysicalPlanTableScopeParseVisitor TABLE_SCOPE_PARSE_VISITOR =
+ new PipeConfigPhysicalPlanTableScopeParseVisitor();
private Set<ConfigPhysicalPlanType> listenedTypeSet = new HashSet<>();
@@ -149,8 +153,23 @@ public class IoTDBConfigRegionExtractor extends IoTDBNonDataRegionExtractor {
return result;
}
}
- if (!Boolean.FALSE.equals(isTableDatabasePlan)) {
- result = TABLE_PATTERN_PARSE_VISITOR.process(plan, tablePattern);
+ if (!Boolean.FALSE.equals(isTableDatabasePlan) && result.isPresent()) {
+ result = TABLE_PATTERN_PARSE_VISITOR.process(result.get(), tablePattern);
+ if (!result.isPresent()) {
+ return result;
+ }
+ }
+ if (!treePattern.isTreeModelDataAllowedToBeCaptured() && result.isPresent()) {
+ result = TREE_SCOPE_PARSE_VISITOR.process(result.get(), null);
+ if (!result.isPresent()) {
+ return result;
+ }
+ }
+ if (!tablePattern.isTableModelDataAllowedToBeCaptured() && result.isPresent()) {
+ result = TABLE_SCOPE_PARSE_VISITOR.process(result.get(), null);
+ if (!result.isPresent()) {
+ return result;
+ }
}
return result;
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitor.java
index 91be75a3bb5..679614ac458 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitor.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.pipe.datastructure.pattern.TablePattern;
import org.apache.iotdb.commons.utils.PathUtils;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
import org.apache.iotdb.confignode.consensus.request.write.pipe.payload.PipeCreateTablePlan;
@@ -132,4 +133,65 @@ public class PipeConfigPhysicalPlanTablePatternParseVisitor
return pattern.matchesDatabase(PathUtils.unQualifyDatabaseName(database))
&& pattern.matchesTable(tableName);
}
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRGrantUserDB(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return visitAuthorDBPlan(plan, pattern);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRGrantRoleDB(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return visitAuthorDBPlan(plan, pattern);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRRevokeUserDBPrivilege(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return visitAuthorDBPlan(plan, pattern);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRRevokeRoleDBPrivilege(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return visitAuthorDBPlan(plan, pattern);
+ }
+
+ private Optional<ConfigPhysicalPlan> visitAuthorDBPlan(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return pattern.matchesDatabase(plan.getDatabaseName()) ? Optional.of(plan) : Optional.empty();
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRGrantUserTB(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return visitAuthorTBPlan(plan, pattern);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRGrantRoleTB(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return visitAuthorTBPlan(plan, pattern);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRRevokeUserTBPrivilege(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return visitAuthorTBPlan(plan, pattern);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRRevokeRoleTBPrivilege(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return visitAuthorTBPlan(plan, pattern);
+ }
+
+ private Optional<ConfigPhysicalPlan> visitAuthorTBPlan(
+ final AuthorRelationalPlan plan, final TablePattern pattern) {
+ return pattern.matchesDatabase(plan.getDatabaseName())
+ && pattern.matchesTable(plan.getTableName())
+ ? Optional.of(plan)
+ : Optional.empty();
+ }
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTableScopeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTableScopeParseVisitor.java
new file mode 100644
index 00000000000..e5673c0dafd
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTableScopeParseVisitor.java
@@ -0,0 +1,86 @@
+/*
+ * 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.manager.pipe.extractor;
+
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class PipeConfigPhysicalPlanTableScopeParseVisitor
+ extends ConfigPhysicalPlanVisitor<Optional<ConfigPhysicalPlan>, Void> {
+ @Override
+ public Optional<ConfigPhysicalPlan> visitPlan(final ConfigPhysicalPlan plan, final Void context) {
+ return Optional.of(plan);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRGrantUserAll(
+ final AuthorRelationalPlan plan, final Void context) {
+ return visitTableAuthorPlan(plan, ConfigPhysicalPlanType.GrantUser);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRGrantRoleAll(
+ final AuthorRelationalPlan plan, final Void context) {
+ return visitTableAuthorPlan(plan, ConfigPhysicalPlanType.GrantRole);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRRevokeUserAll(
+ final AuthorRelationalPlan plan, final Void context) {
+ return visitTableAuthorPlan(plan, ConfigPhysicalPlanType.RevokeUser);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRRevokeRoleAll(
+ final AuthorRelationalPlan plan, final Void context) {
+ return visitTableAuthorPlan(plan, ConfigPhysicalPlanType.RevokeRole);
+ }
+
+ private Optional<ConfigPhysicalPlan> visitTableAuthorPlan(
+ final AuthorRelationalPlan authorRelationalPlan, final ConfigPhysicalPlanType type) {
+ final Set<Integer> permissions =
+ Arrays.stream(PrivilegeType.values())
+ .filter(PrivilegeType::forRelationalSys)
+ .map(Enum::ordinal)
+ .collect(Collectors.toSet());
+ return !permissions.isEmpty()
+ ? Optional.of(
+ new AuthorTreePlan(
+ type,
+ authorRelationalPlan.getUserName(),
+ authorRelationalPlan.getRoleName(),
+ authorRelationalPlan.getPassword(),
+ authorRelationalPlan.getNewPassword(),
+ permissions,
+ authorRelationalPlan.getGrantOpt(),
+ Collections.emptyList()))
+ : Optional.empty();
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreePatternParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreePatternParseVisitor.java
index f5e5888ed7d..344a61c2304 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreePatternParseVisitor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreePatternParseVisitor.java
@@ -25,7 +25,6 @@ import org.apache.iotdb.commons.path.PathPatternTree;
import org.apache.iotdb.commons.pipe.datastructure.pattern.IoTDBTreePattern;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
-import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
@@ -166,52 +165,51 @@ public class PipeConfigPhysicalPlanTreePatternParseVisitor
@Override
public Optional<ConfigPhysicalPlan> visitGrantUser(
- final AuthorPlan grantUserPlan, final IoTDBTreePattern pattern) {
+ final AuthorTreePlan grantUserPlan, final IoTDBTreePattern pattern) {
return visitTreeAuthorPlan(grantUserPlan, pattern);
}
@Override
public Optional<ConfigPhysicalPlan> visitRevokeUser(
- final AuthorPlan revokeUserPlan, final IoTDBTreePattern pattern) {
+ final AuthorTreePlan revokeUserPlan, final IoTDBTreePattern pattern) {
return visitTreeAuthorPlan(revokeUserPlan, pattern);
}
@Override
public Optional<ConfigPhysicalPlan> visitGrantRole(
- final AuthorPlan revokeUserPlan, final IoTDBTreePattern pattern) {
+ final AuthorTreePlan revokeUserPlan, final IoTDBTreePattern pattern) {
return visitTreeAuthorPlan(revokeUserPlan, pattern);
}
@Override
public Optional<ConfigPhysicalPlan> visitRevokeRole(
- final AuthorPlan revokeUserPlan, final IoTDBTreePattern pattern) {
+ final AuthorTreePlan revokeUserPlan, final IoTDBTreePattern pattern) {
return visitTreeAuthorPlan(revokeUserPlan, pattern);
}
private Optional<ConfigPhysicalPlan> visitTreeAuthorPlan(
- final AuthorPlan pathRelatedAuthorPlan, final IoTDBTreePattern pattern) {
- AuthorTreePlan plan = (AuthorTreePlan) pathRelatedAuthorPlan;
+ final AuthorTreePlan pathRelatedAuthorTreePlan, final IoTDBTreePattern pattern) {
final List<PartialPath> intersectedPaths =
- plan.getNodeNameList().stream()
+ pathRelatedAuthorTreePlan.getNodeNameList().stream()
.map(pattern::getIntersection)
.flatMap(Collection::stream)
.collect(Collectors.toList());
final Set<Integer> permissions =
!intersectedPaths.isEmpty()
- ? plan.getPermissions()
- : plan.getPermissions().stream()
+ ? pathRelatedAuthorTreePlan.getPermissions()
+ : pathRelatedAuthorTreePlan.getPermissions().stream()
.filter(permission -> !PrivilegeType.values()[permission].isPathPrivilege())
.collect(Collectors.toSet());
return !permissions.isEmpty()
? Optional.of(
new AuthorTreePlan(
- plan.getAuthorType(),
- plan.getUserName(),
- plan.getRoleName(),
- plan.getPassword(),
- plan.getNewPassword(),
+ pathRelatedAuthorTreePlan.getAuthorType(),
+ pathRelatedAuthorTreePlan.getUserName(),
+ pathRelatedAuthorTreePlan.getRoleName(),
+ pathRelatedAuthorTreePlan.getPassword(),
+ pathRelatedAuthorTreePlan.getNewPassword(),
permissions,
- plan.getGrantOpt(),
+ pathRelatedAuthorTreePlan.getGrantOpt(),
intersectedPaths))
: Optional.empty();
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreeScopeParseVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreeScopeParseVisitor.java
new file mode 100644
index 00000000000..175b836532f
--- /dev/null
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTreeScopeParseVisitor.java
@@ -0,0 +1,80 @@
+/*
+ * 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.manager.pipe.extractor;
+
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
+
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class PipeConfigPhysicalPlanTreeScopeParseVisitor
+ extends ConfigPhysicalPlanVisitor<Optional<ConfigPhysicalPlan>, Void> {
+ @Override
+ public Optional<ConfigPhysicalPlan> visitPlan(final ConfigPhysicalPlan plan, final Void context) {
+ return Optional.of(plan);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitGrantRole(
+ final AuthorTreePlan grantRolePlan, final Void context) {
+ return visitTreeAuthorPlan(grantRolePlan);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitGrantUser(
+ final AuthorTreePlan grantUserPlan, final Void context) {
+ return visitTreeAuthorPlan(grantUserPlan);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRevokeUser(
+ final AuthorTreePlan revokeUserPlan, final Void context) {
+ return visitTreeAuthorPlan(revokeUserPlan);
+ }
+
+ @Override
+ public Optional<ConfigPhysicalPlan> visitRevokeRole(
+ final AuthorTreePlan revokeRolePlan, final Void context) {
+ return visitTreeAuthorPlan(revokeRolePlan);
+ }
+
+ private Optional<ConfigPhysicalPlan> visitTreeAuthorPlan(final AuthorTreePlan authorTreePlan) {
+ final Set<Integer> permissions =
+ authorTreePlan.getPermissions().stream()
+ .filter(permission -> PrivilegeType.values()[permission].forRelationalSys())
+ .collect(Collectors.toSet());
+ return !permissions.isEmpty()
+ ? Optional.of(
+ new AuthorTreePlan(
+ authorTreePlan.getAuthorType(),
+ authorTreePlan.getUserName(),
+ authorTreePlan.getRoleName(),
+ authorTreePlan.getPassword(),
+ authorTreePlan.getNewPassword(),
+ permissions,
+ authorTreePlan.getGrantOpt(),
+ authorTreePlan.getNodeNameList()))
+ : Optional.empty();
+ }
+}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
index 48d9a6f2f16..15da365f57e 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
@@ -41,6 +41,7 @@ import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
@@ -317,6 +318,35 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver {
return configManager
.checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.USE_TRIGGER))
.getStatus();
+ case PipeCreateTable:
+ return configManager
+ .checkUserPrivileges(
+ username,
+ new PrivilegeUnion(
+ ((PipeCreateTablePlan) plan).getDatabase(),
+ ((PipeCreateTablePlan) plan).getTable().getTableName(),
+ PrivilegeType.CREATE))
+ .getStatus();
+ case AddTableColumn:
+ case SetTableProperties:
+ case CommitDeleteColumn:
+ return configManager
+ .checkUserPrivileges(
+ username,
+ new PrivilegeUnion(
+ ((PipeCreateTablePlan) plan).getDatabase(),
+ ((PipeCreateTablePlan) plan).getTable().getTableName(),
+ PrivilegeType.ALTER))
+ .getStatus();
+ case CommitDeleteTable:
+ return configManager
+ .checkUserPrivileges(
+ username,
+ new PrivilegeUnion(
+ ((PipeCreateTablePlan) plan).getDatabase(),
+ ((PipeCreateTablePlan) plan).getTable().getTableName(),
+ PrivilegeType.DROP))
+ .getStatus();
case GrantRole:
case GrantUser:
case RevokeUser:
@@ -338,22 +368,122 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver {
}
}
return StatusUtils.OK;
+ case RGrantUserAny:
+ case RGrantRoleAny:
+ case RRevokeUserAny:
+ case RRevokeRoleAny:
+ for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) {
+ final TSStatus status =
+ configManager
+ .checkUserPrivileges(
+ username, new PrivilegeUnion(PrivilegeType.values()[permission], true, true))
+ .getStatus();
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+ }
+ return StatusUtils.OK;
+ case RGrantUserAll:
+ case RGrantRoleAll:
+ case RRevokeUserAll:
+ case RRevokeRoleAll:
+ for (PrivilegeType privilegeType : PrivilegeType.values()) {
+ final TSStatus status;
+ if (privilegeType.isRelationalPrivilege()) {
+ status =
+ configManager
+ .checkUserPrivileges(username, new PrivilegeUnion(privilegeType, true, true))
+ .getStatus();
+ } else if (privilegeType.forRelationalSys()) {
+ status =
+ configManager
+ .checkUserPrivileges(username, new PrivilegeUnion(privilegeType, true))
+ .getStatus();
+ } else {
+ continue;
+ }
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+ }
+ return StatusUtils.OK;
+ case RGrantUserDBPriv:
+ case RGrantRoleDBPriv:
+ case RRevokeUserDBPriv:
+ case RRevokeRoleDBPriv:
+ for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) {
+ final TSStatus status =
+ configManager
+ .checkUserPrivileges(
+ username,
+ new PrivilegeUnion(
+ ((AuthorRelationalPlan) plan).getDatabaseName(),
+ PrivilegeType.values()[permission],
+ true))
+ .getStatus();
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+ }
+ return StatusUtils.OK;
+ case RGrantUserTBPriv:
+ case RGrantRoleTBPriv:
+ case RRevokeUserTBPriv:
+ case RRevokeRoleTBPriv:
+ for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) {
+ final TSStatus status =
+ configManager
+ .checkUserPrivileges(
+ username,
+ new PrivilegeUnion(
+ ((AuthorRelationalPlan) plan).getDatabaseName(),
+ ((AuthorRelationalPlan) plan).getTableName(),
+ PrivilegeType.values()[permission],
+ true))
+ .getStatus();
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+ }
+ return StatusUtils.OK;
+ case RGrantUserSysPri:
+ case RGrantRoleSysPri:
+ case RRevokeUserSysPri:
+ case RRevokeRoleSysPri:
+ for (final int permission : ((AuthorRelationalPlan) plan).getPermissions()) {
+ final TSStatus status =
+ configManager
+ .checkUserPrivileges(
+ username, new PrivilegeUnion(PrivilegeType.values()[permission], true))
+ .getStatus();
+ if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+ return status;
+ }
+ }
+ return StatusUtils.OK;
case UpdateUser:
+ case RUpdateUser:
return ((AuthorPlan) plan).getUserName().equals(username)
? StatusUtils.OK
: configManager
.checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_USER))
.getStatus();
case CreateUser:
+ case RCreateUser:
case CreateUserWithRawPassword:
case DropUser:
+ case RDropUser:
return configManager
.checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_USER))
.getStatus();
case CreateRole:
+ case RCreateRole:
case DropRole:
+ case RDropRole:
case GrantRoleToUser:
+ case RGrantUserRole:
case RevokeRoleFromUser:
+ case RRevokeUserRole:
return configManager
.checkUserPrivileges(username, new PrivilegeUnion(PrivilegeType.MANAGE_ROLE))
.getStatus();
@@ -552,6 +682,9 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver {
ByteBuffer.wrap(((PipeDeleteDevicesPlan) plan).getModBytes())),
true)
.getStatus();
+ case CreateUser:
+ case CreateUserWithRawPassword:
+ case CreateRole:
case DropUser:
case DropRole:
case GrantRole:
@@ -561,11 +694,34 @@ public class IoTDBConfigNodeReceiver extends IoTDBFileReceiver {
case RevokeRole:
case RevokeRoleFromUser:
case UpdateUser:
+ case RCreateUser:
+ case RCreateRole:
+ case RDropUser:
+ case RDropRole:
+ case RGrantRoleAll:
+ case RGrantUserAll:
+ case RRevokeRoleAll:
+ case RRevokeUserAll:
+ case RGrantRoleAny:
+ case RGrantUserAny:
+ case RRevokeUserAny:
+ case RRevokeRoleAny:
+ case RGrantRoleDBPriv:
+ case RGrantUserDBPriv:
+ case RRevokeRoleDBPriv:
+ case RRevokeUserDBPriv:
+ case RGrantRoleTBPriv:
+ case RGrantUserTBPriv:
+ case RRevokeRoleTBPriv:
+ case RRevokeUserTBPriv:
+ case RGrantRoleSysPri:
+ case RGrantUserSysPri:
+ case RRevokeRoleSysPri:
+ case RRevokeUserSysPri:
+ case RGrantUserRole:
+ case RRevokeUserRole:
return configManager.getPermissionManager().operatePermission((AuthorPlan) plan, true);
case CreateSchemaTemplate:
- case CreateUser:
- case CreateRole:
- case CreateUserWithRawPassword:
default:
return configManager.getConsensusManager().write(new PipeEnrichedPlan(plan));
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/visitor/PipeConfigPhysicalPlanTSStatusVisitor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/visitor/PipeConfigPhysicalPlanTSStatusVisitor.java
index 0583e32e280..653ef4339ea 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/visitor/PipeConfigPhysicalPlanTSStatusVisitor.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/visitor/PipeConfigPhysicalPlanTSStatusVisitor.java
@@ -22,7 +22,8 @@ package org.apache.iotdb.confignode.manager.pipe.receiver.visitor;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanVisitor;
-import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
import org.apache.iotdb.confignode.consensus.request.write.database.SetTTLPlan;
@@ -191,7 +192,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitCreateUser(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitCreateUser(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.USER_ALREADY_EXIST.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -200,7 +201,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitCreateRawUser(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitCreateRawUser(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.USER_ALREADY_EXIST.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -209,7 +210,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitUpdateUser(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitUpdateUser(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.USER_NOT_EXIST.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_USER_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -218,7 +219,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitDropUser(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitDropUser(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.USER_NOT_EXIST.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -227,7 +228,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitGrantUser(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitGrantUser(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.NO_PERMISSION.getStatusCode()) {
// Admin user
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
@@ -241,7 +242,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitRevokeUser(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitRevokeUser(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.NOT_HAS_PRIVILEGE.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -255,7 +256,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitCreateRole(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitCreateRole(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.ROLE_ALREADY_EXIST.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -264,7 +265,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitDropRole(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitDropRole(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.ROLE_NOT_EXIST.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -273,7 +274,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitGrantRole(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitGrantRole(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.ROLE_NOT_EXIST.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_USER_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -282,7 +283,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitRevokeRole(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitRevokeRole(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.NOT_HAS_PRIVILEGE.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -294,7 +295,7 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitGrantRoleToUser(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitGrantRoleToUser(final AuthorTreePlan plan, final TSStatus context) {
if (context.getCode() == TSStatusCode.USER_ALREADY_HAS_ROLE.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -303,7 +304,8 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
}
@Override
- public TSStatus visitRevokeRoleFromUser(final AuthorPlan plan, final TSStatus context) {
+ public TSStatus visitRevokeRoleFromUser(
+ final AuthorTreePlan revokeRoleFromUserPlan, final TSStatus context) {
if (context.getCode() == TSStatusCode.USER_NOT_HAS_ROLE.getStatusCode()) {
return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
@@ -311,7 +313,184 @@ public class PipeConfigPhysicalPlanTSStatusVisitor
return new TSStatus(TSStatusCode.PIPE_RECEIVER_USER_CONFLICT_EXCEPTION.getStatusCode())
.setMessage(context.getMessage());
}
- return super.visitRevokeRoleFromUser(plan, context);
+ return super.visitRevokeRoleFromUser(revokeRoleFromUserPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRCreateUser(
+ final AuthorRelationalPlan rCreateUserPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rCreateUserPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRCreateRole(
+ final AuthorRelationalPlan rCreateRolePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rCreateRolePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRUpdateUser(
+ final AuthorRelationalPlan rUpdateUserPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rUpdateUserPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRDropUserPlan(
+ final AuthorRelationalPlan rDropUserPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rDropUserPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRDropRolePlan(
+ final AuthorRelationalPlan rDropRolePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rDropRolePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantUserRole(
+ final AuthorRelationalPlan rGrantUserRolePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantUserRolePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeUserRole(
+ final AuthorRelationalPlan rRevokeUserRolePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeUserRolePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantUserAny(
+ final AuthorRelationalPlan rGrantUserAnyPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantUserAnyPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantRoleAny(
+ final AuthorRelationalPlan rGrantRoleAnyPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantRoleAnyPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantUserAll(
+ final AuthorRelationalPlan rGrantUserAllPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantUserAllPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantRoleAll(
+ final AuthorRelationalPlan rGrantRoleAllPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantRoleAllPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantUserDB(
+ final AuthorRelationalPlan rGrantUserDBPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantUserDBPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantUserTB(
+ final AuthorRelationalPlan rGrantUserTBPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantUserTBPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantRoleDB(
+ final AuthorRelationalPlan rGrantRoleDBPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantRoleDBPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantRoleTB(
+ final AuthorRelationalPlan rGrantRoleTBPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantRoleTBPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeUserAny(
+ final AuthorRelationalPlan rRevokeUserAnyPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeUserAnyPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeRoleAny(
+ final AuthorRelationalPlan rRevokeRoleAnyPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeRoleAnyPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeUserAll(
+ final AuthorRelationalPlan rRevokeUserAllPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeUserAllPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeRoleAll(
+ final AuthorRelationalPlan rRevokeRoleAllPlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeRoleAllPlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeUserDBPrivilege(
+ final AuthorRelationalPlan rRevokeUserDBPrivilegePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeUserDBPrivilegePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeUserTBPrivilege(
+ final AuthorRelationalPlan rRevokeUserTBPrivilegePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeUserTBPrivilegePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeRoleDBPrivilege(
+ final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeRoleTBPrivilegePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeRoleTBPrivilege(
+ final AuthorRelationalPlan rRevokeRoleTBPrivilegePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeRoleTBPrivilegePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantUserSysPrivilege(
+ final AuthorRelationalPlan rGrantUserSysPrivilegePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantUserSysPrivilegePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRGrantRoleSysPrivilege(
+ final AuthorRelationalPlan rGrantRoleSysPrivilegePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rGrantRoleSysPrivilegePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeUserSysPrivilege(
+ final AuthorRelationalPlan rRevokeUserSysPrivilegePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeUserSysPrivilegePlan, context);
+ }
+
+ @Override
+ public TSStatus visitRRevokeRoleSysPrivilege(
+ final AuthorRelationalPlan rRevokeRoleSysPrivilegePlan, final TSStatus context) {
+ return visitAuthorRelationalPlan(rRevokeRoleSysPrivilegePlan, context);
+ }
+
+ private TSStatus visitAuthorRelationalPlan(
+ final AuthorRelationalPlan plan, final TSStatus context) {
+ if (context.getCode() == TSStatusCode.USER_NOT_EXIST.getStatusCode()
+ || context.getCode() == TSStatusCode.USER_ALREADY_EXIST.getStatusCode()
+ || context.getCode() == TSStatusCode.ROLE_NOT_EXIST.getStatusCode()
+ || context.getCode() == TSStatusCode.ROLE_ALREADY_EXIST.getStatusCode()
+ || context.getCode() == TSStatusCode.USER_ALREADY_HAS_ROLE.getStatusCode()
+ || context.getCode() == TSStatusCode.USER_NOT_HAS_ROLE.getStatusCode()
+ || context.getCode() == TSStatusCode.NO_PERMISSION.getStatusCode()) {
+ return new TSStatus(TSStatusCode.PIPE_RECEIVER_IDEMPOTENT_CONFLICT_EXCEPTION.getStatusCode())
+ .setMessage(context.getMessage());
+ }
+ return visitPlan(plan, context);
}
@Override
diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanScopeParseVisitorTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanScopeParseVisitorTest.java
new file mode 100644
index 00000000000..6e5e9870fbf
--- /dev/null
+++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanScopeParseVisitorTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.manager.pipe.extractor;
+
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorTreePlan;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.stream.Collectors;
+
+public class PipeConfigPhysicalPlanScopeParseVisitorTest {
+ @Test
+ public void testTreeScopeParsing() {
+ testTreeScopeParsing(ConfigPhysicalPlanType.GrantRole, false);
+ testTreeScopeParsing(ConfigPhysicalPlanType.RevokeRole, false);
+ testTreeScopeParsing(ConfigPhysicalPlanType.GrantUser, true);
+ testTreeScopeParsing(ConfigPhysicalPlanType.RevokeUser, true);
+ }
+
+ private void testTreeScopeParsing(final ConfigPhysicalPlanType type, final boolean isUser) {
+ Assert.assertEquals(
+ new AuthorTreePlan(
+ type,
+ isUser ? "user" : "",
+ isUser ? "" : "role",
+ "",
+ "",
+ new HashSet<>(
+ Arrays.stream(PrivilegeType.values())
+ .filter(PrivilegeType::forRelationalSys)
+ .map(Enum::ordinal)
+ .collect(Collectors.toList())),
+ false,
+ Collections.singletonList(new PartialPath(new String[] {"root", "**"}))),
+ IoTDBConfigRegionExtractor.TREE_SCOPE_PARSE_VISITOR
+ .process(
+ new AuthorTreePlan(
+ type,
+ isUser ? "user" : "",
+ isUser ? "" : "role",
+ "",
+ "",
+ new HashSet<>(
+ Arrays.stream(PrivilegeType.values())
+ .filter(privilegeType -> !privilegeType.isRelationalPrivilege())
+ .map(Enum::ordinal)
+ .collect(Collectors.toList())),
+ false,
+ Collections.singletonList(new PartialPath(new String[] {"root", "**"}))),
+ null)
+ .orElseThrow(AssertionError::new));
+ }
+
+ @Test
+ public void testTableScopeParsing() {
+ testTableScopeParsing(
+ ConfigPhysicalPlanType.GrantRole, ConfigPhysicalPlanType.RGrantRoleAll, false);
+ testTableScopeParsing(
+ ConfigPhysicalPlanType.RevokeRole, ConfigPhysicalPlanType.RRevokeRoleAll, false);
+ testTableScopeParsing(
+ ConfigPhysicalPlanType.GrantUser, ConfigPhysicalPlanType.RGrantUserAll, true);
+ testTableScopeParsing(
+ ConfigPhysicalPlanType.RevokeUser, ConfigPhysicalPlanType.RRevokeUserAll, true);
+ }
+
+ private void testTableScopeParsing(
+ final ConfigPhysicalPlanType outputType,
+ final ConfigPhysicalPlanType inputType,
+ final boolean isUser) {
+ Assert.assertEquals(
+ new AuthorTreePlan(
+ outputType,
+ isUser ? "user" : "",
+ isUser ? "" : "role",
+ "",
+ "",
+ new HashSet<>(
+ Arrays.stream(PrivilegeType.values())
+ .filter(PrivilegeType::forRelationalSys)
+ .map(Enum::ordinal)
+ .collect(Collectors.toList())),
+ true,
+ Collections.emptyList()),
+ IoTDBConfigRegionExtractor.TABLE_SCOPE_PARSE_VISITOR
+ .process(
+ new AuthorRelationalPlan(
+ inputType, isUser ? "user" : "", isUser ? "" : "role", "", "", -1, true),
+ null)
+ .orElseThrow(AssertionError::new));
+ }
+}
diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitorTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitorTest.java
index 0681dc5aaca..64ec14be5d8 100644
--- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitorTest.java
+++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/extractor/PipeConfigPhysicalPlanTablePatternParseVisitorTest.java
@@ -19,10 +19,12 @@
package org.apache.iotdb.confignode.manager.pipe.extractor;
+import org.apache.iotdb.commons.auth.entity.PrivilegeType;
import org.apache.iotdb.commons.pipe.datastructure.pattern.TablePattern;
import org.apache.iotdb.commons.schema.table.TsTable;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlan;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
+import org.apache.iotdb.confignode.consensus.request.write.auth.AuthorRelationalPlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
import org.apache.iotdb.confignode.consensus.request.write.database.DeleteDatabasePlan;
import org.apache.iotdb.confignode.consensus.request.write.pipe.payload.PipeCreateTablePlan;
@@ -112,6 +114,29 @@ public class PipeConfigPhysicalPlanTablePatternParseVisitorTest {
new CommitDeleteTablePlan("da", "ac"));
}
+ @Test
+ public void testAuth() {
+ testInput(
+ new AuthorRelationalPlan(
+ ConfigPhysicalPlanType.RGrantRoleAll, "", "role", "", "", -1, false),
+ new AuthorRelationalPlan(
+ ConfigPhysicalPlanType.RGrantUserDBPriv,
+ "user",
+ "",
+ "da",
+ "",
+ PrivilegeType.SELECT.ordinal(),
+ false),
+ new AuthorRelationalPlan(
+ ConfigPhysicalPlanType.RGrantUserTBPriv,
+ "user",
+ "",
+ "db1",
+ "ac",
+ PrivilegeType.DROP.ordinal(),
+ false));
+ }
+
private void testInput(
final ConfigPhysicalPlan trueInput,
final ConfigPhysicalPlan falseInput1,
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/SchemaRegionListeningFilter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/SchemaRegionListeningFilter.java
index cb64d208b38..86e985f330c 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/SchemaRegionListeningFilter.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/SchemaRegionListeningFilter.java
@@ -41,8 +41,8 @@ import java.util.stream.Collectors;
import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.getExclusionString;
import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.getInclusionString;
import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.parseOptions;
-import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.tableOnlySyncPrefix;
-import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.treeOnlySyncPrefix;
+import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.tableOnlySyncPrefixes;
+import static org.apache.iotdb.commons.pipe.datastructure.options.PipeInclusionOptions.treeOnlySyncPrefixes;
/**
* {@link SchemaRegionListeningFilter} is to classify the {@link PlanNode}s to help {@link
@@ -118,11 +118,11 @@ public class SchemaRegionListeningFilter {
exclusionOptions.forEach(exclusion -> planTypes.removeAll(getOptionsByPrefix(exclusion)));
if (!TreePattern.isTreeModelDataAllowToBeCaptured(parameters)) {
- planTypes.removeAll(getOptionsByPrefix(treeOnlySyncPrefix));
+ treeOnlySyncPrefixes.forEach(prefix -> planTypes.removeAll(getOptionsByPrefix(prefix)));
}
if (!TablePattern.isTableModelDataAllowToBeCaptured(parameters)) {
- planTypes.removeAll(getOptionsByPrefix(tableOnlySyncPrefix));
+ tableOnlySyncPrefixes.forEach(prefix -> planTypes.removeAll(getOptionsByPrefix(prefix)));
}
return planTypes;
}
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/datastructure/options/PipeInclusionOptions.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/datastructure/options/PipeInclusionOptions.java
index a4a91f504a0..61478ed88b1 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/datastructure/options/PipeInclusionOptions.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/datastructure/options/PipeInclusionOptions.java
@@ -30,6 +30,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
@@ -45,10 +46,16 @@ import static org.apache.iotdb.commons.pipe.config.constant.PipeExtractorConstan
public class PipeInclusionOptions {
private static final Logger LOGGER = LoggerFactory.getLogger(PipeInclusionOptions.class);
- public static final PartialPath treeOnlySyncPrefix =
- new PartialPath(new String[] {"schema", "timeseries"});
- public static final PartialPath tableOnlySyncPrefix =
- new PartialPath(new String[] {"schema", "table"});
+ public static final List<PartialPath> treeOnlySyncPrefixes =
+ Collections.singletonList(new PartialPath(new String[] {"schema", "timeseries"}));
+ public static final List<PartialPath> tableOnlySyncPrefixes =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ new PartialPath(new String[] {"schema", "table"}),
+ new PartialPath(new String[] {"auth", "role", "grant", "table"}),
+ new PartialPath(new String[] {"auth", "role", "revoke", "table"}),
+ new PartialPath(new String[] {"auth", "user", "grant", "table"}),
+ new PartialPath(new String[] {"auth", "user", "revoke", "table"})));
public static final String ALL = "all";
private static final Set<PartialPath> OPTIONS = new HashSet<>();