This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/inlong.git


The following commit(s) were added to refs/heads/master by this push:
     new d45185a609 [INLONG-8276][Manager] InlongGroup support multiple tenant 
(#8346)
d45185a609 is described below

commit d45185a609469c2ec4cd97e9985e6f969be0c98e
Author: vernedeng <[email protected]>
AuthorDate: Wed Jun 28 12:44:07 2023 +0800

    [INLONG-8276][Manager] InlongGroup support multiple tenant (#8346)
---
 .../manager/dao/config/JDBCSourceConfig.java       |   3 -
 .../manager/dao/entity/InlongGroupEntity.java      |   1 +
 .../dao/interceptor/MultiTenantInterceptor.java    | 153 +++++++++++++++------
 .../MultiTenantInterceptorConfiguration.java       |  51 +++++++
 .../dao/mapper/InlongGroupEntityMapper.java        |   3 +
 .../resources/mappers/InlongGroupEntityMapper.xml  |  32 +++--
 .../org/apache/inlong/manager/dao/DaoBaseTest.java |  25 ++++
 .../dao/mapper/InlongGroupEntityMapperTest.java    |  52 ++++++-
 .../inlong/manager/service/ServiceBaseTest.java    |  12 ++
 .../main/resources/h2/apache_inlong_manager.sql    |   4 +-
 .../manager-web/sql/apache_inlong_manager.sql      |   2 +
 inlong-manager/manager-web/sql/changes-1.8.0.sql   |   7 +-
 .../web/controller/InlongGroupController.java      |  20 +++
 13 files changed, 304 insertions(+), 61 deletions(-)

diff --git 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/config/JDBCSourceConfig.java
 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/config/JDBCSourceConfig.java
index 263fea8b43..b019895f03 100644
--- 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/config/JDBCSourceConfig.java
+++ 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/config/JDBCSourceConfig.java
@@ -17,8 +17,6 @@
 
 package org.apache.inlong.manager.dao.config;
 
-import org.apache.inlong.manager.dao.interceptor.MultiTenantInterceptor;
-
 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
 import org.apache.ibatis.session.SqlSessionFactory;
 import org.mybatis.spring.SqlSessionFactoryBean;
@@ -54,7 +52,6 @@ public class JDBCSourceConfig {
         SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
         bean.setDataSource(dataSource());
         bean.setMapperLocations(new 
PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
-        
Objects.requireNonNull(bean.getObject()).getConfiguration().addInterceptor(new 
MultiTenantInterceptor());
         
Objects.requireNonNull(bean.getObject()).getConfiguration().setMapUnderscoreToCamelCase(true);
         return bean.getObject();
     }
diff --git 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/entity/InlongGroupEntity.java
 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/entity/InlongGroupEntity.java
index 54b2b0b900..a302f51630 100644
--- 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/entity/InlongGroupEntity.java
+++ 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/entity/InlongGroupEntity.java
@@ -33,6 +33,7 @@ public class InlongGroupEntity implements Serializable {
     private String inlongGroupId;
     private String name;
     private String description;
+    private String tenant;
     private String mqType;
     private String mqResource;
     private Integer dailyRecords;
diff --git 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/interceptor/MultiTenantInterceptor.java
 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/interceptor/MultiTenantInterceptor.java
index 00f3f67cb6..d47c5073d0 100644
--- 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/interceptor/MultiTenantInterceptor.java
+++ 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/interceptor/MultiTenantInterceptor.java
@@ -18,18 +18,19 @@
 package org.apache.inlong.manager.dao.interceptor;
 
 import org.apache.inlong.manager.common.consts.InlongConstants;
+import org.apache.inlong.manager.common.tenant.MultiTenantQuery;
+import org.apache.inlong.manager.common.util.JsonUtils;
 import org.apache.inlong.manager.pojo.user.LoginUserUtils;
 import org.apache.inlong.manager.pojo.user.UserInfo;
 
-import net.sf.jsqlparser.expression.Expression;
-import net.sf.jsqlparser.parser.CCJSqlParserManager;
-import net.sf.jsqlparser.parser.CCJSqlParserUtil;
-import net.sf.jsqlparser.statement.select.PlainSelect;
-import net.sf.jsqlparser.statement.select.Select;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.executor.statement.StatementHandler;
+import org.apache.ibatis.cache.CacheKey;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.executor.parameter.ParameterHandler;
 import org.apache.ibatis.mapping.BoundSql;
 import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.ParameterMapping;
 import org.apache.ibatis.plugin.Interceptor;
 import org.apache.ibatis.plugin.Intercepts;
 import org.apache.ibatis.plugin.Invocation;
@@ -37,63 +38,131 @@ import org.apache.ibatis.plugin.Plugin;
 import org.apache.ibatis.plugin.Signature;
 import org.apache.ibatis.reflection.DefaultReflectorFactory;
 import org.apache.ibatis.reflection.MetaObject;
-import org.apache.ibatis.reflection.SystemMetaObject;
-
-import java.io.StringReader;
-import java.sql.Connection;
+import org.apache.ibatis.reflection.ReflectorFactory;
+import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
+import org.apache.ibatis.reflection.factory.ObjectFactory;
+import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
+import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+
+import java.sql.PreparedStatement;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 /**
- * Interceptor for multi-tenant.
+ * This interceptor intercept those queries annotated by {@link 
MultiTenantQuery}.
+ *
+ * <p>The main idea of MultiTenantInterceptor is that developer define sql 
template
+ * support multiple tenant in mapper.xml, but no need to pass the tenant 
explicitly in mapper.java.</p>
+ *
+ * <p>MultiTenantInterceptor will insert <strong>tenant</strong> into the 
parameter maps in
+ * {@link Executor} and {@link ParameterHandler} stages.</p>
  */
+@Slf4j
 @Intercepts({
-        @Signature(type = StatementHandler.class, method = "prepare", args = 
{Connection.class, Integer.class})
+        @Signature(type = ParameterHandler.class, method = "setParameters", 
args = PreparedStatement.class),
+        @Signature(type = Executor.class, method = "query", args = 
{MappedStatement.class, Object.class,
+                RowBounds.class, ResultHandler.class, CacheKey.class, 
BoundSql.class}),
+        @Signature(type = Executor.class, method = "query", args = 
{MappedStatement.class, Object.class,
+                RowBounds.class, ResultHandler.class})
 })
 public class MultiTenantInterceptor implements Interceptor {
 
-    private static final String TENANT_CONDITION = "tenant=";
-
+    private static final String KEY_TENANT = "tenant";
+    private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new 
DefaultObjectFactory();
+    private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = 
new DefaultObjectWrapperFactory();
+    private static final ReflectorFactory REFLECTOR_FACTORY = new 
DefaultReflectorFactory();
     @Override
     public Object intercept(Invocation invocation) throws Throwable {
-        StatementHandler statementHandler = (StatementHandler) 
invocation.getTarget();
-        MetaObject metaObject = MetaObject.forObject(statementHandler, 
SystemMetaObject.DEFAULT_OBJECT_FACTORY,
-                SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new 
DefaultReflectorFactory());
-        MappedStatement mappedStatement = (MappedStatement) 
metaObject.getValue("delegate.mappedStatement");
+        if (invocation.getTarget() instanceof ParameterHandler) {
+            return doParameterHandler((ParameterHandler) 
invocation.getTarget(), invocation);
+        } else if (invocation.getTarget() instanceof Executor) {
+            return doExecutor(invocation);
+        } else {
+            throw new Throwable("do not support type of target=" + 
invocation.getTarget());
+        }
+    }
+
+    private Object doExecutor(Invocation invocation) throws Throwable {
+        MappedStatement mappedStatement = (MappedStatement) 
invocation.getArgs()[0];
+        String fullMethodName = mappedStatement.getId();
+        if 
(!MultiTenantQueryFilter.isMultiTenantQuery(fullMethodName.split(InlongConstants.UNDERSCORE)[0]))
 {
+            return invocation.proceed();
+        }
+        try {
+            Object[] args = invocation.getArgs();
+            MappedStatement ms = (MappedStatement) args[0];
+            Object parameter = args[1];
+            BoundSql boundSql;
+            if (args.length == 4) {
+                // 4 params
+                boundSql = ms.getBoundSql(parameter);
+            } else {
+                // 6 params
+                boundSql = (BoundSql) args[5];
+            }
+
+            List<ParameterMapping> parameterMappings = 
boundSql.getParameterMappings();
+            // new param mapping
+            Map<String, Object> newParameter = makeNewParameters(parameter, 
parameterMappings);
+            // update params
+            invocation.getArgs()[1] = newParameter;
 
+            return invocation.proceed();
+        } catch (Exception e) {
+            log.error("failed to do executor in MultiTenantInterceptor", e);
+            throw e;
+        }
+
+    }
+
+    private Object doParameterHandler(ParameterHandler parameterHandler, 
Invocation invocation) throws Throwable {
+        MetaObject metaResultSetHandler = 
MetaObject.forObject(parameterHandler, DEFAULT_OBJECT_FACTORY,
+                DEFAULT_OBJECT_WRAPPER_FACTORY, REFLECTOR_FACTORY);
+        MappedStatement mappedStatement = (MappedStatement) 
metaResultSetHandler.getValue("mappedStatement");
         String fullMethodName = mappedStatement.getId();
         if 
(!MultiTenantQueryFilter.isMultiTenantQuery(fullMethodName.split(InlongConstants.UNDERSCORE)[0]))
 {
             return invocation.proceed();
         }
+        Object parameterObject = 
metaResultSetHandler.getValue("parameterObject");
 
-        BoundSql boundSql = statementHandler.getBoundSql();
-        String sql = boundSql.getSql();
+        BoundSql boundSql = (BoundSql) 
metaResultSetHandler.getValue("boundSql");
 
-        CCJSqlParserManager parserManager = new CCJSqlParserManager();
-        Select select = (Select) parserManager.parse(new StringReader(sql));
-        PlainSelect plain = (PlainSelect) select.getSelectBody();
+        Map<String, Object> newParams = makeNewParameters(parameterObject, 
boundSql.getParameterMappings());
 
-        StringBuilder whereSql = new StringBuilder();
-        whereSql.append(TENANT_CONDITION).append(getTenant());
+        metaResultSetHandler.setValue("parameterObject", newParams);
+        return invocation.proceed();
+    }
 
-        Expression where = plain.getWhere();
-        if (where == null) {
-            Expression expression = 
CCJSqlParserUtil.parseCondExpression(whereSql.toString());
-            plain.setWhere(expression);
+    private Map<String, Object> makeNewParameters(Object parameterObject, 
List<ParameterMapping> parameters) {
+        Map<String, Object> params;
+        if (isPrimitiveOrWrapper(parameterObject)) {
+            params = new LinkedHashMap<>();
+            params.put(parameters.get(0).getProperty(), parameterObject);
         } else {
-            if (where.toString().contains(TENANT_CONDITION)) {
-                return invocation.proceed();
-            }
+            String jsonStr = JsonUtils.toJsonString(parameterObject);
+            params = JsonUtils.parseObject(jsonStr, Map.class);
+        }
+        params.put(KEY_TENANT, getTenant());
+        return params;
+    }
 
-            // else, append the tenant condition
-            whereSql.append(" and ( ").append(where).append(" )");
-            Expression expression = 
CCJSqlParserUtil.parseCondExpression(whereSql.toString());
-            plain.setWhere(expression);
+    private boolean isPrimitiveOrWrapper(Object obj) {
+        try {
+            Class<?> clazz = obj.getClass();
+            return (obj instanceof String)
+                    || clazz.isPrimitive()
+                    || ((Class<?>) 
clazz.getField("TYPE").get(null)).isPrimitive();
+        } catch (Exception e) {
+            return false;
         }
-        metaObject.setValue("delegate.boundSql.sql", select.toString());
-        return invocation.proceed();
+
     }
 
-    private static String getTenant() {
+    private String getTenant() {
         UserInfo userInfo = LoginUserUtils.getLoginUser();
         if (userInfo == null) {
             throw new IllegalStateException("current login user is null, 
please login first");
@@ -107,11 +176,7 @@ public class MultiTenantInterceptor implements Interceptor 
{
 
     @Override
     public Object plugin(Object target) {
-        if (target instanceof StatementHandler) {
-            return Plugin.wrap(target, this);
-        } else {
-            return target;
-        }
+        return Plugin.wrap(target, this);
     }
 
     @Override
diff --git 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/interceptor/MultiTenantInterceptorConfiguration.java
 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/interceptor/MultiTenantInterceptorConfiguration.java
new file mode 100644
index 0000000000..231a86fb1b
--- /dev/null
+++ 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/interceptor/MultiTenantInterceptorConfiguration.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.manager.dao.interceptor;
+
+import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+
+import java.util.List;
+
+/**
+ * Configuration to add {@link MultiTenantInterceptor} into the sql session 
interceptorChain.
+ *
+ * <p>This MultiTenantInterceptor must be added after {@link 
com.github.pagehelper.PageInterceptor} to ensure the
+ * correct parameter mapping.</p>
+ */
+@Configuration
+public class MultiTenantInterceptorConfiguration {
+
+    @Autowired
+    private List<SqlSessionFactory> sqlSessionFactoryList;
+    @Autowired
+    private PageHelperAutoConfiguration pageHelperAutoConfiguration;
+
+    @PostConstruct
+    public void init() throws Exception {
+        MultiTenantInterceptor multiTenantInterceptor = new 
MultiTenantInterceptor();
+        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
+            org.apache.ibatis.session.Configuration configuration = 
sqlSessionFactory.getConfiguration();
+            configuration.addInterceptor(multiTenantInterceptor);
+        }
+    }
+}
diff --git 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/mapper/InlongGroupEntityMapper.java
 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/mapper/InlongGroupEntityMapper.java
index 1ad77aa6fa..82af114c67 100644
--- 
a/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/mapper/InlongGroupEntityMapper.java
+++ 
b/inlong-manager/manager-dao/src/main/java/org/apache/inlong/manager/dao/mapper/InlongGroupEntityMapper.java
@@ -17,6 +17,7 @@
 
 package org.apache.inlong.manager.dao.mapper;
 
+import org.apache.inlong.manager.common.tenant.MultiTenantQuery;
 import org.apache.inlong.manager.dao.entity.InlongGroupEntity;
 import org.apache.inlong.manager.pojo.group.InlongGroupBriefInfo;
 import org.apache.inlong.manager.pojo.group.InlongGroupPageRequest;
@@ -33,6 +34,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+@MultiTenantQuery
 @Repository
 public interface InlongGroupEntityMapper {
 
@@ -60,6 +62,7 @@ public interface InlongGroupEntityMapper {
      *
      * @return All inlong group info.
      */
+    @MultiTenantQuery(with = false)
     @Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 
Integer.MIN_VALUE)
     Cursor<SortSourceGroupInfo> selectAllGroups();
 
diff --git 
a/inlong-manager/manager-dao/src/main/resources/mappers/InlongGroupEntityMapper.xml
 
b/inlong-manager/manager-dao/src/main/resources/mappers/InlongGroupEntityMapper.xml
index 92430cff47..e995d6f549 100644
--- 
a/inlong-manager/manager-dao/src/main/resources/mappers/InlongGroupEntityMapper.xml
+++ 
b/inlong-manager/manager-dao/src/main/resources/mappers/InlongGroupEntityMapper.xml
@@ -25,6 +25,7 @@
         <result column="inlong_group_id" jdbcType="VARCHAR" 
property="inlongGroupId"/>
         <result column="name" jdbcType="VARCHAR" property="name"/>
         <result column="description" jdbcType="VARCHAR" 
property="description"/>
+        <result column="tenant" jdbcType="VARCHAR" property="tenant"/>
         <result column="mq_type" jdbcType="VARCHAR" property="mqType"/>
         <result column="mq_resource" jdbcType="VARCHAR" property="mqResource"/>
         <result column="daily_records" jdbcType="INTEGER" 
property="dailyRecords"/>
@@ -56,7 +57,7 @@
     </resultMap>
 
     <sql id="Base_Column_List">
-        id, inlong_group_id, name, description, mq_type, mq_resource, 
daily_records, daily_storage,
+        id, inlong_group_id, name, description, tenant, mq_type, mq_resource, 
daily_records, daily_storage,
         peak_records, max_length, enable_zookeeper, enable_create_resource, 
inlong_group_mode, data_report_type,
         inlong_cluster_tag, ext_params, in_charges, followers, status, 
previous_status, is_deleted,
         creator, modifier, create_time, modify_time, version
@@ -65,7 +66,7 @@
     <insert id="insert" useGeneratedKeys="true" keyProperty="id"
             
parameterType="org.apache.inlong.manager.dao.entity.InlongGroupEntity">
         insert into inlong_group (id, inlong_group_id,
-                                  name, description,
+                                  name, description, tenant,
                                   mq_type, mq_resource,
                                   daily_records, daily_storage,
                                   peak_records, max_length,
@@ -76,7 +77,7 @@
                                   status, previous_status,
                                   creator, modifier)
         values (#{id,jdbcType=INTEGER}, #{inlongGroupId,jdbcType=VARCHAR},
-                #{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
+                #{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, 
#{tenant,jdbcType=VARCHAR},
                 #{mqType,jdbcType=VARCHAR}, #{mqResource,jdbcType=VARCHAR},
                 #{dailyRecords,jdbcType=INTEGER}, 
#{dailyStorage,jdbcType=INTEGER},
                 #{peakRecords,jdbcType=INTEGER}, #{maxLength,jdbcType=INTEGER},
@@ -88,16 +89,18 @@
                 #{creator,jdbcType=VARCHAR}, #{modifier,jdbcType=VARCHAR})
     </insert>
 
-    <select id="selectByPrimaryKey" parameterType="java.lang.Integer" 
resultMap="BaseResultMap">
+    <select id="selectByPrimaryKey" resultMap="BaseResultMap">
         select
         <include refid="Base_Column_List"/>
         from inlong_group
         where id = #{id,jdbcType=INTEGER}
+        and tenant = #{tenant,jdbcType=VARCHAR}
     </select>
     <select id="countGroupByUser" resultMap="statusCountMap">
         select count(*) as total, status
         from inlong_group
         where is_deleted = 0
+          and tenant = #{tenant,jdbcType=VARCHAR}
           <if test="inlongGroupMode != null">
               and inlong_group_mode = #{inlongGroupMode,jdbcType=TINYINT}
           </if>
@@ -109,6 +112,7 @@
         <include refid="Base_Column_List"/>
         from inlong_group
         where inlong_group_id = #{groupId, jdbcType=VARCHAR}
+        and tenant = #{tenant, jdbcType=VARCHAR}
         and is_deleted = 0
     </select>
     <select id="selectByGroupIdForUpdate" resultMap="BaseResultMap">
@@ -116,6 +120,7 @@
         <include refid="Base_Column_List"/>
         from inlong_group
         where inlong_group_id = #{groupId, jdbcType=VARCHAR}
+        and tenant = #{tenant,jdbcType=VARCHAR}
         and is_deleted = 0 for update
     </select>
     <select id="selectByCondition" resultMap="BaseResultMap"
@@ -124,12 +129,8 @@
         <include refid="Base_Column_List"/>
         from inlong_group
         <where>
-            is_deleted = 0
-            <if test="isAdminRole == false">
-                and (
-                creator = #{currentUser, jdbcType=VARCHAR} or 
find_in_set(#{currentUser, jdbcType=VARCHAR}, in_charges)
-                )
-            </if>
+            tenant = #{tenant,jdbcType=VARCHAR}
+            and is_deleted = 0
             <if test="keyword != null and keyword != ''">
                 and (inlong_group_id like CONCAT('%',#{keyword},'%') or name 
like CONCAT('%',#{keyword},'%'))
             </if>
@@ -177,6 +178,7 @@
         from inlong_group
         <where>
             is_deleted = 0
+            and tenant = #{tenant,jdbcType=VARCHAR}
             <if test="mqType != null and mqType != ''">
                 and mq_type = #{mqType, jdbcType=VARCHAR}
             </if>
@@ -203,6 +205,7 @@
         from inlong_group
         <where>
             is_deleted = 0
+            and tenant = #{tenant,jdbcType=VARCHAR}
             <if test="groupIdList != null and groupIdList.size() > 0">
                 and inlong_group_id in
                 <foreach collection="groupIdList" item="inlongGroupId" 
index="index" open="(" close=")" separator=",">
@@ -216,6 +219,7 @@
         <include refid="Base_Column_List"/>
         from inlong_group
         where is_deleted = 0
+        and tenant = #{tenant,jdbcType=VARCHAR}
         and inlong_cluster_tag = #{inlongClusterTag, jdbcType=VARCHAR}
         limit 10
     </select>
@@ -232,6 +236,7 @@
         select inlong_group_id
         from inlong_group
         where modify_time &lt;= #{timeBefore, jdbcType=TIMESTAMP}
+        and tenant = #{tenant,jdbcType=VARCHAR}
         group by inlong_group_id
         having min(is_deleted) > 0
         limit #{limit, jdbcType=INTEGER}
@@ -264,6 +269,7 @@
             modifier               = #{modifier,jdbcType=VARCHAR},
             version                = #{version,jdbcType=INTEGER} + 1
         where id = #{id,jdbcType=INTEGER}
+          and tenant = #{tenant,jdbcType=VARCHAR}
           and version = #{version,jdbcType=INTEGER}
     </update>
     <update id="updateByIdentifierSelective" 
parameterType="org.apache.inlong.manager.dao.entity.InlongGroupEntity">
@@ -332,6 +338,7 @@
             version = #{version,jdbcType=INTEGER} + 1
         </set>
         where inlong_group_id = #{inlongGroupId, jdbcType=VARCHAR}
+        and tenant = #{tenant,jdbcType=VARCHAR}
         and is_deleted = 0
         and version = #{version, jdbcType=INTEGER}
     </update>
@@ -341,13 +348,15 @@
             status          = #{status, jdbcType=INTEGER},
             modifier        = #{modifier, jdbcType=VARCHAR}
         where inlong_group_id = #{groupId, jdbcType=VARCHAR}
+          and tenant = #{tenant,jdbcType=VARCHAR}
           and is_deleted = 0
     </update>
 
-    <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
+    <delete id="deleteByPrimaryKey">
         delete
         from inlong_group
         where id = #{id,jdbcType=INTEGER}
+        and tenant = #{tenant,jdbcType=VARCHAR}
     </delete>
     <delete id="deleteByInlongGroupIds">
         delete
@@ -356,5 +365,6 @@
         <foreach item="item" index="index" collection="groupIdList" open="(" 
close=")" separator=",">
             #{item}
         </foreach>
+        and tenant = #{tenant,jdbcType=VARCHAR}
     </delete>
 </mapper>
diff --git 
a/inlong-manager/manager-dao/src/test/java/org/apache/inlong/manager/dao/DaoBaseTest.java
 
b/inlong-manager/manager-dao/src/test/java/org/apache/inlong/manager/dao/DaoBaseTest.java
index 1cceaea55d..2d0b149696 100644
--- 
a/inlong-manager/manager-dao/src/test/java/org/apache/inlong/manager/dao/DaoBaseTest.java
+++ 
b/inlong-manager/manager-dao/src/test/java/org/apache/inlong/manager/dao/DaoBaseTest.java
@@ -17,8 +17,11 @@
 
 package org.apache.inlong.manager.dao;
 
+import org.apache.inlong.manager.pojo.user.LoginUserUtils;
+import org.apache.inlong.manager.pojo.user.UserInfo;
 import org.apache.inlong.manager.test.BaseTest;
 
+import org.junit.jupiter.api.BeforeEach;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.annotation.Rollback;
@@ -30,4 +33,26 @@ import 
org.springframework.transaction.annotation.Transactional;
 @SpringBootTest(classes = DaoBaseTest.class)
 public abstract class DaoBaseTest extends BaseTest {
 
+    public static final String PUBLIC_TENANT = "public";
+    public static final String ANOTHER_TENANT = "another";
+    public static final String ADMIN = "admin";
+
+    @BeforeEach
+    public void login() {
+        UserInfo userInfo = new UserInfo();
+        userInfo.setTenant(PUBLIC_TENANT);
+        userInfo.setName(ADMIN);
+        LoginUserUtils.setUserLoginInfo(userInfo);
+    }
+
+    public void setOtherUser(String newUser) {
+        UserInfo info = LoginUserUtils.getLoginUser();
+        info.setName(newUser);
+    }
+
+    public void setOtherTenant(String newTenant) {
+        UserInfo info = LoginUserUtils.getLoginUser();
+        info.setTenant(newTenant);
+    }
+
 }
diff --git 
a/inlong-manager/manager-dao/src/test/java/org/apache/inlong/manager/dao/mapper/InlongGroupEntityMapperTest.java
 
b/inlong-manager/manager-dao/src/test/java/org/apache/inlong/manager/dao/mapper/InlongGroupEntityMapperTest.java
index 133657f47c..c07e6bc953 100644
--- 
a/inlong-manager/manager-dao/src/test/java/org/apache/inlong/manager/dao/mapper/InlongGroupEntityMapperTest.java
+++ 
b/inlong-manager/manager-dao/src/test/java/org/apache/inlong/manager/dao/mapper/InlongGroupEntityMapperTest.java
@@ -20,12 +20,15 @@ package org.apache.inlong.manager.dao.mapper;
 import org.apache.inlong.manager.common.consts.InlongConstants;
 import org.apache.inlong.manager.dao.DaoBaseTest;
 import org.apache.inlong.manager.dao.entity.InlongGroupEntity;
+import org.apache.inlong.manager.pojo.group.InlongGroupPageRequest;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * Inlong group entity mapper test for {@link InlongGroupEntityMapper}
@@ -39,10 +42,23 @@ public class InlongGroupEntityMapperTest extends 
DaoBaseTest {
     public void deleteByPrimaryKey() {
         InlongGroupEntity entity = createGroupEntity();
         groupEntityMapper.insert(entity);
-        groupEntityMapper.deleteByPrimaryKey(entity.getId());
+        int delete = groupEntityMapper.deleteByPrimaryKey(entity.getId());
+        Assertions.assertEquals(1, delete);
         
Assertions.assertNull(groupEntityMapper.selectByGroupId(entity.getInlongGroupId()));
     }
 
+    @Test
+    public void deleteByPrimaryKeyWithOtherTenant() {
+        InlongGroupEntity entity = createGroupEntity();
+        groupEntityMapper.insert(entity);
+        setOtherTenant(ANOTHER_TENANT);
+        int delete = groupEntityMapper.deleteByPrimaryKey(entity.getId());
+        setOtherTenant(PUBLIC_TENANT);
+        InlongGroupEntity select = 
groupEntityMapper.selectByGroupId(entity.getInlongGroupId());
+        Assertions.assertEquals(0, delete);
+        Assertions.assertNotNull(select);
+    }
+
     @Test
     public void selectByPrimaryKey() {
         InlongGroupEntity entity = createGroupEntity();
@@ -51,6 +67,40 @@ public class InlongGroupEntityMapperTest extends DaoBaseTest 
{
         Assertions.assertEquals(entity.getInlongGroupId(), 
groupEntity.getInlongGroupId());
     }
 
+    @Test
+    public void selectByPrimaryKeyWithOtherTenant() {
+        InlongGroupEntity entity = createGroupEntity();
+        groupEntityMapper.insert(entity);
+        setOtherTenant(ANOTHER_TENANT);
+        InlongGroupEntity groupEntity = 
groupEntityMapper.selectByPrimaryKey(entity.getId());
+        Assertions.assertNull(groupEntity);
+    }
+
+    @Test
+    public void selectByCondition() {
+        InlongGroupEntity entity = createGroupEntity();
+        groupEntityMapper.insert(entity);
+        InlongGroupPageRequest request = new InlongGroupPageRequest();
+        List<String> groups = new LinkedList<>();
+        request.setGroupIdList(groups);
+        groups.add(entity.getInlongGroupId());
+        List<InlongGroupEntity> entities = 
groupEntityMapper.selectByCondition(request);
+        Assertions.assertEquals(1, entities.size());
+    }
+
+    @Test
+    public void selectByConditionWithOtherTenant() {
+        InlongGroupEntity entity = createGroupEntity();
+        groupEntityMapper.insert(entity);
+        setOtherTenant(ANOTHER_TENANT);
+        InlongGroupPageRequest request = new InlongGroupPageRequest();
+        List<String> groups = new LinkedList<>();
+        request.setGroupIdList(groups);
+        groups.add(entity.getInlongGroupId());
+        List<InlongGroupEntity> entities = 
groupEntityMapper.selectByCondition(request);
+        Assertions.assertEquals(0, entities.size());
+    }
+
     private InlongGroupEntity createGroupEntity() {
         InlongGroupEntity entity = new InlongGroupEntity();
         entity.setInlongGroupId("test_group");
diff --git 
a/inlong-manager/manager-service/src/test/java/org/apache/inlong/manager/service/ServiceBaseTest.java
 
b/inlong-manager/manager-service/src/test/java/org/apache/inlong/manager/service/ServiceBaseTest.java
index 73fdce485c..4aae873949 100644
--- 
a/inlong-manager/manager-service/src/test/java/org/apache/inlong/manager/service/ServiceBaseTest.java
+++ 
b/inlong-manager/manager-service/src/test/java/org/apache/inlong/manager/service/ServiceBaseTest.java
@@ -26,10 +26,13 @@ import 
org.apache.inlong.manager.pojo.group.pulsar.InlongPulsarInfo;
 import org.apache.inlong.manager.pojo.stream.InlongStreamInfo;
 import org.apache.inlong.manager.pojo.stream.InlongStreamRequest;
 import org.apache.inlong.manager.pojo.stream.StreamField;
+import org.apache.inlong.manager.pojo.user.LoginUserUtils;
+import org.apache.inlong.manager.pojo.user.UserInfo;
 import org.apache.inlong.manager.service.group.InlongGroupService;
 import org.apache.inlong.manager.service.stream.InlongStreamService;
 import org.apache.inlong.manager.test.BaseTest;
 
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -50,6 +53,7 @@ public class ServiceBaseTest extends BaseTest {
     public static final String GLOBAL_GROUP_ID = "global_group";
     public static final String GLOBAL_STREAM_ID = "global_stream";
     public static final String GLOBAL_OPERATOR = "admin";
+    public static final String PUBLIC_TENANT = "public";
     public static final String GLOBAL_CLUSTER_NAME = "global_cluster";
     private static final Logger LOGGER = 
LoggerFactory.getLogger(ServiceBaseTest.class);
 
@@ -58,6 +62,14 @@ public class ServiceBaseTest extends BaseTest {
     @Autowired
     protected InlongStreamService streamService;
 
+    @BeforeEach
+    public void login() {
+        UserInfo userInfo = new UserInfo();
+        userInfo.setTenant(PUBLIC_TENANT);
+        userInfo.setName(GLOBAL_OPERATOR);
+        LoginUserUtils.setUserLoginInfo(userInfo);
+    }
+
     @Test
     public void test() {
         LOGGER.info("The test class cannot be empty, otherwise 'No runnable 
methods exception' will be reported");
diff --git 
a/inlong-manager/manager-test/src/main/resources/h2/apache_inlong_manager.sql 
b/inlong-manager/manager-test/src/main/resources/h2/apache_inlong_manager.sql
index 6a1a7f65c6..36b99f35d3 100644
--- 
a/inlong-manager/manager-test/src/main/resources/h2/apache_inlong_manager.sql
+++ 
b/inlong-manager/manager-test/src/main/resources/h2/apache_inlong_manager.sql
@@ -27,6 +27,7 @@ CREATE TABLE IF NOT EXISTS `inlong_group`
     `inlong_group_id`        varchar(256) NOT NULL COMMENT 'Inlong group id, 
filled in by the user, undeleted ones cannot be repeated',
     `name`                   varchar(128)          DEFAULT '' COMMENT 'Inlong 
group name, English, Chinese, numbers, etc',
     `description`            varchar(256)          DEFAULT '' COMMENT 
'Description of inlong group',
+    `tenant`                 varchar(256)          DEFAULT 'public' COMMENT 
'Inlong tenant of group',
     `mq_type`                varchar(20)           DEFAULT 'TUBEMQ' COMMENT 
'The message queue type, high throughput: TUBEMQ, high consistency: PULSAR',
     `mq_resource`            varchar(128) NOT NULL COMMENT 'MQ resource, for 
TubeMQ, its Topic, for Pulsar, its Namespace',
     `daily_records`          int(11)               DEFAULT '10' COMMENT 
'Number of access records per day, unit: 10,000 records per day',
@@ -792,7 +793,8 @@ CREATE TABLE IF NOT EXISTS `inlong_tenant`
 -- Insert inlong_tenant item
 -- ----------------------------
 INSERT INTO `inlong_tenant`(`name`, `description`, `creator`, `modifier`)
-VALUES ('public', 'Default tenant', 'admin', 'admin');
+VALUES ('public', 'Default tenant', 'admin', 'admin'),
+       ('another', 'Another tenant', 'admin', 'admin');
 
 -- ----------------------------
 -- Table structure for audit_base
diff --git a/inlong-manager/manager-web/sql/apache_inlong_manager.sql 
b/inlong-manager/manager-web/sql/apache_inlong_manager.sql
index 5f4dad52d9..148cf6a052 100644
--- a/inlong-manager/manager-web/sql/apache_inlong_manager.sql
+++ b/inlong-manager/manager-web/sql/apache_inlong_manager.sql
@@ -33,6 +33,7 @@ CREATE TABLE IF NOT EXISTS `inlong_group`
     `inlong_group_id`        varchar(256) NOT NULL COMMENT 'Inlong group id, 
filled in by the user, undeleted ones cannot be repeated',
     `name`                   varchar(128)          DEFAULT '' COMMENT 'Inlong 
group name, English, Chinese, numbers, etc',
     `description`            varchar(256)          DEFAULT '' COMMENT 
'Description of inlong group',
+    `tenant`                 varchar(256)          DEFAULT 'public' COMMENT 
'Inlong tenant of group',
     `mq_type`                varchar(20)           DEFAULT 'TUBEMQ' COMMENT 
'The message queue type, high throughput: TUBEMQ, high consistency: PULSAR',
     `mq_resource`            varchar(128) NOT NULL COMMENT 'MQ resource, for 
TubeMQ, its Topic, for Pulsar, its Namespace',
     `daily_records`          int(11)               DEFAULT '10' COMMENT 
'Number of access records per day, unit: 10,000 records per day',
@@ -58,6 +59,7 @@ CREATE TABLE IF NOT EXISTS `inlong_group`
     PRIMARY KEY (`id`),
     UNIQUE KEY `unique_inlong_group` (`inlong_group_id`, `is_deleted`),
     INDEX `group_status_deleted_index` (`status`, `is_deleted`),
+    INDEX `tenant_index` (`tenant`, `is_deleted`),
     INDEX `group_modify_time_index` (`modify_time`),
     INDEX `group_cluster_tag_index` (`inlong_cluster_tag`)
 ) ENGINE = InnoDB
diff --git a/inlong-manager/manager-web/sql/changes-1.8.0.sql 
b/inlong-manager/manager-web/sql/changes-1.8.0.sql
index 83d080e14d..d27bc2de19 100644
--- a/inlong-manager/manager-web/sql/changes-1.8.0.sql
+++ b/inlong-manager/manager-web/sql/changes-1.8.0.sql
@@ -80,4 +80,9 @@ CREATE INDEX index_tenant
 UPDATE inlong_group SET ext_params = replace(ext_params, '"tenant"', 
'"pulsarTenant"');
 UPDATE inlong_cluster SET ext_params = replace(ext_params, '"tenant"', 
'"pulsarTenant"');
 
-ALTER TABLE `inlong_stream` MODIFY COLUMN `name` varchar(256) DEFAULT NULL 
COMMENT 'The name of the inlong stream page display, can be Chinese';
\ No newline at end of file
+ALTER TABLE `inlong_stream` MODIFY COLUMN `name` varchar(256) DEFAULT NULL 
COMMENT 'The name of the inlong stream page display, can be Chinese';
+
+ALTER TABLE `inlong_group`
+    ADD tenant VARCHAR(256) DEFAULT 'public' NOT NULL comment 'Inlong tenant 
of group';
+CREATE INDEX tenant_index
+    ON inlong_group (`tenant`, `is_deleted`);
\ No newline at end of file
diff --git 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/controller/InlongGroupController.java
 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/controller/InlongGroupController.java
index edf6ed6a33..6fc7319a62 100644
--- 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/controller/InlongGroupController.java
+++ 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/controller/InlongGroupController.java
@@ -32,6 +32,7 @@ import 
org.apache.inlong.manager.pojo.group.InlongGroupResetRequest;
 import org.apache.inlong.manager.pojo.group.InlongGroupTopicInfo;
 import org.apache.inlong.manager.pojo.group.InlongGroupTopicRequest;
 import org.apache.inlong.manager.pojo.user.LoginUserUtils;
+import org.apache.inlong.manager.pojo.user.UserRoleCode;
 import org.apache.inlong.manager.pojo.workflow.WorkflowResult;
 import org.apache.inlong.manager.service.group.InlongGroupProcessService;
 import org.apache.inlong.manager.service.group.InlongGroupService;
@@ -40,6 +41,7 @@ import 
org.apache.inlong.manager.service.operationlog.OperationLog;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -70,6 +72,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/save", method = RequestMethod.POST)
     @OperationLog(operation = OperationType.CREATE)
     @ApiOperation(value = "Save inlong group")
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<String> save(@Validated(SaveValidation.class) @RequestBody 
InlongGroupRequest groupRequest) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return Response.success(groupService.save(groupRequest, operator));
@@ -78,6 +81,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/exist/{groupId}", method = 
RequestMethod.GET)
     @ApiOperation(value = "Is the inlong group id exists")
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class, required = true)
+    @RequiresRoles(value = UserRoleCode.TENANT_OPERATOR)
     public Response<Boolean> exist(@PathVariable String groupId) {
         return Response.success(groupService.exist(groupId));
     }
@@ -85,6 +89,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/get/{groupId}", method = RequestMethod.GET)
     @ApiOperation(value = "Get inlong group")
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class, required = true)
+    @RequiresRoles(value = UserRoleCode.TENANT_OPERATOR)
     public Response<InlongGroupInfo> get(@PathVariable String groupId) {
         return Response.success(groupService.get(groupId));
     }
@@ -92,6 +97,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/countByStatus", method = RequestMethod.GET)
     @ApiOperation(value = "Count inlong group status for current user")
     @ApiImplicitParam(name = "inlongGroupMode", dataTypeClass = Integer.class, 
defaultValue = "0")
+    @RequiresRoles(value = UserRoleCode.TENANT_OPERATOR)
     public Response<InlongGroupCountResponse> countGroupByUser(
             @RequestParam(required = false, defaultValue = "0") Integer 
inlongGroupMode) {
         String operator = LoginUserUtils.getLoginUser().getName();
@@ -100,24 +106,28 @@ public class InlongGroupController {
 
     @GetMapping(value = "/group/getTopic/{groupId}")
     @ApiOperation(value = "Get topic info")
+    @RequiresRoles(value = UserRoleCode.TENANT_OPERATOR)
     public Response<InlongGroupTopicInfo> getTopic(@PathVariable String 
groupId) {
         return Response.success(groupService.getTopic(groupId));
     }
 
     @PostMapping(value = "/group/listTopics")
     @ApiOperation(value = "Get topic infos")
+    @RequiresRoles(value = UserRoleCode.TENANT_OPERATOR)
     public Response<List<InlongGroupTopicInfo>> listTopics(@RequestBody 
InlongGroupTopicRequest request) {
         return Response.success(groupService.listTopics(request));
     }
 
     @GetMapping(value = "/group/getBackupTopic/{groupId}")
     @ApiOperation(value = "Get backup topic info")
+    @RequiresRoles(value = UserRoleCode.TENANT_OPERATOR)
     public Response<InlongGroupTopicInfo> getBackupTopic(@PathVariable String 
groupId) {
         return Response.success(groupService.getBackupTopic(groupId));
     }
 
     @RequestMapping(value = "/group/list", method = RequestMethod.POST)
     @ApiOperation(value = "List inlong groups by paginating")
+    @RequiresRoles(value = UserRoleCode.TENANT_OPERATOR)
     public Response<PageResult<InlongGroupBriefInfo>> listBrief(@RequestBody 
InlongGroupPageRequest request) {
         request.setCurrentUser(LoginUserUtils.getLoginUser().getName());
         request.setIsAdminRole(
@@ -128,6 +138,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/update", method = RequestMethod.POST)
     @OperationLog(operation = OperationType.UPDATE)
     @ApiOperation(value = "Update inlong group")
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<String> update(@Validated(UpdateValidation.class) 
@RequestBody InlongGroupRequest groupRequest) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return Response.success(groupService.update(groupRequest, operator));
@@ -137,6 +148,7 @@ public class InlongGroupController {
     @ApiOperation(value = "Delete inlong group info")
     @OperationLog(operation = OperationType.DELETE)
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class, required = true)
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<Boolean> delete(@PathVariable String groupId) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return Response.success(groupProcessOperation.deleteProcess(groupId, 
operator));
@@ -146,6 +158,7 @@ public class InlongGroupController {
     @ApiOperation(value = "Delete inlong group info")
     @OperationLog(operation = OperationType.DELETE)
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class, required = true)
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<String> deleteAsync(@PathVariable String groupId) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return 
Response.success(groupProcessOperation.deleteProcessAsync(groupId, operator));
@@ -154,6 +167,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/startProcess/{groupId}", method = 
RequestMethod.POST)
     @ApiOperation(value = "Start inlong approval process")
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class)
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<WorkflowResult> startProcess(@PathVariable String groupId) 
{
         String operator = LoginUserUtils.getLoginUser().getName();
         return Response.success(groupProcessOperation.startProcess(groupId, 
operator));
@@ -162,6 +176,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/suspendProcess/{groupId}", method = 
RequestMethod.POST)
     @ApiOperation(value = "Suspend inlong group process")
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class)
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<WorkflowResult> suspendProcess(@PathVariable String 
groupId) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return Response.success(groupProcessOperation.suspendProcess(groupId, 
operator));
@@ -170,6 +185,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/restartProcess/{groupId}", method = 
RequestMethod.POST)
     @ApiOperation(value = "Restart inlong group process")
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class)
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<WorkflowResult> restartProcess(@PathVariable String 
groupId) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return Response.success(groupProcessOperation.restartProcess(groupId, 
operator));
@@ -178,6 +194,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/suspendProcessAsync/{groupId}", method = 
RequestMethod.POST)
     @ApiOperation(value = "Suspend inlong group process")
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class)
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<String> suspendProcessAsync(@PathVariable String groupId) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return 
Response.success(groupProcessOperation.suspendProcessAsync(groupId, operator));
@@ -186,6 +203,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/restartProcessAsync/{groupId}", method = 
RequestMethod.POST)
     @ApiOperation(value = "Restart inlong group process")
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class)
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<String> restartProcessAsync(@PathVariable String groupId) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return 
Response.success(groupProcessOperation.restartProcessAsync(groupId, operator));
@@ -193,6 +211,7 @@ public class InlongGroupController {
 
     @PostMapping(value = "/group/reset")
     @ApiOperation(value = "Reset group status when group is in 
CONFIG_ING|SUSPENDING|RESTARTING|DELETING")
+    @RequiresRoles(value = UserRoleCode.TENANT_ADMIN)
     public Response<Boolean> reset(@RequestBody @Validated 
InlongGroupResetRequest request) {
         String operator = LoginUserUtils.getLoginUser().getName();
         return 
Response.success(groupProcessOperation.resetGroupStatus(request, operator));
@@ -201,6 +220,7 @@ public class InlongGroupController {
     @RequestMapping(value = "/group/detail/{groupId}", method = 
RequestMethod.GET)
     @ApiOperation(value = "get group detail")
     @ApiImplicitParam(name = "groupId", value = "Inlong group id", 
dataTypeClass = String.class, required = true)
+    @RequiresRoles(value = UserRoleCode.TENANT_OPERATOR)
     public Response<Map<String, Object>> detail(@PathVariable String groupId) {
         return Response.success(groupService.detail(groupId));
     }


Reply via email to