From bc1a05d16cfbc3b537620840e1e2b4583779f70e Mon Sep 17 00:00:00 2001 From: Crazylychee <110229037+Crazylychee@users.noreply.github.com> Date: Mon, 16 Jun 2025 14:04:53 +0800 Subject: [PATCH] [GSOC][RIP-78][ISSUES#308] Add part of refactored backend files (#313) --- pom.xml | 50 +- .../dashboard/admin/MQAdminExtCallback.java | 25 + .../dashboard/admin/MQAdminFactory.java | 3 +- .../admin/UserMQAdminPoolManager.java | 132 +++++ ...serSpecificMQAdminPooledObjectFactory.java | 112 ++++ .../dashboard/aspect/admin/MQAdminAspect.java | 94 ++- .../config/AuthWebMVCConfigurerAdapter.java | 55 +- .../config/CollectExecutorConfig.java | 9 +- .../dashboard/config/RMQConfigure.java | 97 +--- .../dashboard/controller/AclController.java | 139 ++--- .../controller/ClusterController.java | 3 +- .../controller/ConsumerController.java | 4 +- .../controller/DashboardController.java | 3 +- .../controller/DlqMessageController.java | 11 +- .../dashboard/controller/LoginController.java | 22 +- .../controller/MessageController.java | 12 +- .../controller/MessageTraceController.java | 9 +- .../controller/MonitorController.java | 2 +- .../controller/NamesvrController.java | 2 +- .../dashboard/controller/OpsController.java | 2 +- .../controller/ProducerController.java | 5 +- .../dashboard/controller/ProxyController.java | 4 +- .../dashboard/controller/TestController.java | 7 +- .../dashboard/controller/TopicController.java | 11 +- .../filter/HttpBasicAuthorizedFilter.java | 22 +- .../interceptor/AuthInterceptor.java | 14 +- .../dashboard/model/ConnectionInfo.java | 5 +- .../model/ConsumerGroupRollBackStat.java | 2 +- .../dashboard/model/DlqMessageExcelModel.java | 5 +- .../rocketmq/dashboard/model/Entry.java | 33 ++ .../rocketmq/dashboard/model/MessageView.java | 2 +- .../rocketmq/dashboard/model/Policy.java | 30 + .../dashboard/model/PolicyRequest.java | 31 + .../dashboard/model/QueueStatInfo.java | 2 +- .../dashboard/model/request/AclRequest.java | 3 +- .../model/request/UserCreateRequest.java | 28 + .../model/request/UserInfoParam.java | 28 + .../model/request/UserUpdateRequest.java | 28 + .../permisssion/PermissionAspect.java | 19 +- .../service/AbstractCommonService.java | 7 +- .../dashboard/service/AclService.java | 32 +- .../dashboard/service/ClusterInfoService.java | 6 +- .../dashboard/service/ConsumerService.java | 6 +- .../service/DashboardCollectService.java | 1 + .../dashboard/service/DlqMessageService.java | 5 +- .../dashboard/service/LoginService.java | 5 +- .../dashboard/service/MessageService.java | 6 +- .../service/MessageTraceService.java | 3 +- .../dashboard/service/MonitorService.java | 3 +- .../dashboard/service/OpsService.java | 3 +- .../dashboard/service/TopicService.java | 4 +- .../dashboard/service/UserService.java | 1 + .../service/client/MQAdminExtImpl.java | 256 ++++++--- .../service/client/MQAdminInstance.java | 63 ++- .../service/client/ProxyAdminImpl.java | 11 +- .../service/impl/AbstractFileStore.java | 7 +- .../service/impl/AclServiceImpl.java | 535 ++++++++---------- .../service/impl/ClusterServiceImpl.java | 25 +- .../service/impl/ConsumerServiceImpl.java | 78 ++- .../impl/DashboardCollectServiceImpl.java | 13 +- .../service/impl/DashboardServiceImpl.java | 9 +- .../service/impl/DlqMessageServiceImpl.java | 15 +- .../service/impl/LoginServiceImpl.java | 21 +- .../service/impl/MessageServiceImpl.java | 22 +- .../service/impl/MessageTraceServiceImpl.java | 17 +- .../service/impl/MonitorServiceImpl.java | 13 +- .../service/impl/OpsServiceImpl.java | 7 +- .../service/impl/PermissionServiceImpl.java | 13 +- .../service/impl/ProducerServiceImpl.java | 4 +- .../service/impl/ProxyServiceImpl.java | 2 +- .../service/impl/TopicServiceImpl.java | 10 +- .../service/impl/UserServiceImpl.java | 130 ++--- .../service/provider/UserInfoProvider.java | 24 + .../provider/UserInfoProviderImpl.java | 68 +++ .../support/AutoCloseConsumerWrapper.java | 5 +- .../support/GlobalExceptionHandler.java | 4 +- .../GlobalRestfulResponseBodyAdvice.java | 3 +- .../dashboard/task/CollectTaskRunnble.java | 11 +- .../dashboard/task/DashboardCollectTask.java | 33 +- .../rocketmq/dashboard/task/MonitorTask.java | 5 +- .../rocketmq/dashboard/util/ExcelUtil.java | 5 +- .../rocketmq/dashboard/util/JsonUtil.java | 5 +- .../dashboard/util/MsgTraceDecodeUtil.java | 6 +- .../dashboard/util/UserInfoContext.java | 47 ++ .../rocketmq/dashboard/util/WebUtil.java | 8 +- src/main/resources/application.yml | 4 +- 86 files changed, 1624 insertions(+), 1002 deletions(-) create mode 100644 src/main/java/org/apache/rocketmq/dashboard/admin/MQAdminExtCallback.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/admin/UserMQAdminPoolManager.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/admin/UserSpecificMQAdminPooledObjectFactory.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/model/Entry.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/model/Policy.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/model/PolicyRequest.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/model/request/UserCreateRequest.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/model/request/UserInfoParam.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/model/request/UserUpdateRequest.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/service/provider/UserInfoProvider.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/service/provider/UserInfoProviderImpl.java create mode 100644 src/main/java/org/apache/rocketmq/dashboard/util/UserInfoContext.java diff --git a/pom.xml b/pom.xml index 0735a1a..0fb6540 100644 --- a/pom.xml +++ b/pom.xml @@ -82,29 +82,28 @@ UTF-8 - 1.8 - 1.8 - + 17 + 17 29.0-jre 2.1 2.6 2.4 1.2 3.2.2 - 5.1.0 + 5.3.3 2.19.1 1.9.6 1.18.22 ${basedir}/../.. apacherocketmq - 2.6.0 + 3.4.5 3.3.3 - 2.3.1 + 4.0.0 2.4.3 2.2.10 4.2 4.12 - 1.32 + 2.0 2.2.2 0.9.6 1.68 @@ -115,6 +114,12 @@ org.springframework.boot spring-boot-starter-web ${spring.boot.version} + + + javax.annotation + javax.annotation-api + + org.springframework.boot @@ -235,9 +240,9 @@ ${bcpkix-jdk15on.version} - javax.xml.bind - jaxb-api - ${jaxb-api.version} + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind-api.version} org.projectlombok @@ -282,7 +287,7 @@ maven-compiler-plugin - 3.5.1 + 3.11.0 ${maven.compiler.source} ${maven.compiler.target} @@ -296,19 +301,22 @@ ${lombok.version} + + -parameters + org.springframework.boot spring-boot-maven-plugin ${spring.boot.version} - - - - repackage - - - + + + + + + + @@ -384,9 +392,9 @@ 4.3.0 - javax.xml.bind - jaxb-api - ${jaxb-api.version} + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind-api.version} diff --git a/src/main/java/org/apache/rocketmq/dashboard/admin/MQAdminExtCallback.java b/src/main/java/org/apache/rocketmq/dashboard/admin/MQAdminExtCallback.java new file mode 100644 index 0000000..324b82d --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/admin/MQAdminExtCallback.java @@ -0,0 +1,25 @@ +/* + * 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.rocketmq.dashboard.admin; + +import org.apache.rocketmq.tools.admin.MQAdminExt; + +@FunctionalInterface +public interface MQAdminExtCallback { + T doInMQAdminExt(MQAdminExt mqAdminExt) throws Exception; +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/admin/MQAdminFactory.java b/src/main/java/org/apache/rocketmq/dashboard/admin/MQAdminFactory.java index e5e90c7..48dfe1b 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/admin/MQAdminFactory.java +++ b/src/main/java/org/apache/rocketmq/dashboard/admin/MQAdminFactory.java @@ -16,7 +16,6 @@ */ package org.apache.rocketmq.dashboard.admin; -import java.util.concurrent.atomic.AtomicLong; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.acl.common.AclClientRPCHook; @@ -26,6 +25,8 @@ import org.apache.rocketmq.remoting.RPCHook; import org.apache.rocketmq.tools.admin.DefaultMQAdminExt; import org.apache.rocketmq.tools.admin.MQAdminExt; +import java.util.concurrent.atomic.AtomicLong; + @Slf4j public class MQAdminFactory { private RMQConfigure rmqConfigure; diff --git a/src/main/java/org/apache/rocketmq/dashboard/admin/UserMQAdminPoolManager.java b/src/main/java/org/apache/rocketmq/dashboard/admin/UserMQAdminPoolManager.java new file mode 100644 index 0000000..31b9cab --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/admin/UserMQAdminPoolManager.java @@ -0,0 +1,132 @@ +/* + * 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.rocketmq.dashboard.admin; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.apache.rocketmq.client.ClientConfig; +import org.apache.rocketmq.dashboard.config.RMQConfigure; +import org.apache.rocketmq.tools.admin.MQAdminExt; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PreDestroy; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +@Component +@Slf4j +public class UserMQAdminPoolManager { + + + private final ConcurrentMap> userPools = new ConcurrentHashMap<>(); + + private final ClientConfig baseClientConfig; + + @Autowired + public UserMQAdminPoolManager(RMQConfigure rmqConfigure) { + this.baseClientConfig = new ClientConfig(); + this.baseClientConfig.setNamesrvAddr(rmqConfigure.getNamesrvAddr()); + this.baseClientConfig.setClientCallbackExecutorThreads(rmqConfigure.getClientCallbackExecutorThreads()); + this.baseClientConfig.setVipChannelEnabled(Boolean.parseBoolean(rmqConfigure.getIsVIPChannel())); + this.baseClientConfig.setUseTLS(rmqConfigure.isUseTLS()); + log.info("UserMQAdminPoolManager initialized with baseClientConfig for NameServer: {}", rmqConfigure.getNamesrvAddr()); + } + + + public MQAdminExt borrowMQAdminExt(String userAk, String userSk) throws Exception { + GenericObjectPool userPool = userPools.get(userAk); + + if (userPool == null) { + log.info("Creating new MQAdminExt pool for user: {}", userAk); + GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); + poolConfig.setMaxTotal(1); + poolConfig.setMaxIdle(1); + poolConfig.setMinIdle(0); + poolConfig.setTestWhileIdle(true); + poolConfig.setTimeBetweenEvictionRunsMillis(20000); + poolConfig.setMaxWaitMillis(10000); + + UserSpecificMQAdminPooledObjectFactory factory = + new UserSpecificMQAdminPooledObjectFactory(baseClientConfig, userAk, userSk); + + GenericObjectPool newUserPool = new GenericObjectPool<>(factory, poolConfig); + + GenericObjectPool existingPool = userPools.putIfAbsent(userAk, newUserPool); + if (existingPool != null) { + log.warn("Another thread concurrently created MQAdminExt pool for user {}. Shutting down redundant pool.", userAk); + newUserPool.close(); + userPool = existingPool; + } else { + userPool = newUserPool; + log.info("Successfully created and registered MQAdminExt pool for user: {}", userAk); + } + } + + return userPool.borrowObject(); + } + + public void returnMQAdminExt(String userAk, MQAdminExt mqAdminExt) { + GenericObjectPool userPool = userPools.get(userAk); + if (userPool != null) { + try { + userPool.returnObject(mqAdminExt); + log.debug("Returned MQAdminExt object ({}) to pool for user: {}", mqAdminExt, userAk); + } catch (Exception e) { + log.error("Failed to return MQAdminExt object ({}) for user {}: {}", mqAdminExt, userAk, e.getMessage(), e); + if (mqAdminExt != null) { + try { + mqAdminExt.shutdown(); + } catch (Exception se) { + log.warn("Error shutting down MQAdminExt after failed return: {}", se.getMessage()); + } + } + } + } else { + log.warn("Attempted to return MQAdminExt for non-existent user pool: {}. Shutting down the object directly.", userAk); + if (mqAdminExt != null) { + try { + mqAdminExt.shutdown(); + } catch (Exception se) { + log.warn("Error shutting down MQAdminExt for non-existent pool: {}", se.getMessage()); + } + } + } + } + + public void shutdownUserPool(String userAk) { + GenericObjectPool userPool = userPools.remove(userAk); + if (userPool != null) { + userPool.close(); + log.info("Shutdown and removed MQAdminExt pool for user: {}", userAk); + } else { + log.warn("Attempted to shut down non-existent user pool: {}", userAk); + } + } + + @PreDestroy + public void shutdownAllPools() { + log.info("Shutting down all MQAdminExt user pools..."); + userPools.forEach((userAk, pool) -> { + pool.close(); + log.info("Shutdown MQAdminExt pool for user: {}", userAk); + }); + userPools.clear(); + log.info("All MQAdminExt user pools have been shut down."); + } +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/admin/UserSpecificMQAdminPooledObjectFactory.java b/src/main/java/org/apache/rocketmq/dashboard/admin/UserSpecificMQAdminPooledObjectFactory.java new file mode 100644 index 0000000..95530ad --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/admin/UserSpecificMQAdminPooledObjectFactory.java @@ -0,0 +1,112 @@ +/* + * 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.rocketmq.dashboard.admin; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.PooledObjectFactory; +import org.apache.commons.pool2.impl.DefaultPooledObject; +import org.apache.rocketmq.acl.common.AclClientRPCHook; +import org.apache.rocketmq.acl.common.SessionCredentials; +import org.apache.rocketmq.client.ClientConfig; +import org.apache.rocketmq.remoting.RPCHook; +import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; +import org.apache.rocketmq.tools.admin.DefaultMQAdminExt; +import org.apache.rocketmq.tools.admin.MQAdminExt; + +import java.util.UUID; +import java.util.concurrent.atomic.AtomicLong; + +@Slf4j +public class UserSpecificMQAdminPooledObjectFactory implements PooledObjectFactory { + + private final ClientConfig userSpecificClientConfig; + private final RPCHook rpcHook; + private final String userAk; + private final AtomicLong instanceCreationCounter = new AtomicLong(0); + + public UserSpecificMQAdminPooledObjectFactory(ClientConfig baseClientConfig, String userAk, String userSk) { + this.userSpecificClientConfig = baseClientConfig.cloneClientConfig(); + this.userSpecificClientConfig.setInstanceName("MQ_ADMIN_INSTANCE_" + userAk + "_" + UUID.randomUUID()); + + if (StringUtils.isNotEmpty(userAk) && StringUtils.isNotEmpty(userSk)) { + this.rpcHook = new AclClientRPCHook(new SessionCredentials(userAk, userSk)); + } else { + this.rpcHook = null; + } + this.userAk = userAk; + + log.info("UserSpecificMQAdminPooledObjectFactory initialized for user: {}", userAk); + log.debug("Factory ClientConfig for user {}: {}", userAk, userSpecificClientConfig); + } + + @Override + public PooledObject makeObject() throws Exception { + DefaultMQAdminExt mqAdminExt = new DefaultMQAdminExt(rpcHook); + + mqAdminExt.setAdminExtGroup("MQ_ADMIN_GROUP_FOR_" + userAk + "_" + instanceCreationCounter.getAndIncrement()); + + mqAdminExt.start(); + log.info("Created new MQAdminExt instance ({}) for user {}", mqAdminExt, userAk); + return new DefaultPooledObject<>(mqAdminExt); + } + + @Override + public void destroyObject(PooledObject p) { + MQAdminExt mqAdmin = p.getObject(); + if (mqAdmin != null) { + try { + mqAdmin.shutdown(); + } catch (Exception e) { + log.warn("Failed to shut down MQAdminExt object ({}) for user {}: {}", p.getObject(), userAk, e.getMessage(), e); + } + } + log.info("Destroyed MQAdminExt object ({}) for user {}", p.getObject(), userAk); + } + + + @Override + public boolean validateObject(PooledObject p) { + MQAdminExt mqAdmin = p.getObject(); + if (mqAdmin == null) { + log.warn("MQAdminExt object is null or not started for user {}: {}", userAk, mqAdmin); + return false; + } + try { + ClusterInfo clusterInfo = mqAdmin.examineBrokerClusterInfo(); + boolean isValid = clusterInfo != null && !clusterInfo.getBrokerAddrTable().isEmpty(); + if (!isValid) { + log.warn("Validation failed for MQAdminExt object for user {}: ClusterInfo is invalid or empty. ClusterInfo = {}", userAk, clusterInfo); + } + return isValid; + } catch (Exception e) { + log.warn("Validation error for MQAdminExt object for user {}: {}", userAk, e.getMessage(), e); + return false; + } + } + + @Override + public void activateObject(PooledObject p) { + log.debug("Activating MQAdminExt object ({}) for user {}", p.getObject(), userAk); + } + + @Override + public void passivateObject(PooledObject p) { + log.debug("Passivating MQAdminExt object ({}) for user {}", p.getObject(), userAk); + } +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/aspect/admin/MQAdminAspect.java b/src/main/java/org/apache/rocketmq/dashboard/aspect/admin/MQAdminAspect.java index 56f37f6..8539c4a 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/aspect/admin/MQAdminAspect.java +++ b/src/main/java/org/apache/rocketmq/dashboard/aspect/admin/MQAdminAspect.java @@ -18,42 +18,114 @@ package org.apache.rocketmq.dashboard.aspect.admin; import lombok.extern.slf4j.Slf4j; import org.apache.commons.pool2.impl.GenericObjectPool; +import org.apache.rocketmq.dashboard.admin.UserMQAdminPoolManager; +import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.service.client.MQAdminInstance; +import org.apache.rocketmq.dashboard.util.UserInfoContext; +import org.apache.rocketmq.dashboard.util.WebUtil; +import org.apache.rocketmq.remoting.protocol.body.UserInfo; import org.apache.rocketmq.tools.admin.MQAdminExt; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; +import org.springframework.stereotype.Component; + +import java.util.HashSet; +import java.util.Set; @Aspect -@Service +@Component @Slf4j public class MQAdminAspect { + @Autowired + private UserMQAdminPoolManager userMQAdminPoolManager; + @Autowired private GenericObjectPool mqAdminExtPool; - public MQAdminAspect() { + @Autowired + private RMQConfigure rmqConfigure; + + private static final Set METHODS_TO_CHECK = new HashSet<>(); + + static { + METHODS_TO_CHECK.add("getUser"); + METHODS_TO_CHECK.add("examineBrokerClusterInfo"); + METHODS_TO_CHECK.add("examineConsumerConnectionInfo"); + METHODS_TO_CHECK.add("examineConsumeStats"); + METHODS_TO_CHECK.add("examineProducerConnectionInfo"); } + // Pointcut remains the same, targeting methods in MQAdminExtImpl @Pointcut("execution(* org.apache.rocketmq.dashboard.service.client.MQAdminExtImpl..*(..))") public void mQAdminMethodPointCut() { - } - @Around(value = "mQAdminMethodPointCut()") + @Pointcut("execution(* org.apache.rocketmq.dashboard.service.client.ProxyAdminImpl..*(..))") + public void proxyAdminMethodPointCut() { + } + + @Around(value = "mQAdminMethodPointCut()||proxyAdminMethodPointCut()") public Object aroundMQAdminMethod(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); - Object obj = null; + MQAdminExt mqAdminExt = null; // The MQAdminExt instance borrowed from the pool + UserInfo currentUserInfo = null; // The user initiating the operation + String methodName = joinPoint.getSignature().getName(); + try { - MQAdminInstance.createMQAdmin(mqAdminExtPool); - obj = joinPoint.proceed(); + if (isPoolConfigIsolatedByUser(rmqConfigure.isLoginRequired(), methodName)) { + currentUserInfo = (UserInfo) UserInfoContext.get(WebUtil.USER_NAME); + // 2. Borrow the user-specific MQAdminExt instance. + // currentUser.getName() is assumed to be the AccessKey, and currentUser.getPassword() is SecretKey. + mqAdminExt = userMQAdminPoolManager.borrowMQAdminExt(currentUserInfo.getUsername(), currentUserInfo.getPassword()); + + // 3. Set the borrowed MQAdminExt instance into the ThreadLocal for MQAdminInstance. + // This makes it available to MQAdminExtImpl methods. + MQAdminInstance.setCurrentMQAdminExt(mqAdminExt); + log.debug("MQAdminExt borrowed for user {} and set in ThreadLocal.", currentUserInfo.getUsername()); + } else { + mqAdminExt = mqAdminExtPool.borrowObject(); // Fallback to a default MQAdminExt if no user is provided + MQAdminInstance.setCurrentMQAdminExt(mqAdminExt); + } + // 4. Proceed with the original method execution. + return joinPoint.proceed(); + } finally { - MQAdminInstance.returnMQAdmin(mqAdminExtPool); - log.debug("op=look method={} cost={}", joinPoint.getSignature().getName(), System.currentTimeMillis() - start); + + if (currentUserInfo != null) { + if (mqAdminExt != null) { + userMQAdminPoolManager.returnMQAdminExt(currentUserInfo.getUsername(), mqAdminExt); + MQAdminInstance.clearCurrentMQAdminExt(); + log.debug("MQAdminExt returned for user {} and cleared from ThreadLocal.", currentUserInfo.getUsername()); + } + log.debug("Operation {} for user {} cost {}ms", + methodName, + currentUserInfo.getUsername(), + System.currentTimeMillis() - start); + } else { + if (mqAdminExt != null) { + mqAdminExtPool.returnObject(mqAdminExt); + MQAdminInstance.clearCurrentMQAdminExt(); + log.debug("MQAdminExt returned to default pool and cleared from ThreadLocal."); + } + log.debug("Operation {} cost {}ms", + methodName, + System.currentTimeMillis() - start); + } + } - return obj; } + + private boolean isPoolConfigIsolatedByUser(boolean loginRequired, String methodName) { + if (!loginRequired) { + return false; + } else { + return !METHODS_TO_CHECK.contains(methodName); + } + } + + } diff --git a/src/main/java/org/apache/rocketmq/dashboard/config/AuthWebMVCConfigurerAdapter.java b/src/main/java/org/apache/rocketmq/dashboard/config/AuthWebMVCConfigurerAdapter.java index 3a28d70..b902575 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/config/AuthWebMVCConfigurerAdapter.java +++ b/src/main/java/org/apache/rocketmq/dashboard/config/AuthWebMVCConfigurerAdapter.java @@ -17,6 +17,8 @@ package org.apache.rocketmq.dashboard.config; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; import org.apache.rocketmq.dashboard.interceptor.AuthInterceptor; import org.apache.rocketmq.dashboard.model.UserInfo; import org.apache.rocketmq.dashboard.util.WebUtil; @@ -29,16 +31,16 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.multipart.support.MissingServletRequestPartException; +import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; import java.util.List; @Configuration -public class AuthWebMVCConfigurerAdapter extends WebMvcConfigurerAdapter { +public class AuthWebMVCConfigurerAdapter implements WebMvcConfigurer { + @Autowired @Qualifier("authInterceptor") private AuthInterceptor authInterceptor; @@ -50,19 +52,19 @@ public class AuthWebMVCConfigurerAdapter extends WebMvcConfigurerAdapter { public void addInterceptors(InterceptorRegistry registry) { if (configure.isLoginRequired()) { registry.addInterceptor(authInterceptor).addPathPatterns( - "/cluster/**", - "/consumer/**", - "/dashboard/**", - "/dlqMessage/**", - "/message/**", - "/messageTrace/**", - "/monitor/**", - "/rocketmq/**", - "/ops/**", - "/producer/**", - "/test/**", - "/topic/**", - "/acl/**"); + "/cluster/**", + "/consumer/**", + "/dashboard/**", + "/dlqMessage/**", + "/message/**", + "/messageTrace/**", + "/monitor/**", + "/rocketmq/**", + "/ops/**", + "/producer/**", + "/test/**", + "/topic/**", + "/acl/**"); } } @@ -77,19 +79,30 @@ public class AuthWebMVCConfigurerAdapter extends WebMvcConfigurerAdapter { @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, - NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { + NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { UserInfo userInfo = (UserInfo) WebUtil.getValueFromSession((HttpServletRequest) nativeWebRequest.getNativeRequest(), - UserInfo.USER_INFO); + UserInfo.USER_INFO); if (userInfo != null) { return userInfo; } throw new MissingServletRequestPartException(UserInfo.USER_INFO); } }); - - super.addArgumentResolvers(argumentResolvers); //REVIEW ME } + @Override + public void addCorsMappings(CorsRegistry registry) { + + registry.addMapping("/**") + .allowedOriginPatterns("http://localhost:3003") + .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") + .maxAge(3600) + .allowCredentials(true) + .allowedHeaders("content-type", "Authorization", "X-Requested-With", "Origin", "Accept") + .exposedHeaders("authorization"); + } + + @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("*.htm").setViewName("forward:/app.html"); diff --git a/src/main/java/org/apache/rocketmq/dashboard/config/CollectExecutorConfig.java b/src/main/java/org/apache/rocketmq/dashboard/config/CollectExecutorConfig.java index 510ab8e..d72b62a 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/config/CollectExecutorConfig.java +++ b/src/main/java/org/apache/rocketmq/dashboard/config/CollectExecutorConfig.java @@ -17,16 +17,17 @@ package org.apache.rocketmq.dashboard.config; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "threadpool.config") diff --git a/src/main/java/org/apache/rocketmq/dashboard/config/RMQConfigure.java b/src/main/java/org/apache/rocketmq/dashboard/config/RMQConfigure.java index 5ce21ff..7bec055 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/config/RMQConfigure.java +++ b/src/main/java/org/apache/rocketmq/dashboard/config/RMQConfigure.java @@ -16,7 +16,8 @@ */ package org.apache.rocketmq.dashboard.config; -import java.util.ArrayList; +import lombok.Getter; +import lombok.Setter; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.common.MixAll; @@ -31,68 +32,64 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import java.io.File; +import java.util.ArrayList; import java.util.List; import static org.apache.rocketmq.client.ClientConfig.SEND_MESSAGE_WITH_VIP_CHANNEL_PROPERTY; +@Setter +@Getter @Configuration @ConfigurationProperties(prefix = "rocketmq.config") public class RMQConfigure { private Logger logger = LoggerFactory.getLogger(RMQConfigure.class); //use rocketmq.namesrv.addr first,if it is empty,than use system proerty or system env + @Getter private volatile String namesrvAddr = System.getProperty(MixAll.NAMESRV_ADDR_PROPERTY, System.getenv(MixAll.NAMESRV_ADDR_ENV)); + @Setter + @Getter private volatile String proxyAddr; + @Getter private volatile String isVIPChannel = System.getProperty(SEND_MESSAGE_WITH_VIP_CHANNEL_PROPERTY, "true"); + @Setter private String dataPath = "/tmp/rocketmq-console/data"; + @Getter private boolean enableDashBoardCollect; + @Setter + @Getter private boolean loginRequired = false; + private String accessKey; + @Setter + @Getter private String secretKey; + @Setter + @Getter private boolean useTLS = false; + @Setter + @Getter private Long timeoutMillis; + @Getter private List namesrvAddrs = new ArrayList<>(); + @Getter private List proxyAddrs = new ArrayList<>(); - public String getAccessKey() { - return accessKey; - } - - public void setAccessKey(String accessKey) { - this.accessKey = accessKey; - } - - public String getSecretKey() { - return secretKey; - } - - public void setSecretKey(String secretKey) { - this.secretKey = secretKey; - } - - public String getNamesrvAddr() { - return namesrvAddr; - } - - public List getNamesrvAddrs() { - return namesrvAddrs; - } - - public List getProxyAddrs() { - return this.proxyAddrs; - } + @Setter + @Getter + private Integer clientCallbackExecutorThreads = 4; public void setProxyAddrs(List proxyAddrs) { this.proxyAddrs = proxyAddrs; @@ -101,14 +98,6 @@ public class RMQConfigure { } } - public String getProxyAddr() { - return proxyAddr; - } - - public void setProxyAddr(String proxyAddr) { - this.proxyAddr = proxyAddr; - } - public void setNamesrvAddrs(List namesrvAddrs) { this.namesrvAddrs = namesrvAddrs; if (CollectionUtils.isNotEmpty(namesrvAddrs)) { @@ -135,14 +124,6 @@ public class RMQConfigure { return dataPath + File.separator + "dashboard"; } - public void setDataPath(String dataPath) { - this.dataPath = dataPath; - } - - public String getIsVIPChannel() { - return isVIPChannel; - } - public void setIsVIPChannel(String isVIPChannel) { if (StringUtils.isNotBlank(isVIPChannel)) { this.isVIPChannel = isVIPChannel; @@ -151,38 +132,10 @@ public class RMQConfigure { } } - public boolean isEnableDashBoardCollect() { - return enableDashBoardCollect; - } - public void setEnableDashBoardCollect(String enableDashBoardCollect) { this.enableDashBoardCollect = Boolean.valueOf(enableDashBoardCollect); } - public boolean isLoginRequired() { - return loginRequired; - } - - public void setLoginRequired(boolean loginRequired) { - this.loginRequired = loginRequired; - } - - public boolean isUseTLS() { - return useTLS; - } - - public void setUseTLS(boolean useTLS) { - this.useTLS = useTLS; - } - - public Long getTimeoutMillis() { - return timeoutMillis; - } - - public void setTimeoutMillis(Long timeoutMillis) { - this.timeoutMillis = timeoutMillis; - } - // Error Page process logic, move to a central configure later @Bean public ErrorPageRegistrar errorPageRegistrar() { diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/AclController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/AclController.java index 7aef786..6e22958 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/AclController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/AclController.java @@ -14,133 +14,90 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.rocketmq.dashboard.controller; -import com.google.common.base.Preconditions; -import java.util.List; -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.common.AclConfig; -import org.apache.rocketmq.common.PlainAccessConfig; -import org.apache.rocketmq.dashboard.config.RMQConfigure; -import org.apache.rocketmq.dashboard.model.User; -import org.apache.rocketmq.dashboard.model.UserInfo; -import org.apache.rocketmq.dashboard.model.request.AclRequest; -import org.apache.rocketmq.dashboard.permisssion.Permission; -import org.apache.rocketmq.dashboard.service.AclService; -import org.apache.rocketmq.dashboard.support.JsonResult; -import org.apache.rocketmq.dashboard.util.WebUtil; +import org.apache.rocketmq.dashboard.model.PolicyRequest; +import org.apache.rocketmq.dashboard.model.request.UserCreateRequest; +import org.apache.rocketmq.dashboard.model.request.UserUpdateRequest; +import org.apache.rocketmq.dashboard.service.impl.AclServiceImpl; +import org.apache.rocketmq.remoting.protocol.body.UserInfo; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + @RestController @RequestMapping("/acl") -@Permission public class AclController { - @Resource - private AclService aclService; + @Autowired + private AclServiceImpl aclService; - @Resource - private RMQConfigure configure; - - @GetMapping("/enable.query") - public Object isEnableAcl() { - return new JsonResult<>(configure.isACLEnabled()); + @GetMapping("/listUsers") + @ResponseBody + public List listUsers(@RequestParam(required = false) String brokerAddress) { + return aclService.listUsers(brokerAddress); } - @GetMapping("/config.query") - public AclConfig getAclConfig(HttpServletRequest request) { - if (!configure.isLoginRequired()) { - return aclService.getAclConfig(false); - } - UserInfo userInfo = (UserInfo) WebUtil.getValueFromSession(request, WebUtil.USER_INFO); - // if user info is null but reach here, must exclude secret key for safety. - return aclService.getAclConfig(userInfo == null || userInfo.getUser().getType() != User.ADMIN); + @GetMapping("/listAcls") + @ResponseBody + public Object listAcls( + @RequestParam(required = false) String brokerAddress, + @RequestParam(required = false) String searchParam) { + return aclService.listAcls(brokerAddress, searchParam); } - @PostMapping("/add.do") - public Object addAclConfig(@RequestBody PlainAccessConfig config) { - Preconditions.checkArgument(StringUtils.isNotEmpty(config.getAccessKey()), "accessKey is null"); - Preconditions.checkArgument(StringUtils.isNotEmpty(config.getSecretKey()), "secretKey is null"); - aclService.addAclConfig(config); + @PostMapping("/createAcl") + @ResponseBody + public Object createAcl(@RequestBody PolicyRequest request) { + aclService.createAcl(request); return true; } - @PostMapping("/delete.do") - public Object deleteAclConfig(@RequestBody PlainAccessConfig config) { - Preconditions.checkArgument(StringUtils.isNotEmpty(config.getAccessKey()), "accessKey is null"); - aclService.deleteAclConfig(config); + @DeleteMapping("/deleteUser") + @ResponseBody + public Object deleteUser(@RequestParam(required = false) String brokerAddress, @RequestParam String username) { + aclService.deleteUser(brokerAddress, username); return true; } - @PostMapping("/update.do") - public Object updateAclConfig(@RequestBody PlainAccessConfig config) { - Preconditions.checkArgument(StringUtils.isNotEmpty(config.getSecretKey()), "secretKey is null"); - aclService.updateAclConfig(config); + @RequestMapping(value = "/updateUser", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") + @ResponseBody + public Object updateUser(@RequestBody UserUpdateRequest request) { + aclService.updateUser(request.getBrokerAddress(), request.getUserInfo()); return true; } - @PostMapping("/topic/add.do") - public Object addAclTopicConfig(@RequestBody AclRequest request) { - Preconditions.checkArgument(StringUtils.isNotEmpty(request.getConfig().getAccessKey()), "accessKey is null"); - Preconditions.checkArgument(StringUtils.isNotEmpty(request.getConfig().getSecretKey()), "secretKey is null"); - Preconditions.checkArgument(CollectionUtils.isNotEmpty(request.getConfig().getTopicPerms()), "topic perms is null"); - Preconditions.checkArgument(StringUtils.isNotEmpty(request.getTopicPerm()), "topic perm is null"); - aclService.addOrUpdateAclTopicConfig(request); + @PostMapping("/createUser") + public Object createUser(@RequestBody UserCreateRequest request) { + aclService.createUser(request.getBrokerAddress(), request.getUserInfo()); return true; } - @PostMapping("/group/add.do") - public Object addAclGroupConfig(@RequestBody AclRequest request) { - Preconditions.checkArgument(StringUtils.isNotEmpty(request.getConfig().getAccessKey()), "accessKey is null"); - Preconditions.checkArgument(StringUtils.isNotEmpty(request.getConfig().getSecretKey()), "secretKey is null"); - Preconditions.checkArgument(CollectionUtils.isNotEmpty(request.getConfig().getGroupPerms()), "group perms is null"); - Preconditions.checkArgument(StringUtils.isNotEmpty(request.getGroupPerm()), "group perm is null"); - aclService.addOrUpdateAclGroupConfig(request); + @DeleteMapping("/deleteAcl") + public Object deleteAcl( + @RequestParam(required = false) String brokerAddress, + @RequestParam String subject, + @RequestParam(required = false) String resource) { + aclService.deleteAcl(brokerAddress, subject, resource); return true; } - @PostMapping("/perm/delete.do") - public Object deletePermConfig(@RequestBody AclRequest request) { - Preconditions.checkArgument(StringUtils.isNotEmpty(request.getConfig().getAccessKey()), "accessKey is null"); - Preconditions.checkArgument(StringUtils.isNotEmpty(request.getConfig().getSecretKey()), "secretKey is null"); - aclService.deletePermConfig(request); + @RequestMapping(value = "/updateAcl", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") + @ResponseBody + public Object updateAcl(@RequestBody PolicyRequest request) { + aclService.updateAcl(request); return true; } - @PostMapping("/sync.do") - public Object syncConfig(@RequestBody PlainAccessConfig config) { - Preconditions.checkArgument(StringUtils.isNotEmpty(config.getAccessKey()), "accessKey is null"); - Preconditions.checkArgument(StringUtils.isNotEmpty(config.getSecretKey()), "secretKey is null"); - aclService.syncData(config); - return true; - } - @PostMapping("/white/list/add.do") - public Object addWhiteList(@RequestBody List whiteList) { - Preconditions.checkArgument(CollectionUtils.isNotEmpty(whiteList), "white list is null"); - aclService.addWhiteList(whiteList); - return true; - } - - @DeleteMapping("/white/list/delete.do") - public Object deleteWhiteAddr(@RequestParam String request) { - aclService.deleteWhiteAddr(request); - return true; - } - - @PostMapping("/white/list/sync.do") - public Object synchronizeWhiteList(@RequestBody List whiteList) { - Preconditions.checkArgument(CollectionUtils.isNotEmpty(whiteList), "white list is null"); - aclService.synchronizeWhiteList(whiteList); - return true; - } } diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/ClusterController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/ClusterController.java index c3e9fd2..16f9972 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/ClusterController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/ClusterController.java @@ -16,14 +16,13 @@ */ package org.apache.rocketmq.dashboard.controller; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.ClusterService; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; - -import javax.annotation.Resource; import org.springframework.web.bind.annotation.ResponseBody; @Controller diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/ConsumerController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/ConsumerController.java index 59055a7..fdf51bf 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/ConsumerController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/ConsumerController.java @@ -17,9 +17,8 @@ package org.apache.rocketmq.dashboard.controller; import com.google.common.base.Preconditions; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; -import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection; import org.apache.rocketmq.dashboard.model.ConnectionInfo; import org.apache.rocketmq.dashboard.model.request.ConsumerConfigInfo; import org.apache.rocketmq.dashboard.model.request.DeleteSubGroupRequest; @@ -27,6 +26,7 @@ import org.apache.rocketmq.dashboard.model.request.ResetOffsetRequest; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.ConsumerService; import org.apache.rocketmq.dashboard.util.JsonUtil; +import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/DashboardController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/DashboardController.java index 5b0379c..6ea911e 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/DashboardController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/DashboardController.java @@ -17,9 +17,8 @@ package org.apache.rocketmq.dashboard.controller; -import javax.annotation.Resource; - import com.google.common.base.Strings; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.DashboardService; import org.springframework.stereotype.Controller; diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/DlqMessageController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/DlqMessageController.java index d32b1aa..6a499a2 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/DlqMessageController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/DlqMessageController.java @@ -17,10 +17,8 @@ package org.apache.rocketmq.dashboard.controller; import com.google.common.collect.Lists; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.common.MixAll; import org.apache.rocketmq.common.message.MessageExt; @@ -41,6 +39,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.ArrayList; +import java.util.List; + @Controller @RequestMapping("/dlqMessage") @Permission @@ -61,7 +62,7 @@ public class DlqMessageController { @GetMapping(value = "/exportDlqMessage.do") public void exportDlqMessage(HttpServletResponse response, @RequestParam String consumerGroup, - @RequestParam String msgId) { + @RequestParam String msgId) { MessageExt messageExt = null; try { String topic = MixAll.DLQ_GROUP_TOPIC_PREFIX + consumerGroup; diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/LoginController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/LoginController.java index ac76768..9345acc 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/LoginController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/LoginController.java @@ -17,6 +17,9 @@ package org.apache.rocketmq.dashboard.controller; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.model.LoginInfo; import org.apache.rocketmq.dashboard.model.LoginResult; @@ -32,12 +35,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; @Controller @RequestMapping("/login") @@ -66,12 +65,11 @@ public class LoginController { @RequestMapping(value = "/login.do", method = RequestMethod.POST) @ResponseBody - public Object login(@RequestParam("username") String username, - @RequestParam(value = "password") String password, - HttpServletRequest request, - HttpServletResponse response) throws Exception { - logger.info("user:{} login", username); - User user = userService.queryByUsernameAndPassword(username, password); + public Object login(org.apache.rocketmq.remoting.protocol.body.UserInfo userInfoRequest, + HttpServletRequest request, + HttpServletResponse response) throws Exception { + logger.info("user:{} login", userInfoRequest.getUsername()); + User user = userService.queryByUsernameAndPassword(userInfoRequest.getUsername(), userInfoRequest.getPassword()); if (user == null) { throw new IllegalArgumentException("Bad username or password!"); @@ -79,9 +77,9 @@ public class LoginController { user.setPassword(null); UserInfo userInfo = WebUtil.setLoginInfo(request, response, user); WebUtil.setSessionValue(request, WebUtil.USER_INFO, userInfo); - WebUtil.setSessionValue(request, WebUtil.USER_NAME, username); + WebUtil.setSessionValue(request, WebUtil.USER_NAME, userInfoRequest.getUsername()); userInfo.setSessionId(WebUtil.getSessionId(request)); - LoginResult result = new LoginResult(username, user.getType(), contextPath); + LoginResult result = new LoginResult(userInfoRequest.getUsername(), user.getType(), contextPath); return result; } } diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/MessageController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/MessageController.java index 9eb08f6..ba60a27 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/MessageController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/MessageController.java @@ -17,26 +17,26 @@ package org.apache.rocketmq.dashboard.controller; import com.google.common.collect.Maps; +import jakarta.annotation.Resource; import org.apache.rocketmq.common.Pair; -import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; import org.apache.rocketmq.dashboard.model.MessagePage; import org.apache.rocketmq.dashboard.model.MessageView; import org.apache.rocketmq.dashboard.model.request.MessageQuery; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.MessageService; import org.apache.rocketmq.dashboard.util.JsonUtil; +import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; import org.apache.rocketmq.tools.admin.api.MessageTrack; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; -import javax.annotation.Resource; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/MessageTraceController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/MessageTraceController.java index ef3c1b1..f2b04af 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/MessageTraceController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/MessageTraceController.java @@ -18,11 +18,7 @@ package org.apache.rocketmq.dashboard.controller; import com.google.common.collect.Maps; - -import java.util.List; -import java.util.Map; -import javax.annotation.Resource; - +import jakarta.annotation.Resource; import org.apache.rocketmq.common.Pair; import org.apache.rocketmq.dashboard.model.MessageView; import org.apache.rocketmq.dashboard.model.trace.MessageTraceGraph; @@ -36,6 +32,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.List; +import java.util.Map; + @Controller @RequestMapping("/messageTrace") @Permission diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/MonitorController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/MonitorController.java index eb1e979..224ae04 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/MonitorController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/MonitorController.java @@ -16,7 +16,7 @@ */ package org.apache.rocketmq.dashboard.controller; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.model.ConsumerMonitorConfig; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.MonitorService; diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/NamesvrController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/NamesvrController.java index a4a8a4e..acc0e57 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/NamesvrController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/NamesvrController.java @@ -16,7 +16,7 @@ */ package org.apache.rocketmq.dashboard.controller; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.aspect.admin.annotation.OriginalControllerReturnValue; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.OpsService; diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/OpsController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/OpsController.java index 6a56447..601a679 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/OpsController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/OpsController.java @@ -17,7 +17,7 @@ package org.apache.rocketmq.dashboard.controller; import com.google.common.base.Preconditions; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.OpsService; diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/ProducerController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/ProducerController.java index 389506e..42fe872 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/ProducerController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/ProducerController.java @@ -16,11 +16,12 @@ */ package org.apache.rocketmq.dashboard.controller; -import javax.annotation.Resource; -import org.apache.rocketmq.remoting.protocol.body.ProducerConnection; + +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.model.ConnectionInfo; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.ProducerService; +import org.apache.rocketmq.remoting.protocol.body.ProducerConnection; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/ProxyController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/ProxyController.java index 27aa59d..ca8c4c8 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/ProxyController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/ProxyController.java @@ -16,6 +16,7 @@ */ package org.apache.rocketmq.dashboard.controller; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.ProxyService; import org.springframework.stereotype.Controller; @@ -24,8 +25,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import javax.annotation.Resource; - @Controller @RequestMapping("/proxy") @Permission @@ -38,6 +37,7 @@ public class ProxyController { return proxyService.getProxyHomePage(); } + @RequestMapping(value = "/addProxyAddr.do", method = RequestMethod.POST) @ResponseBody public Object addProxyAddr(@RequestParam String newProxyAddr) { diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/TestController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/TestController.java index e50c46e..43938c7 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/TestController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/TestController.java @@ -16,6 +16,7 @@ */ package org.apache.rocketmq.dashboard.controller; +import jakarta.annotation.Resource; import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; @@ -26,11 +27,9 @@ import org.apache.rocketmq.client.producer.SendResult; import org.apache.rocketmq.common.consumer.ConsumeFromWhere; import org.apache.rocketmq.common.message.Message; import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.remoting.exception.RemotingException; -import java.util.List; -import javax.annotation.Resource; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.util.JsonUtil; +import org.apache.rocketmq.remoting.exception.RemotingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; @@ -38,6 +37,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.List; + @Controller @RequestMapping("/test") public class TestController { diff --git a/src/main/java/org/apache/rocketmq/dashboard/controller/TopicController.java b/src/main/java/org/apache/rocketmq/dashboard/controller/TopicController.java index 665a80a..039983a 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/controller/TopicController.java +++ b/src/main/java/org/apache/rocketmq/dashboard/controller/TopicController.java @@ -16,16 +16,17 @@ */ package org.apache.rocketmq.dashboard.controller; +import com.google.common.base.Preconditions; +import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.dashboard.permisssion.Permission; -import org.apache.rocketmq.remoting.exception.RemotingException; import org.apache.rocketmq.dashboard.model.request.SendTopicMessageRequest; import org.apache.rocketmq.dashboard.model.request.TopicConfigInfo; +import org.apache.rocketmq.dashboard.permisssion.Permission; import org.apache.rocketmq.dashboard.service.ConsumerService; import org.apache.rocketmq.dashboard.service.TopicService; import org.apache.rocketmq.dashboard.util.JsonUtil; -import com.google.common.base.Preconditions; -import org.apache.commons.collections.CollectionUtils; +import org.apache.rocketmq.remoting.exception.RemotingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; @@ -33,8 +34,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; - -import javax.annotation.Resource; import org.springframework.web.bind.annotation.ResponseBody; @Controller diff --git a/src/main/java/org/apache/rocketmq/dashboard/filter/HttpBasicAuthorizedFilter.java b/src/main/java/org/apache/rocketmq/dashboard/filter/HttpBasicAuthorizedFilter.java index 10c3671..3e25a68 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/filter/HttpBasicAuthorizedFilter.java +++ b/src/main/java/org/apache/rocketmq/dashboard/filter/HttpBasicAuthorizedFilter.java @@ -17,27 +17,29 @@ package org.apache.rocketmq.dashboard.filter; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.annotation.WebFilter; +import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.annotation.WebFilter; -import javax.servlet.http.HttpServletResponse; + @WebFilter(urlPatterns = "/*", filterName = "httpBasicAuthorizedFilter") public class HttpBasicAuthorizedFilter implements Filter { - + @Override public void init(FilterConfig config) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { + FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setCharacterEncoding("UTF-8"); httpResponse.setContentType("application/json; charset=utf-8"); diff --git a/src/main/java/org/apache/rocketmq/dashboard/interceptor/AuthInterceptor.java b/src/main/java/org/apache/rocketmq/dashboard/interceptor/AuthInterceptor.java index 88b742b..b85c4a2 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/interceptor/AuthInterceptor.java +++ b/src/main/java/org/apache/rocketmq/dashboard/interceptor/AuthInterceptor.java @@ -17,22 +17,24 @@ package org.apache.rocketmq.dashboard.interceptor; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.rocketmq.dashboard.service.LoginService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; +import org.springframework.web.servlet.HandlerInterceptor; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; @Component -public class AuthInterceptor extends HandlerInterceptorAdapter { +public class AuthInterceptor implements HandlerInterceptor { + @Autowired private LoginService loginService; @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return loginService.login(request, response); } + + } diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/ConnectionInfo.java b/src/main/java/org/apache/rocketmq/dashboard/model/ConnectionInfo.java index a100f92..497ec69 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/model/ConnectionInfo.java +++ b/src/main/java/org/apache/rocketmq/dashboard/model/ConnectionInfo.java @@ -17,11 +17,12 @@ package org.apache.rocketmq.dashboard.model; import com.google.common.collect.Sets; -import java.util.Collection; -import java.util.HashSet; import org.apache.rocketmq.common.MQVersion; import org.apache.rocketmq.remoting.protocol.body.Connection; +import java.util.Collection; +import java.util.HashSet; + public class ConnectionInfo extends Connection { private String versionDesc; diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/ConsumerGroupRollBackStat.java b/src/main/java/org/apache/rocketmq/dashboard/model/ConsumerGroupRollBackStat.java index a42037b..52383cd 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/model/ConsumerGroupRollBackStat.java +++ b/src/main/java/org/apache/rocketmq/dashboard/model/ConsumerGroupRollBackStat.java @@ -16,8 +16,8 @@ */ package org.apache.rocketmq.dashboard.model; -import org.apache.rocketmq.remoting.protocol.admin.RollbackStats; import com.google.common.collect.Lists; +import org.apache.rocketmq.remoting.protocol.admin.RollbackStats; import java.util.List; diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/DlqMessageExcelModel.java b/src/main/java/org/apache/rocketmq/dashboard/model/DlqMessageExcelModel.java index e010a1c..b0fec05 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/model/DlqMessageExcelModel.java +++ b/src/main/java/org/apache/rocketmq/dashboard/model/DlqMessageExcelModel.java @@ -22,12 +22,13 @@ import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.util.DateUtils; import com.google.common.base.Charsets; -import java.io.Serializable; -import java.util.Date; import lombok.Data; import lombok.NoArgsConstructor; import org.apache.rocketmq.common.message.MessageExt; +import java.io.Serializable; +import java.util.Date; + @Data @NoArgsConstructor public class DlqMessageExcelModel extends BaseRowModel implements Serializable { diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/Entry.java b/src/main/java/org/apache/rocketmq/dashboard/model/Entry.java new file mode 100644 index 0000000..40b292a --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/model/Entry.java @@ -0,0 +1,33 @@ +/* + * 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.rocketmq.dashboard.model; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Setter +@Getter +public class Entry { + private List resource; + private List actions; + private List sourceIps; + private String decision; + +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/MessageView.java b/src/main/java/org/apache/rocketmq/dashboard/model/MessageView.java index 13a9641..edd56e0 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/model/MessageView.java +++ b/src/main/java/org/apache/rocketmq/dashboard/model/MessageView.java @@ -16,8 +16,8 @@ */ package org.apache.rocketmq.dashboard.model; -import org.apache.rocketmq.common.message.MessageExt; import com.google.common.base.Charsets; +import org.apache.rocketmq.common.message.MessageExt; import org.springframework.beans.BeanUtils; import java.net.SocketAddress; diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/Policy.java b/src/main/java/org/apache/rocketmq/dashboard/model/Policy.java new file mode 100644 index 0000000..641e7fe --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/model/Policy.java @@ -0,0 +1,30 @@ +/* + * 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.rocketmq.dashboard.model; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Setter +@Getter +public class Policy { + private String policyType; + private List entries; +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/PolicyRequest.java b/src/main/java/org/apache/rocketmq/dashboard/model/PolicyRequest.java new file mode 100644 index 0000000..43dcd0d --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/model/PolicyRequest.java @@ -0,0 +1,31 @@ +/* + * 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.rocketmq.dashboard.model; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class PolicyRequest { + private String brokerAddress; + private String subject; + private List policies; +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/QueueStatInfo.java b/src/main/java/org/apache/rocketmq/dashboard/model/QueueStatInfo.java index 29dc542..80acbf0 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/model/QueueStatInfo.java +++ b/src/main/java/org/apache/rocketmq/dashboard/model/QueueStatInfo.java @@ -16,8 +16,8 @@ */ package org.apache.rocketmq.dashboard.model; -import org.apache.rocketmq.remoting.protocol.admin.OffsetWrapper; import org.apache.rocketmq.common.message.MessageQueue; +import org.apache.rocketmq.remoting.protocol.admin.OffsetWrapper; import org.springframework.beans.BeanUtils; public class QueueStatInfo { diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/request/AclRequest.java b/src/main/java/org/apache/rocketmq/dashboard/model/request/AclRequest.java index 8f11e7b..032c6d7 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/model/request/AclRequest.java +++ b/src/main/java/org/apache/rocketmq/dashboard/model/request/AclRequest.java @@ -17,7 +17,8 @@ package org.apache.rocketmq.dashboard.model.request; import lombok.Data; -import org.apache.rocketmq.common.PlainAccessConfig; +import org.apache.rocketmq.auth.migration.v1.PlainAccessConfig; + @Data public class AclRequest { diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/request/UserCreateRequest.java b/src/main/java/org/apache/rocketmq/dashboard/model/request/UserCreateRequest.java new file mode 100644 index 0000000..b0888d3 --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/model/request/UserCreateRequest.java @@ -0,0 +1,28 @@ +/* + * 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.rocketmq.dashboard.model.request; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class UserCreateRequest { + private String brokerAddress; + private UserInfoParam userInfo; +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/request/UserInfoParam.java b/src/main/java/org/apache/rocketmq/dashboard/model/request/UserInfoParam.java new file mode 100644 index 0000000..f2dc8ab --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/model/request/UserInfoParam.java @@ -0,0 +1,28 @@ +/* + * 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.rocketmq.dashboard.model.request; + +import lombok.Data; + +@Data +public class UserInfoParam { + private String username; + private String password; + private String userStatus; + private String userType; +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/model/request/UserUpdateRequest.java b/src/main/java/org/apache/rocketmq/dashboard/model/request/UserUpdateRequest.java new file mode 100644 index 0000000..9ef63f5 --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/model/request/UserUpdateRequest.java @@ -0,0 +1,28 @@ +/* + * 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.rocketmq.dashboard.model.request; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class UserUpdateRequest { + private String brokerAddress; + private UserInfoParam userInfo; +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/permisssion/PermissionAspect.java b/src/main/java/org/apache/rocketmq/dashboard/permisssion/PermissionAspect.java index fcbfea2..e588b47 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/permisssion/PermissionAspect.java +++ b/src/main/java/org/apache/rocketmq/dashboard/permisssion/PermissionAspect.java @@ -16,10 +16,9 @@ */ package org.apache.rocketmq.dashboard.permisssion; -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; import org.apache.rocketmq.dashboard.config.RMQConfigure; -import org.apache.rocketmq.dashboard.exception.ServiceException; import org.apache.rocketmq.dashboard.model.UserInfo; import org.apache.rocketmq.dashboard.service.PermissionService; import org.apache.rocketmq.dashboard.util.WebUtil; @@ -56,13 +55,13 @@ public class PermissionAspect { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String url = request.getRequestURI(); UserInfo userInfo = (UserInfo) request.getSession().getAttribute(WebUtil.USER_INFO); - if (userInfo == null || userInfo.getUser() == null) { - throw new ServiceException(-1, "user not login"); - } - boolean checkResult = permissionService.checkUrlAvailable(userInfo, url); - if (!checkResult) { - throw new ServiceException(-1, "no permission"); - } +// if (userInfo == null || userInfo.getUser() == null) { +// throw new ServiceException(-1, "user not login"); +// } +// boolean checkResult = permissionService.checkUrlAvailable(userInfo, url); +// if (!checkResult) { +// throw new ServiceException(-1, "no permission"); +// } } return joinPoint.proceed(); } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/AbstractCommonService.java b/src/main/java/org/apache/rocketmq/dashboard/service/AbstractCommonService.java index a546fbf..b1b097c 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/AbstractCommonService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/AbstractCommonService.java @@ -16,14 +16,15 @@ */ package org.apache.rocketmq.dashboard.service; -import org.apache.rocketmq.tools.admin.MQAdminExt; import com.google.common.base.Throwables; import com.google.common.collect.Sets; +import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; +import org.apache.rocketmq.tools.admin.MQAdminExt; + import java.util.List; import java.util.Map; import java.util.Set; -import javax.annotation.Resource; -import org.apache.commons.collections.CollectionUtils; public abstract class AbstractCommonService { @Resource diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/AclService.java b/src/main/java/org/apache/rocketmq/dashboard/service/AclService.java index 96b6e06..9386331 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/AclService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/AclService.java @@ -14,34 +14,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.rocketmq.dashboard.service; + +import org.apache.rocketmq.dashboard.model.PolicyRequest; +import org.apache.rocketmq.dashboard.model.request.UserInfoParam; +import org.apache.rocketmq.remoting.protocol.body.UserInfo; + import java.util.List; -import org.apache.rocketmq.common.AclConfig; -import org.apache.rocketmq.common.PlainAccessConfig; -import org.apache.rocketmq.dashboard.model.request.AclRequest; public interface AclService { + List listUsers(String brokerAddress); - AclConfig getAclConfig(boolean excludeSecretKey); + Object listAcls(String brokerAddress, String searchParam); - void addAclConfig(PlainAccessConfig config); + List createAcl(PolicyRequest policyRequest); - void deleteAclConfig(PlainAccessConfig config); + void deleteUser(String brokerAddress, String username); - void updateAclConfig(PlainAccessConfig config); + void updateUser(String brokerAddress, UserInfoParam userParam); - void addOrUpdateAclTopicConfig(AclRequest request); + void createUser(String brokerAddress, UserInfoParam userParam); - void addOrUpdateAclGroupConfig(AclRequest request); + void deleteAcl(String brokerAddress, String subject, String resource); - void deletePermConfig(AclRequest request); - - void syncData(PlainAccessConfig config); - - void addWhiteList(List whiteList); - - void deleteWhiteAddr(String addr); - - void synchronizeWhiteList(List whiteList); + void updateAcl(PolicyRequest policyRequest); } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/ClusterInfoService.java b/src/main/java/org/apache/rocketmq/dashboard/service/ClusterInfoService.java index 3dc12b3..da2bdec 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/ClusterInfoService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/ClusterInfoService.java @@ -16,14 +16,14 @@ */ package org.apache.rocketmq.dashboard.service; +import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; import org.apache.rocketmq.tools.admin.MQAdminExt; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; -import javax.annotation.Resource; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -33,7 +33,7 @@ import java.util.concurrent.atomic.AtomicReference; @Service public class ClusterInfoService { - @Resource + @Autowired private MQAdminExt mqAdminExt; @Value("${rocketmq.cluster.cache.expire:60000}") diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/ConsumerService.java b/src/main/java/org/apache/rocketmq/dashboard/service/ConsumerService.java index 60bc1b3..9a80df3 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/ConsumerService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/ConsumerService.java @@ -17,14 +17,14 @@ package org.apache.rocketmq.dashboard.service; +import org.apache.rocketmq.dashboard.model.ConsumerGroupRollBackStat; +import org.apache.rocketmq.dashboard.model.GroupConsumeInfo; +import org.apache.rocketmq.dashboard.model.TopicConsumerInfo; import org.apache.rocketmq.dashboard.model.request.ConsumerConfigInfo; import org.apache.rocketmq.dashboard.model.request.DeleteSubGroupRequest; import org.apache.rocketmq.dashboard.model.request.ResetOffsetRequest; import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection; import org.apache.rocketmq.remoting.protocol.body.ConsumerRunningInfo; -import org.apache.rocketmq.dashboard.model.ConsumerGroupRollBackStat; -import org.apache.rocketmq.dashboard.model.GroupConsumeInfo; -import org.apache.rocketmq.dashboard.model.TopicConsumerInfo; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/DashboardCollectService.java b/src/main/java/org/apache/rocketmq/dashboard/service/DashboardCollectService.java index fdee259..fb21c2d 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/DashboardCollectService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/DashboardCollectService.java @@ -17,6 +17,7 @@ package org.apache.rocketmq.dashboard.service; import com.google.common.cache.LoadingCache; + import java.io.File; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/DlqMessageService.java b/src/main/java/org/apache/rocketmq/dashboard/service/DlqMessageService.java index 96adf92..1ed3c65 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/DlqMessageService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/DlqMessageService.java @@ -17,12 +17,13 @@ package org.apache.rocketmq.dashboard.service; -import java.util.List; -import org.apache.rocketmq.dashboard.model.DlqMessageResendResult; import org.apache.rocketmq.dashboard.model.DlqMessageRequest; +import org.apache.rocketmq.dashboard.model.DlqMessageResendResult; import org.apache.rocketmq.dashboard.model.MessagePage; import org.apache.rocketmq.dashboard.model.request.MessageQuery; +import java.util.List; + public interface DlqMessageService { MessagePage queryDlqMessageByPage(MessageQuery query); diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/LoginService.java b/src/main/java/org/apache/rocketmq/dashboard/service/LoginService.java index 10e5a7f..91d7c63 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/LoginService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/LoginService.java @@ -17,8 +17,9 @@ package org.apache.rocketmq.dashboard.service; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; public interface LoginService { boolean login(HttpServletRequest request, HttpServletResponse response); diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/MessageService.java b/src/main/java/org/apache/rocketmq/dashboard/service/MessageService.java index 36fb5cd..ce738fe 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/MessageService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/MessageService.java @@ -19,11 +19,11 @@ package org.apache.rocketmq.dashboard.service; import org.apache.rocketmq.common.Pair; import org.apache.rocketmq.common.message.MessageExt; -import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; import org.apache.rocketmq.dashboard.model.MessagePage; -import org.apache.rocketmq.dashboard.model.request.MessageQuery; -import org.apache.rocketmq.tools.admin.api.MessageTrack; import org.apache.rocketmq.dashboard.model.MessageView; +import org.apache.rocketmq.dashboard.model.request.MessageQuery; +import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; +import org.apache.rocketmq.tools.admin.api.MessageTrack; import java.util.List; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/MessageTraceService.java b/src/main/java/org/apache/rocketmq/dashboard/service/MessageTraceService.java index 797fc40..3e7efd9 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/MessageTraceService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/MessageTraceService.java @@ -17,10 +17,11 @@ package org.apache.rocketmq.dashboard.service; -import java.util.List; import org.apache.rocketmq.dashboard.model.MessageTraceView; import org.apache.rocketmq.dashboard.model.trace.MessageTraceGraph; +import java.util.List; + public interface MessageTraceService { List queryMessageTraceKey(final String key); diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/MonitorService.java b/src/main/java/org/apache/rocketmq/dashboard/service/MonitorService.java index 526bb5c..afb8bd2 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/MonitorService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/MonitorService.java @@ -16,9 +16,10 @@ */ package org.apache.rocketmq.dashboard.service; -import java.util.Map; import org.apache.rocketmq.dashboard.model.ConsumerMonitorConfig; +import java.util.Map; + public interface MonitorService { boolean createOrUpdateConsumerMonitor(String name, ConsumerMonitorConfig config); diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/OpsService.java b/src/main/java/org/apache/rocketmq/dashboard/service/OpsService.java index ea1b85e..4d7fd0a 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/OpsService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/OpsService.java @@ -16,9 +16,10 @@ */ package org.apache.rocketmq.dashboard.service; -import java.util.Map; import org.apache.rocketmq.dashboard.service.checker.CheckerType; +import java.util.Map; + public interface OpsService { Map homePageInfo(); diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/TopicService.java b/src/main/java/org/apache/rocketmq/dashboard/service/TopicService.java index b0f4814..fe2c1ed 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/TopicService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/TopicService.java @@ -19,13 +19,13 @@ package org.apache.rocketmq.dashboard.service; import org.apache.rocketmq.client.producer.SendResult; import org.apache.rocketmq.common.TopicConfig; +import org.apache.rocketmq.dashboard.model.request.SendTopicMessageRequest; +import org.apache.rocketmq.dashboard.model.request.TopicConfigInfo; import org.apache.rocketmq.dashboard.model.request.TopicTypeList; import org.apache.rocketmq.remoting.protocol.admin.TopicStatsTable; import org.apache.rocketmq.remoting.protocol.body.GroupList; import org.apache.rocketmq.remoting.protocol.body.TopicList; import org.apache.rocketmq.remoting.protocol.route.TopicRouteData; -import org.apache.rocketmq.dashboard.model.request.SendTopicMessageRequest; -import org.apache.rocketmq.dashboard.model.request.TopicConfigInfo; import java.util.List; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/UserService.java b/src/main/java/org/apache/rocketmq/dashboard/service/UserService.java index 37ab67f..e534fd0 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/UserService.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/UserService.java @@ -22,4 +22,5 @@ public interface UserService { User queryByName(String name); User queryByUsernameAndPassword(String username, String password); + } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/client/MQAdminExtImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/client/MQAdminExtImpl.java index 146f9e5..15270bc 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/client/MQAdminExtImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/client/MQAdminExtImpl.java @@ -17,34 +17,34 @@ package org.apache.rocketmq.dashboard.service.client; import com.google.common.base.Throwables; - -import java.io.UnsupportedEncodingException; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import org.apache.rocketmq.client.QueryResult; import org.apache.rocketmq.client.exception.MQBrokerException; import org.apache.rocketmq.client.exception.MQClientException; import org.apache.rocketmq.client.impl.MQAdminImpl; -import org.apache.rocketmq.common.AclConfig; -import org.apache.rocketmq.common.PlainAccessConfig; +import org.apache.rocketmq.common.CheckRocksdbCqWriteResult; +import org.apache.rocketmq.common.Pair; import org.apache.rocketmq.common.TopicConfig; -import org.apache.rocketmq.remoting.protocol.admin.ConsumeStats; -import org.apache.rocketmq.remoting.protocol.admin.RollbackStats; -import org.apache.rocketmq.remoting.protocol.admin.TopicStatsTable; import org.apache.rocketmq.common.message.MessageClientIDSetter; import org.apache.rocketmq.common.message.MessageExt; import org.apache.rocketmq.common.message.MessageQueue; import org.apache.rocketmq.common.message.MessageRequestMode; +import org.apache.rocketmq.dashboard.util.JsonUtil; +import org.apache.rocketmq.remoting.RemotingClient; +import org.apache.rocketmq.remoting.exception.RemotingCommandException; +import org.apache.rocketmq.remoting.exception.RemotingConnectException; +import org.apache.rocketmq.remoting.exception.RemotingException; +import org.apache.rocketmq.remoting.exception.RemotingSendRequestException; +import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; +import org.apache.rocketmq.remoting.protocol.RemotingCommand; import org.apache.rocketmq.remoting.protocol.RequestCode; import org.apache.rocketmq.remoting.protocol.ResponseCode; +import org.apache.rocketmq.remoting.protocol.admin.ConsumeStats; +import org.apache.rocketmq.remoting.protocol.admin.RollbackStats; +import org.apache.rocketmq.remoting.protocol.admin.TopicStatsTable; +import org.apache.rocketmq.remoting.protocol.body.AclInfo; +import org.apache.rocketmq.remoting.protocol.body.BrokerMemberGroup; import org.apache.rocketmq.remoting.protocol.body.BrokerReplicasInfo; import org.apache.rocketmq.remoting.protocol.body.BrokerStatsData; -import org.apache.rocketmq.remoting.protocol.body.ClusterAclVersionInfo; import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; import org.apache.rocketmq.remoting.protocol.body.ConsumeStatsList; @@ -61,6 +61,8 @@ import org.apache.rocketmq.remoting.protocol.body.QueueTimeSpan; import org.apache.rocketmq.remoting.protocol.body.SubscriptionGroupWrapper; import org.apache.rocketmq.remoting.protocol.body.TopicConfigSerializeWrapper; import org.apache.rocketmq.remoting.protocol.body.TopicList; +import org.apache.rocketmq.remoting.protocol.body.UserInfo; +import org.apache.rocketmq.remoting.protocol.header.ExportRocksDBConfigToJsonRequestHeader; import org.apache.rocketmq.remoting.protocol.header.controller.ElectMasterResponseHeader; import org.apache.rocketmq.remoting.protocol.header.controller.GetMetaDataResponseHeader; import org.apache.rocketmq.remoting.protocol.heartbeat.SubscriptionData; @@ -68,14 +70,6 @@ import org.apache.rocketmq.remoting.protocol.route.TopicRouteData; import org.apache.rocketmq.remoting.protocol.statictopic.TopicQueueMappingDetail; import org.apache.rocketmq.remoting.protocol.subscription.GroupForbidden; import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig; -import org.apache.rocketmq.dashboard.util.JsonUtil; -import org.apache.rocketmq.remoting.RemotingClient; -import org.apache.rocketmq.remoting.exception.RemotingCommandException; -import org.apache.rocketmq.remoting.exception.RemotingConnectException; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.apache.rocketmq.remoting.exception.RemotingSendRequestException; -import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; -import org.apache.rocketmq.remoting.protocol.RemotingCommand; import org.apache.rocketmq.tools.admin.MQAdminExt; import org.apache.rocketmq.tools.admin.api.BrokerOperatorResult; import org.apache.rocketmq.tools.admin.api.MessageTrack; @@ -85,6 +79,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import java.io.UnsupportedEncodingException; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + import static org.apache.rocketmq.remoting.protocol.RemotingSerializable.decode; @Service @@ -114,34 +116,10 @@ public class MQAdminExtImpl implements MQAdminExt { } @Override - public void createAndUpdatePlainAccessConfig(String addr, - PlainAccessConfig plainAccessConfig) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { - MQAdminInstance.threadLocalMQAdminExt().createAndUpdatePlainAccessConfig(addr, plainAccessConfig); + public void createAndUpdateTopicConfigList(String s, List list) throws InterruptedException, RemotingException, MQClientException { + } - @Override - public void deletePlainAccessConfig(String addr, - String accessKey) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { - MQAdminInstance.threadLocalMQAdminExt().deletePlainAccessConfig(addr, accessKey); - } - - @Override - public void updateGlobalWhiteAddrConfig(String addr, - String globalWhiteAddrs) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { - MQAdminInstance.threadLocalMQAdminExt().updateGlobalWhiteAddrConfig(addr, globalWhiteAddrs); - } - - @Override - public ClusterAclVersionInfo examineBrokerClusterAclVersionInfo( - String addr) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { - return null; - } - - @Override - public AclConfig examineBrokerClusterAclConfig( - String addr) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { - return MQAdminInstance.threadLocalMQAdminExt().examineBrokerClusterAclConfig(addr); - } @Override public void createAndUpdateSubscriptionGroupConfig(String addr, SubscriptionGroupConfig config) @@ -149,6 +127,11 @@ public class MQAdminExtImpl implements MQAdminExt { MQAdminInstance.threadLocalMQAdminExt().createAndUpdateSubscriptionGroupConfig(addr, config); } + @Override + public void createAndUpdateSubscriptionGroupConfigList(String s, List list) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { + + } + @Override public SubscriptionGroupConfig examineSubscriptionGroupConfig(String addr, String group) throws MQBrokerException { RemotingClient remotingClient = MQAdminInstance.threadLocalRemotingClient(); @@ -228,12 +211,22 @@ public class MQAdminExtImpl implements MQAdminExt { return MQAdminInstance.threadLocalMQAdminExt().examineConsumeStats(consumerGroup); } + @Override + public CheckRocksdbCqWriteResult checkRocksdbCqWriteProgress(String s, String s1, long l) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQClientException { + return null; + } + @Override public ConsumeStats examineConsumeStats(String consumerGroup, String topic) throws RemotingException, MQClientException, InterruptedException, MQBrokerException { return MQAdminInstance.threadLocalMQAdminExt().examineConsumeStats(consumerGroup, topic); } + @Override + public ConsumeStats examineConsumeStats(String s, String s1, String s2) throws RemotingException, MQClientException, InterruptedException, MQBrokerException { + return null; + } + @Override public ClusterInfo examineBrokerClusterInfo() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, @@ -344,6 +337,11 @@ public class MQAdminExtImpl implements MQAdminExt { return MQAdminInstance.threadLocalMQAdminExt().resetOffsetByTimestamp(topic, group, timestamp, isForce); } + @Override + public Map resetOffsetByTimestamp(String s, String s1, String s2, long l, boolean b) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { + return Map.of(); + } + @Override public void resetOffsetNew(String consumerGroup, String topic, long timestamp) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { @@ -389,11 +387,6 @@ public class MQAdminExtImpl implements MQAdminExt { return MQAdminInstance.threadLocalMQAdminExt().getConsumerRunningInfo(consumerGroup, clientId, jstack); } - @Override - public ConsumeMessageDirectlyResult consumeMessageDirectly(String consumerGroup, String clientId, - String msgId) throws RemotingException, MQClientException, InterruptedException, MQBrokerException { - return MQAdminInstance.threadLocalMQAdminExt().consumeMessageDirectly(consumerGroup, clientId, msgId); - } @Override public List messageTrackDetail(MessageExt msg) @@ -438,12 +431,6 @@ public class MQAdminExtImpl implements MQAdminExt { return MQAdminInstance.threadLocalMQAdminExt().earliestMsgStoreTime(mq); } - @Override - public MessageExt viewMessage(String msgId) - throws RemotingException, MQBrokerException, InterruptedException, MQClientException { - return MQAdminInstance.threadLocalMQAdminExt().viewMessage(msgId); - } - @Override public QueryResult queryMessage(String topic, String key, int maxNum, long begin, long end) throws MQClientException, InterruptedException { @@ -478,10 +465,6 @@ public class MQAdminExtImpl implements MQAdminExt { public MessageExt viewMessage(String topic, String msgId) throws RemotingException, MQBrokerException, InterruptedException, MQClientException { logger.info("MessageClientIDSetter.getNearlyTimeFromID(msgId)={} msgId={}", MessageClientIDSetter.getNearlyTimeFromID(msgId), msgId); - try { - return viewMessage(msgId); - } catch (Exception e) { - } MQAdminImpl mqAdminImpl = MQAdminInstance.threadLocalMqClientInstance().getMQAdminImpl(); Set clusterList = MQAdminInstance.threadLocalMQAdminExt().getTopicClusterList(topic); if (clusterList == null || clusterList.isEmpty()) { @@ -508,6 +491,11 @@ public class MQAdminExtImpl implements MQAdminExt { return MQAdminInstance.threadLocalMQAdminExt().consumeMessageDirectly(consumerGroup, clientId, topic, msgId); } + @Override + public ConsumeMessageDirectlyResult consumeMessageDirectly(String s, String s1, String s2, String s3, String s4) throws RemotingException, MQClientException, InterruptedException, MQBrokerException { + return null; + } + @Override public Properties getBrokerConfig( String brokerAddr) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, UnsupportedEncodingException, InterruptedException, MQBrokerException { @@ -603,11 +591,12 @@ public class MQAdminExtImpl implements MQAdminExt { return null; } - @Override public boolean resumeCheckHalfMessage( - String msgId) throws RemotingException, MQClientException, InterruptedException, MQBrokerException { - return false; + @Override + public void exportRocksDBConfigToJson(String s, List list) throws InterruptedException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException, MQClientException { + } + @Override public boolean resumeCheckHalfMessage(String topic, String msgId) throws RemotingException, MQClientException, InterruptedException, MQBrokerException { return false; @@ -628,12 +617,6 @@ public class MQAdminExtImpl implements MQAdminExt { throw new UnsupportedOperationException("Unimplemented method 'removeBrokerFromContainer'"); } - @Override - public void updateGlobalWhiteAddrConfig(String addr, String globalWhiteAddrs, String aclFileFullPath) - throws RemotingException, MQBrokerException, InterruptedException, MQClientException { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'updateGlobalWhiteAddrConfig'"); - } @Override public TopicStatsTable examineTopicStats(String brokerAddr, String topic) @@ -851,10 +834,8 @@ public class MQAdminExtImpl implements MQAdminExt { } @Override - public ElectMasterResponseHeader electMaster(String controllerAddr, String clusterName, String brokerName, - String brokerAddr) throws RemotingException, InterruptedException, MQBrokerException { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'electMaster'"); + public Pair electMaster(String s, String s1, String s2, Long aLong) throws RemotingException, InterruptedException, MQBrokerException { + return null; } @Override @@ -864,4 +845,125 @@ public class MQAdminExtImpl implements MQAdminExt { // TODO Auto-generated method stub throw new UnsupportedOperationException("Unimplemented method 'cleanControllerBrokerData'"); } + + @Override + public void updateColdDataFlowCtrGroupConfig(String brokerAddr, Properties properties) + throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, + UnsupportedEncodingException, InterruptedException, MQBrokerException { + MQAdminInstance.threadLocalMQAdminExt().updateColdDataFlowCtrGroupConfig(brokerAddr, properties); + } + + @Override + public void removeColdDataFlowCtrGroupConfig(String brokerAddr, String consumerGroup) + throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, + UnsupportedEncodingException, InterruptedException, MQBrokerException { + MQAdminInstance.threadLocalMQAdminExt().removeColdDataFlowCtrGroupConfig(brokerAddr, consumerGroup); + } + + @Override + public String getColdDataFlowCtrInfo(String brokerAddr) + throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, + UnsupportedEncodingException, InterruptedException, MQBrokerException { + return MQAdminInstance.threadLocalMQAdminExt().getColdDataFlowCtrInfo(brokerAddr); + } + + @Override + public String setCommitLogReadAheadMode(String brokerAddr, String mode) + throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, + InterruptedException, MQBrokerException, UnsupportedEncodingException { + return MQAdminInstance.threadLocalMQAdminExt().setCommitLogReadAheadMode(brokerAddr, mode); + } + + @Override + public void createUser(String brokerAddr, + UserInfo userInfo) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().createUser(brokerAddr, userInfo); + } + + @Override + public void createUser(String brokerAddr, String username, String password, + String userType) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().createUser(brokerAddr, username, password, userType); + } + + @Override + public void updateUser(String brokerAddr, String username, + String password, String userType, + String userStatus) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().updateUser(brokerAddr, username, password, userType, userStatus); + } + + @Override + public void updateUser(String brokerAddr, + UserInfo userInfo) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().updateUser(brokerAddr, userInfo); + } + + @Override + public void deleteUser(String brokerAddr, + String username) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().deleteUser(brokerAddr, username); + } + + @Override + public UserInfo getUser(String brokerAddr, + String username) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + return MQAdminInstance.threadLocalMQAdminExt().getUser(brokerAddr, username); + } + + @Override + public List listUser(String brokerAddr, + String filter) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + return MQAdminInstance.threadLocalMQAdminExt().listUser(brokerAddr, filter); + } + + @Override + public void createAcl(String brokerAddr, String subject, List resources, List actions, + List sourceIps, + String decision) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().createAcl(brokerAddr, subject, resources, actions, sourceIps, decision); + } + + @Override + public void createAcl(String brokerAddr, + AclInfo aclInfo) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().createAcl(brokerAddr, aclInfo); + } + + @Override + public void updateAcl(String brokerAddr, String subject, List resources, List actions, + List sourceIps, + String decision) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().updateAcl(brokerAddr, subject, resources, actions, sourceIps, decision); + } + + @Override + public void updateAcl(String brokerAddr, + AclInfo aclInfo) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().updateAcl(brokerAddr, aclInfo); + } + + @Override + public void deleteAcl(String brokerAddr, String subject, + String resource) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().deleteAcl(brokerAddr, subject, resource); + } + + @Override + public AclInfo getAcl(String brokerAddr, + String subject) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + return MQAdminInstance.threadLocalMQAdminExt().getAcl(brokerAddr, subject); + } + + @Override + public List listAcl(String brokerAddr, String subjectFilter, + String resourceFilter) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + return MQAdminInstance.threadLocalMQAdminExt().listAcl(brokerAddr, subjectFilter, resourceFilter); + } + + @Override + public void exportPopRecords(String brokerAddr, long timeout) throws RemotingConnectException, + RemotingSendRequestException, RemotingTimeoutException, MQBrokerException, InterruptedException { + MQAdminInstance.threadLocalMQAdminExt().exportPopRecords(brokerAddr, timeout); + } } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/client/MQAdminInstance.java b/src/main/java/org/apache/rocketmq/dashboard/service/client/MQAdminInstance.java index 8d9ae4f..47d5eb7 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/client/MQAdminInstance.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/client/MQAdminInstance.java @@ -16,7 +16,6 @@ */ package org.apache.rocketmq.dashboard.service.client; -import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.rocketmq.client.impl.MQClientAPIImpl; import org.apache.rocketmq.client.impl.factory.MQClientInstance; import org.apache.rocketmq.remoting.RemotingClient; @@ -29,47 +28,69 @@ import org.slf4j.LoggerFactory; public class MQAdminInstance { private static final Logger LOGGER = LoggerFactory.getLogger(MQAdminInstance.class); + // ThreadLocal to store the MQAdminExt instance for the current thread. private static final ThreadLocal MQ_ADMIN_EXT_THREAD_LOCAL = new ThreadLocal<>(); + /** + * Retrieves the MQAdminExt instance associated with the current thread. + * + * @return The MQAdminExt instance. + * @throws IllegalStateException if no MQAdminExt instance has been set for the current thread. + */ public static MQAdminExt threadLocalMQAdminExt() { MQAdminExt mqAdminExt = MQ_ADMIN_EXT_THREAD_LOCAL.get(); if (mqAdminExt == null) { - throw new IllegalStateException("defaultMQAdminExt should be init before you get this"); + // This indicates a programming error: MQAdminExt was not set by the aspect. + throw new IllegalStateException("MQAdminExt instance should be set by MQAdminAspect before it's accessed."); } return mqAdminExt; } - public static RemotingClient threadLocalRemotingClient() { + /** + * Retrieves the RemotingClient from the MQAdminExt instance in the current thread. + * This method relies on reflection and the internal structure of RocketMQ classes. + * + * @return The RemotingClient instance. + */ + public static RemotingClient threadLocalRemotingClient() { // Assuming RemotingClient is a type you have MQClientInstance mqClientInstance = threadLocalMqClientInstance(); + // Use jOOQ-Reflect to access private field "mQClientAPIImpl" from mqClientInstance MQClientAPIImpl mQClientAPIImpl = Reflect.on(mqClientInstance).get("mQClientAPIImpl"); + // Use jOOQ-Reflect to access private field "remotingClient" from mQClientAPIImpl return Reflect.on(mQClientAPIImpl).get("remotingClient"); } + /** + * Retrieves the MQClientInstance from the MQAdminExt instance in the current thread. + * This method relies on reflection and the internal structure of RocketMQ classes. + * + * @return The MQClientInstance instance. + */ public static MQClientInstance threadLocalMqClientInstance() { + // Use jOOQ-Reflect to access private field "defaultMQAdminExtImpl" from threadLocalMQAdminExt() DefaultMQAdminExtImpl defaultMQAdminExtImpl = Reflect.on(MQAdminInstance.threadLocalMQAdminExt()).get("defaultMQAdminExtImpl"); + // Use jOOQ-Reflect to access private field "mqClientInstance" from defaultMQAdminExtImpl return Reflect.on(defaultMQAdminExtImpl).get("mqClientInstance"); } - public static void createMQAdmin(GenericObjectPool mqAdminExtPool) { - try { - // Get the mqAdmin instance from the object pool - MQAdminExt mqAdminExt = mqAdminExtPool.borrowObject(); - MQ_ADMIN_EXT_THREAD_LOCAL.set(mqAdminExt); - } catch (Exception e) { - LOGGER.error("get mqAdmin from pool error", e); - } + /** + * Sets the MQAdminExt instance for the current thread. + * This method should be called by the aspect after borrowing an instance from the pool. + * + * @param mqAdminExt The MQAdminExt instance to set. + */ + public static void setCurrentMQAdminExt(MQAdminExt mqAdminExt) { + MQ_ADMIN_EXT_THREAD_LOCAL.set(mqAdminExt); + LOGGER.debug("Set MQAdminExt instance for current thread: {}", mqAdminExt); } - public static void returnMQAdmin(GenericObjectPool mqAdminExtPool) { - MQAdminExt mqAdminExt = MQ_ADMIN_EXT_THREAD_LOCAL.get(); - if (mqAdminExt != null) { - try { - // After execution, return the mqAdmin instance to the object pool - mqAdminExtPool.returnObject(mqAdminExt); - } catch (Exception e) { - LOGGER.error("return mqAdmin to pool error", e); - } - } + /** + * Clears the MQAdminExt instance from the current thread. + * This method should be called by the aspect after returning the instance to the pool. + */ + public static void clearCurrentMQAdminExt() { MQ_ADMIN_EXT_THREAD_LOCAL.remove(); + LOGGER.debug("Cleared MQAdminExt instance from current thread."); } + } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/client/ProxyAdminImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/client/ProxyAdminImpl.java index eadae12..afe8a11 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/client/ProxyAdminImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/client/ProxyAdminImpl.java @@ -17,7 +17,6 @@ package org.apache.rocketmq.dashboard.service.client; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.rocketmq.client.exception.MQBrokerException; import org.apache.rocketmq.remoting.RemotingClient; import org.apache.rocketmq.remoting.exception.RemotingConnectException; @@ -26,8 +25,6 @@ import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; import org.apache.rocketmq.remoting.protocol.RemotingCommand; import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection; import org.apache.rocketmq.remoting.protocol.header.GetConsumerConnectionListRequestHeader; -import org.apache.rocketmq.tools.admin.MQAdminExt; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import static org.apache.rocketmq.remoting.protocol.RequestCode.GET_CONSUMER_CONNECTION_LIST; @@ -35,13 +32,10 @@ import static org.apache.rocketmq.remoting.protocol.RequestCode.GET_CONSUMER_CON @Slf4j @Service public class ProxyAdminImpl implements ProxyAdmin { - @Autowired - private GenericObjectPool mqAdminExtPool; @Override public ConsumerConnection examineConsumerConnectionInfo(String addr, String consumerGroup) throws RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException, InterruptedException, MQBrokerException { try { - MQAdminInstance.createMQAdmin(mqAdminExtPool); RemotingClient remotingClient = MQAdminInstance.threadLocalRemotingClient(); GetConsumerConnectionListRequestHeader requestHeader = new GetConsumerConnectionListRequestHeader(); requestHeader.setConsumerGroup(consumerGroup); @@ -53,8 +47,9 @@ public class ProxyAdminImpl implements ProxyAdmin { default: throw new MQBrokerException(response.getCode(), response.getRemark(), addr); } - } finally { - MQAdminInstance.returnMQAdmin(mqAdminExtPool); + } catch (Exception e) { + log.error("examineConsumerConnectionInfo error", e); + throw e; } } } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/AbstractFileStore.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/AbstractFileStore.java index 045b990..0d65ae1 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/AbstractFileStore.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/AbstractFileStore.java @@ -16,14 +16,15 @@ */ package org.apache.rocketmq.dashboard.service.impl; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.srvutil.FileWatchService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + public abstract class AbstractFileStore { public final Logger log = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/AclServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/AclServiceImpl.java index 0c0177f..d123013 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/AclServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/AclServiceImpl.java @@ -14,357 +14,266 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.rocketmq.dashboard.service.impl; -import com.google.common.base.Throwables; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.client.exception.MQBrokerException; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.common.AclConfig; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.common.PlainAccessConfig; -import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; -import org.apache.rocketmq.remoting.protocol.route.BrokerData; -import org.apache.rocketmq.dashboard.model.request.AclRequest; -import org.apache.rocketmq.dashboard.service.AbstractCommonService; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.rocketmq.dashboard.config.RMQConfigure; +import org.apache.rocketmq.dashboard.model.Entry; +import org.apache.rocketmq.dashboard.model.Policy; +import org.apache.rocketmq.dashboard.model.PolicyRequest; +import org.apache.rocketmq.dashboard.model.request.UserInfoParam; import org.apache.rocketmq.dashboard.service.AclService; -import org.apache.rocketmq.remoting.exception.RemotingConnectException; -import org.apache.rocketmq.remoting.exception.RemotingException; -import org.apache.rocketmq.remoting.exception.RemotingSendRequestException; -import org.apache.rocketmq.remoting.exception.RemotingTimeoutException; +import org.apache.rocketmq.dashboard.service.ClusterInfoService; +import org.apache.rocketmq.remoting.protocol.body.AclInfo; +import org.apache.rocketmq.remoting.protocol.body.UserInfo; +import org.apache.rocketmq.tools.admin.MQAdminExt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + @Service -@Slf4j -public class AclServiceImpl extends AbstractCommonService implements AclService { +public class AclServiceImpl implements AclService { + + private Logger logger = LoggerFactory.getLogger(AclServiceImpl.class); + + + @Autowired + private MQAdminExt mqAdminExt; + + @Autowired + private RMQConfigure rmqConfigure; + + @Autowired + private ClusterInfoService clusterInfoService; + + private static final String DEFAULT_BROKER_ADDRESS = "localhost:10911"; @Override - public AclConfig getAclConfig(boolean excludeSecretKey) { + public List listUsers(String brokerAddress) { + List userList; try { - Optional addr = getMasterSet().stream().findFirst(); - if (addr.isPresent()) { - if (!excludeSecretKey) { - return mqAdminExt.examineBrokerClusterAclConfig(addr.get()); - } else { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr.get()); - if (CollectionUtils.isNotEmpty(aclConfig.getPlainAccessConfigs())) { - aclConfig.getPlainAccessConfigs().forEach(pac -> pac.setSecretKey(null)); - } - return aclConfig; - } - } - } catch (Exception e) { - log.error("getAclConfig error.", e); - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); + String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; + userList = mqAdminExt.listUser(address, ""); + } catch (Exception ex) { + logger.error("Failed to list users from broker: {}", brokerAddress, ex); + throw new RuntimeException("Failed to list users", ex); } - AclConfig aclConfig = new AclConfig(); - aclConfig.setGlobalWhiteAddrs(Collections.emptyList()); - aclConfig.setPlainAccessConfigs(Collections.emptyList()); - return aclConfig; + if (userList == null || userList.isEmpty()) { + logger.warn("No users found for broker: {}", brokerAddress); + return new ArrayList<>(); + } + return userList; } @Override - public void addAclConfig(PlainAccessConfig config) { + public Object listAcls(String brokerAddress, String searchParam) { + List aclList; try { - Set masterSet = getMasterSet(); - - if (masterSet.isEmpty()) { - throw new IllegalStateException("broker addr list is empty"); + String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; + String user = searchParam != null ? searchParam : ""; + String res = searchParam != null ? searchParam : ""; + aclList = mqAdminExt.listAcl(address, user, ""); + if (aclList == null) { + aclList = new ArrayList<>(); } - // check to see if account is exists - for (String addr : masterSet) { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr); - List plainAccessConfigs = aclConfig.getPlainAccessConfigs(); - for (PlainAccessConfig pac : plainAccessConfigs) { - if (pac.getAccessKey().equals(config.getAccessKey())) { - throw new IllegalArgumentException(String.format("broker: %s, exist accessKey: %s", addr, config.getAccessKey())); - } - } + List resAclList = mqAdminExt.listAcl(address, "", res); + if (resAclList != null) { + aclList.addAll(resAclList); } - - // all broker - for (String addr : getBrokerAddrs()) { - mqAdminExt.createAndUpdatePlainAccessConfig(addr, config); - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); + } catch (Exception ex) { + logger.error("Failed to list ACLs from broker: {}", brokerAddress, ex); + throw new RuntimeException("Failed to list ACLs", ex); } + ObjectMapper mapper = new ObjectMapper(); + Set uniqueAclStrings = new HashSet<>(); + List resultAclList = new ArrayList<>(); + for (AclInfo acl : aclList) { + try { + String aclString = mapper.writeValueAsString(acl); + if (uniqueAclStrings.add(aclString)) { + resultAclList.add(acl); + } + } catch (Exception e) { + logger.error("Error serializing AclInfo", e); + } + } + return resultAclList; } @Override - public void deleteAclConfig(PlainAccessConfig config) { - try { - for (String addr : getBrokerAddrs()) { - log.info("Start to delete acl [{}] from broker [{}]", config.getAccessKey(), addr); - if (isExistAccessKey(config.getAccessKey(), addr)) { - mqAdminExt.deletePlainAccessConfig(addr, config.getAccessKey()); - } - log.info("Delete acl [{}] from broker [{}] complete", config.getAccessKey(), addr); - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } + public List createAcl(PolicyRequest policyRequest) { + List successfulResources = new ArrayList<>(); - @Override - public void updateAclConfig(PlainAccessConfig config) { - try { - for (String addr : getBrokerAddrs()) { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr); - if (aclConfig.getPlainAccessConfigs() != null) { - PlainAccessConfig remoteConfig = null; - for (PlainAccessConfig pac : aclConfig.getPlainAccessConfigs()) { - if (pac.getAccessKey().equals(config.getAccessKey())) { - remoteConfig = pac; - break; - } - } - if (remoteConfig != null) { - remoteConfig.setSecretKey(config.getSecretKey()); - remoteConfig.setAdmin(config.isAdmin()); - config = remoteConfig; - } - } - mqAdminExt.createAndUpdatePlainAccessConfig(addr, config); - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); + if (policyRequest == null || policyRequest.getPolicies() == null || policyRequest.getPolicies().isEmpty()) { + logger.warn("Policy request is null or policies list is empty. No ACLs to create."); + return successfulResources; } - } - @Override - public void addOrUpdateAclTopicConfig(AclRequest request) { - try { - PlainAccessConfig addConfig = request.getConfig(); - for (String addr : getBrokerAddrs()) { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr); - PlainAccessConfig remoteConfig = null; - if (aclConfig.getPlainAccessConfigs() != null) { - for (PlainAccessConfig config : aclConfig.getPlainAccessConfigs()) { - if (config.getAccessKey().equals(addConfig.getAccessKey())) { - remoteConfig = config; - break; + String brokerAddress = policyRequest.getBrokerAddress() != null && !policyRequest.getBrokerAddress().isEmpty() ? + policyRequest.getBrokerAddress() : DEFAULT_BROKER_ADDRESS; + String subject = policyRequest.getSubject(); + + if (subject == null || subject.isEmpty()) { + throw new IllegalArgumentException("Subject cannot be null or empty."); + } + + for (Policy policy : policyRequest.getPolicies()) { + if (policy.getEntries() != null && !policy.getEntries().isEmpty()) { + for (Entry entry : policy.getEntries()) { + if (entry.getResource() != null && !entry.getResource().isEmpty()) { + for (String resource : entry.getResource()) { + AclInfo aclInfo = new AclInfo(); + List aclPolicies = new ArrayList<>(); + AclInfo.PolicyInfo policyInfo = new AclInfo.PolicyInfo(); + List entries = new ArrayList<>(); + AclInfo.PolicyEntryInfo entryInfo = new AclInfo.PolicyEntryInfo(); + + entryInfo.setActions(entry.getActions()); + entryInfo.setDecision(entry.getDecision()); + entryInfo.setResource(resource); + entryInfo.setSourceIps(entry.getSourceIps()); + entries.add(entryInfo); + + policyInfo.setEntries(entries); + policyInfo.setPolicyType(policy.getPolicyType()); + aclPolicies.add(policyInfo); + + aclInfo.setPolicies(aclPolicies); + aclInfo.setSubject(subject); + + try { + logger.info("Attempting to create ACL for subject: {}, resource: {} on broker: {}", subject, resource, brokerAddress); + mqAdminExt.createAcl(brokerAddress, aclInfo); + successfulResources.add(resource); + logger.info("Successfully created ACL for subject: {}, resource: {}", subject, resource); + } catch (Exception ex) { + logger.error("Failed to create ACL for subject: {}, resource: {} on broker: {}", subject, resource, brokerAddress, ex); + throw new RuntimeException("Failed to create ACL", ex); + } } } } - if (remoteConfig == null) { - // Maybe the broker no acl config of the access key, therefore add it; - mqAdminExt.createAndUpdatePlainAccessConfig(addr, addConfig); - } else { - if (remoteConfig.getTopicPerms() == null) { - remoteConfig.setTopicPerms(new ArrayList<>()); - } - removeExist(remoteConfig.getTopicPerms(), request.getTopicPerm().split("=")[0]); - remoteConfig.getTopicPerms().add(request.getTopicPerm()); - mqAdminExt.createAndUpdatePlainAccessConfig(addr, remoteConfig); - } } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); + } + return successfulResources; + } + + @Override + public void deleteUser(String brokerAddress, String username) { + try { + String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; + mqAdminExt.deleteUser(address, username); + } catch (Exception ex) { + logger.error("Failed to delete user: {} from broker: {}", username, brokerAddress, ex); + throw new RuntimeException("Failed to delete user", ex); } } @Override - public void addOrUpdateAclGroupConfig(AclRequest request) { + public void updateUser(String brokerAddress, UserInfoParam userParam) { + UserInfo user = new UserInfo(); + user.setUsername(userParam.getUsername()); + user.setPassword(userParam.getPassword()); + user.setUserStatus(userParam.getUserStatus()); + user.setUserType(userParam.getUserType()); + try { - PlainAccessConfig addConfig = request.getConfig(); - for (String addr : getBrokerAddrs()) { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr); - PlainAccessConfig remoteConfig = null; - if (aclConfig.getPlainAccessConfigs() != null) { - for (PlainAccessConfig config : aclConfig.getPlainAccessConfigs()) { - if (config.getAccessKey().equals(addConfig.getAccessKey())) { - remoteConfig = config; - break; + String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; + mqAdminExt.updateUser(address, user); + } catch (Exception ex) { + logger.error("Failed to update user: {} on broker: {}", userParam.getUsername(), brokerAddress, ex); + throw new RuntimeException("Failed to update user", ex); + } + } + + @Override + public void createUser(String brokerAddress, UserInfoParam userParam) { + UserInfo user = new UserInfo(); + user.setUsername(userParam.getUsername()); + user.setPassword(userParam.getPassword()); + user.setUserStatus(userParam.getUserStatus()); + user.setUserType(userParam.getUserType()); + try { + String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; + mqAdminExt.createUser(address, user); + } catch (Exception ex) { + logger.error("Failed to create user: {} on broker: {}", userParam.getUsername(), brokerAddress, ex); + throw new RuntimeException("Failed to create user", ex); + } + } + + @Override + public void deleteAcl(String brokerAddress, String subject, String resource) { + try { + String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; + String res = resource != null ? resource : ""; + mqAdminExt.deleteAcl(address, subject, res); + } catch (Exception ex) { + logger.error("Failed to delete ACL for subject: {} and resource: {} on broker: {}", subject, resource, brokerAddress, ex); + throw new RuntimeException("Failed to delete ACL", ex); + } + } + + @Override + public void updateAcl(PolicyRequest policyRequest) { + + if (policyRequest == null || policyRequest.getPolicies() == null || policyRequest.getPolicies().isEmpty()) { + logger.warn("Policy request is null or policies list is empty. No ACLs to update."); + } + + String brokerAddress = policyRequest.getBrokerAddress() != null && !policyRequest.getBrokerAddress().isEmpty() ? + policyRequest.getBrokerAddress() : DEFAULT_BROKER_ADDRESS; + String subject = policyRequest.getSubject(); + + if (subject == null || subject.isEmpty()) { + throw new IllegalArgumentException("Subject cannot be null or empty."); + } + + for (Policy policy : policyRequest.getPolicies()) { + if (policy.getEntries() != null && !policy.getEntries().isEmpty()) { + for (Entry entry : policy.getEntries()) { + if (entry.getResource() != null && !entry.getResource().isEmpty()) { + for (String resource : entry.getResource()) { + AclInfo aclInfo = new AclInfo(); + List aclPolicies = new ArrayList<>(); + AclInfo.PolicyInfo policyInfo = new AclInfo.PolicyInfo(); + List entries = new ArrayList<>(); + AclInfo.PolicyEntryInfo entryInfo = new AclInfo.PolicyEntryInfo(); + + entryInfo.setActions(entry.getActions()); + entryInfo.setDecision(entry.getDecision()); + entryInfo.setResource(resource); + entryInfo.setSourceIps(entry.getSourceIps()); + entries.add(entryInfo); + + policyInfo.setEntries(entries); + policyInfo.setPolicyType(policy.getPolicyType()); + aclPolicies.add(policyInfo); + + aclInfo.setPolicies(aclPolicies); + aclInfo.setSubject(subject); + + try { + String address = brokerAddress != null && !brokerAddress.isEmpty() ? brokerAddress : DEFAULT_BROKER_ADDRESS; + mqAdminExt.updateAcl(address, aclInfo); + } catch (Exception ex) { + logger.error("Failed to update ACL for subject: {} on broker: {}", subject, brokerAddress, ex); + throw new RuntimeException("Failed to update ACL", ex); + } } } } - if (remoteConfig == null) { - // May be the broker no acl config of the access key, therefore add it; - mqAdminExt.createAndUpdatePlainAccessConfig(addr, addConfig); - } else { - if (remoteConfig.getGroupPerms() == null) { - remoteConfig.setGroupPerms(new ArrayList<>()); - } - removeExist(remoteConfig.getGroupPerms(), request.getGroupPerm().split("=")[0]); - remoteConfig.getGroupPerms().add(request.getGroupPerm()); - mqAdminExt.createAndUpdatePlainAccessConfig(addr, remoteConfig); - } - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } - - @Override - public void deletePermConfig(AclRequest request) { - try { - PlainAccessConfig deleteConfig = request.getConfig(); - - String topic = StringUtils.isNotEmpty(request.getTopicPerm()) ? request.getTopicPerm().split("=")[0] : null; - String group = StringUtils.isNotEmpty(request.getGroupPerm()) ? request.getGroupPerm().split("=")[0] : null; - if (deleteConfig.getTopicPerms() != null && topic != null) { - removeExist(deleteConfig.getTopicPerms(), topic); - } - if (deleteConfig.getGroupPerms() != null && group != null) { - removeExist(deleteConfig.getGroupPerms(), group); - } - - for (String addr : getBrokerAddrs()) { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr); - PlainAccessConfig remoteConfig = null; - if (aclConfig.getPlainAccessConfigs() != null) { - for (PlainAccessConfig config : aclConfig.getPlainAccessConfigs()) { - if (config.getAccessKey().equals(deleteConfig.getAccessKey())) { - remoteConfig = config; - break; - } - } - } - if (remoteConfig == null) { - // Maybe the broker no acl config of the access key, therefore add it; - mqAdminExt.createAndUpdatePlainAccessConfig(addr, deleteConfig); - } else { - if (remoteConfig.getTopicPerms() != null && topic != null) { - removeExist(remoteConfig.getTopicPerms(), topic); - } - if (remoteConfig.getGroupPerms() != null && group != null) { - removeExist(remoteConfig.getGroupPerms(), group); - } - mqAdminExt.createAndUpdatePlainAccessConfig(addr, remoteConfig); - } - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - - } - - @Override - public void syncData(PlainAccessConfig config) { - try { - for (String addr : getBrokerAddrs()) { - mqAdminExt.createAndUpdatePlainAccessConfig(addr, config); - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } - - @Override - public void addWhiteList(List whiteList) { - if (whiteList == null) { - return; - } - try { - for (String addr : getBrokerAddrs()) { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr); - if (aclConfig.getGlobalWhiteAddrs() != null) { - aclConfig.setGlobalWhiteAddrs(Stream.of(whiteList, aclConfig.getGlobalWhiteAddrs()).flatMap(Collection::stream).distinct().collect(Collectors.toList())); - } else { - aclConfig.setGlobalWhiteAddrs(whiteList); - } - mqAdminExt.updateGlobalWhiteAddrConfig(addr, StringUtils.join(aclConfig.getGlobalWhiteAddrs(), ",")); - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } - - @Override - public void deleteWhiteAddr(String deleteAddr) { - try { - for (String addr : getBrokerAddrs()) { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr); - if (aclConfig.getGlobalWhiteAddrs() == null || aclConfig.getGlobalWhiteAddrs().isEmpty()) { - continue; - } - aclConfig.getGlobalWhiteAddrs().remove(deleteAddr); - mqAdminExt.updateGlobalWhiteAddrConfig(addr, StringUtils.join(aclConfig.getGlobalWhiteAddrs(), ",")); - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } - - @Override - public void synchronizeWhiteList(List whiteList) { - if (whiteList == null) { - return; - } - try { - for (String addr : getBrokerAddrs()) { - mqAdminExt.updateGlobalWhiteAddrConfig(addr, StringUtils.join(whiteList, ",")); - } - } catch (Exception e) { - Throwables.throwIfUnchecked(e); - throw new RuntimeException(e); - } - } - - private void removeExist(List list, String name) { - Iterator iterator = list.iterator(); - while (iterator.hasNext()) { - String v = iterator.next(); - String cmp = v.split("=")[0]; - if (cmp.equals(name)) { - iterator.remove(); } } + } - private boolean isExistAccessKey(String accessKey, - String addr) throws InterruptedException, RemotingException, MQClientException, MQBrokerException { - AclConfig aclConfig = mqAdminExt.examineBrokerClusterAclConfig(addr); - List plainAccessConfigs = aclConfig.getPlainAccessConfigs(); - if (plainAccessConfigs == null || plainAccessConfigs.isEmpty()) { - return false; - } - for (PlainAccessConfig config : plainAccessConfigs) { - if (accessKey.equals(config.getAccessKey())) { - return true; - } - } - return false; - } - - private Set getBrokerDataSet() throws InterruptedException, RemotingConnectException, RemotingTimeoutException, RemotingSendRequestException, MQBrokerException { - ClusterInfo clusterInfo = mqAdminExt.examineBrokerClusterInfo(); - Map brokerDataMap = clusterInfo.getBrokerAddrTable(); - return new HashSet<>(brokerDataMap.values()); - } - - private Set getMasterSet() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException { - return getBrokerDataSet().stream().map(data -> data.getBrokerAddrs().get(MixAll.MASTER_ID)).collect(Collectors.toSet()); - } - - private Set getBrokerAddrs() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException { - Set brokerAddrs = new HashSet<>(); - getBrokerDataSet().forEach(data -> brokerAddrs.addAll(data.getBrokerAddrs().values())); - return brokerAddrs; - } } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/ClusterServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/ClusterServiceImpl.java index 12e7f71..12886d7 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/ClusterServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/ClusterServiceImpl.java @@ -17,20 +17,20 @@ package org.apache.rocketmq.dashboard.service.impl; +import com.google.common.base.Throwables; +import com.google.common.collect.Maps; +import jakarta.annotation.Resource; import org.apache.rocketmq.common.attribute.TopicMessageType; +import org.apache.rocketmq.dashboard.service.ClusterService; +import org.apache.rocketmq.dashboard.util.JsonUtil; import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; import org.apache.rocketmq.remoting.protocol.body.KVTable; import org.apache.rocketmq.remoting.protocol.route.BrokerData; import org.apache.rocketmq.tools.admin.MQAdminExt; -import org.apache.rocketmq.dashboard.service.ClusterService; -import org.apache.rocketmq.dashboard.util.JsonUtil; -import com.google.common.base.Throwables; -import com.google.common.collect.Maps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import javax.annotation.Resource; import java.util.Arrays; import java.util.Map; import java.util.Properties; @@ -61,10 +61,9 @@ public class ClusterServiceImpl implements ClusterService { resultMap.put("brokerServer", brokerServer); // add messageType resultMap.put("messageTypes", Arrays.stream(TopicMessageType.values()).sorted() - .collect(Collectors.toMap(TopicMessageType::getValue, messageType ->String.format("MESSAGE_TYPE_%s",messageType.getValue())))); + .collect(Collectors.toMap(TopicMessageType::getValue, messageType -> String.format("MESSAGE_TYPE_%s", messageType.getValue())))); return resultMap; - } - catch (Exception err) { + } catch (Exception err) { Throwables.throwIfUnchecked(err); throw new RuntimeException(err); } @@ -73,12 +72,16 @@ public class ClusterServiceImpl implements ClusterService { @Override public Properties getBrokerConfig(String brokerAddr) { + Properties properties = null; try { - return mqAdminExt.getBrokerConfig(brokerAddr); - } - catch (Exception e) { + properties = mqAdminExt.getBrokerConfig(brokerAddr); + if (properties == null) { + throw new RuntimeException("get broker config failed, brokerAddr:" + brokerAddr); + } + } catch (Exception e) { Throwables.throwIfUnchecked(e); throw new RuntimeException(e); } + return properties; } } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/ConsumerServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/ConsumerServiceImpl.java index a91cbeb..ab61a71 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/ConsumerServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/ConsumerServiceImpl.java @@ -23,7 +23,43 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; - +import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.rocketmq.client.exception.MQClientException; +import org.apache.rocketmq.common.MQVersion; +import org.apache.rocketmq.common.MixAll; +import org.apache.rocketmq.common.message.MessageQueue; +import org.apache.rocketmq.common.utils.ThreadUtils; +import org.apache.rocketmq.dashboard.config.RMQConfigure; +import org.apache.rocketmq.dashboard.model.ConsumerGroupRollBackStat; +import org.apache.rocketmq.dashboard.model.GroupConsumeInfo; +import org.apache.rocketmq.dashboard.model.QueueStatInfo; +import org.apache.rocketmq.dashboard.model.TopicConsumerInfo; +import org.apache.rocketmq.dashboard.model.request.ConsumerConfigInfo; +import org.apache.rocketmq.dashboard.model.request.DeleteSubGroupRequest; +import org.apache.rocketmq.dashboard.model.request.ResetOffsetRequest; +import org.apache.rocketmq.dashboard.service.AbstractCommonService; +import org.apache.rocketmq.dashboard.service.ClusterInfoService; +import org.apache.rocketmq.dashboard.service.ConsumerService; +import org.apache.rocketmq.dashboard.service.client.ProxyAdmin; +import org.apache.rocketmq.remoting.protocol.ResponseCode; +import org.apache.rocketmq.remoting.protocol.admin.ConsumeStats; +import org.apache.rocketmq.remoting.protocol.admin.RollbackStats; +import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; +import org.apache.rocketmq.remoting.protocol.body.Connection; +import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection; +import org.apache.rocketmq.remoting.protocol.body.ConsumerRunningInfo; +import org.apache.rocketmq.remoting.protocol.body.GroupList; +import org.apache.rocketmq.remoting.protocol.body.SubscriptionGroupWrapper; +import org.apache.rocketmq.remoting.protocol.route.BrokerData; +import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Arrays; @@ -44,44 +80,6 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; -import javax.annotation.Resource; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.rocketmq.client.exception.MQClientException; -import org.apache.rocketmq.common.MQVersion; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.dashboard.model.request.ConsumerConfigInfo; -import org.apache.rocketmq.dashboard.model.request.DeleteSubGroupRequest; -import org.apache.rocketmq.dashboard.model.request.ResetOffsetRequest; -import org.apache.rocketmq.dashboard.service.ClusterInfoService; -import org.apache.rocketmq.dashboard.service.client.ProxyAdmin; -import org.apache.rocketmq.remoting.protocol.admin.ConsumeStats; -import org.apache.rocketmq.remoting.protocol.admin.RollbackStats; -import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.remoting.protocol.ResponseCode; -import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; -import org.apache.rocketmq.remoting.protocol.body.Connection; -import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection; -import org.apache.rocketmq.remoting.protocol.body.ConsumerRunningInfo; -import org.apache.rocketmq.remoting.protocol.body.GroupList; -import org.apache.rocketmq.remoting.protocol.body.SubscriptionGroupWrapper; -import org.apache.rocketmq.remoting.protocol.route.BrokerData; -import org.apache.rocketmq.remoting.protocol.subscription.SubscriptionGroupConfig; -import org.apache.rocketmq.common.utils.ThreadUtils; -import org.apache.rocketmq.dashboard.config.RMQConfigure; -import org.apache.rocketmq.dashboard.model.ConsumerGroupRollBackStat; -import org.apache.rocketmq.dashboard.model.GroupConsumeInfo; -import org.apache.rocketmq.dashboard.model.QueueStatInfo; -import org.apache.rocketmq.dashboard.model.TopicConsumerInfo; -import org.apache.rocketmq.dashboard.service.AbstractCommonService; -import org.apache.rocketmq.dashboard.service.ConsumerService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; @Service public class ConsumerServiceImpl extends AbstractCommonService implements ConsumerService, InitializingBean, DisposableBean { @@ -180,7 +178,7 @@ public class ConsumerServiceImpl extends AbstractCommonService implements Consum try { ClusterInfo clusterInfo = clusterInfoService.get(); for (BrokerData brokerData : clusterInfo.getBrokerAddrTable().values()) { - subscriptionGroupWrapper = mqAdminExt.getAllSubscriptionGroup(brokerData.selectBrokerAddr(), 3000L); + subscriptionGroupWrapper = mqAdminExt.getAllSubscriptionGroup(brokerData.selectBrokerAddr(), 30000L); for (String groupName : subscriptionGroupWrapper.getSubscriptionGroupTable().keySet()) { if (!consumerGroupMap.containsKey(groupName)) { consumerGroupMap.putIfAbsent(groupName, new ArrayList<>()); diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/DashboardCollectServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/DashboardCollectServiceImpl.java index 75cebd4..f6c8f6b 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/DashboardCollectServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/DashboardCollectServiceImpl.java @@ -29,18 +29,19 @@ import com.google.common.cache.RemovalNotification; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.io.Files; -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Set; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.service.DashboardCollectService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + @Service public class DashboardCollectServiceImpl implements DashboardCollectService { diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/DashboardServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/DashboardServiceImpl.java index b2885e4..ae8c31d 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/DashboardServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/DashboardServiceImpl.java @@ -18,15 +18,16 @@ package org.apache.rocketmq.dashboard.service.impl; import com.google.common.collect.Lists; +import jakarta.annotation.Resource; +import org.apache.rocketmq.dashboard.service.DashboardCollectService; +import org.apache.rocketmq.dashboard.service.DashboardService; +import org.springframework.stereotype.Service; + import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; -import javax.annotation.Resource; -import org.apache.rocketmq.dashboard.service.DashboardCollectService; -import org.apache.rocketmq.dashboard.service.DashboardService; -import org.springframework.stereotype.Service; @Service public class DashboardServiceImpl implements DashboardService { diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/DlqMessageServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/DlqMessageServiceImpl.java index 4d3c3f7..e21ff00 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/DlqMessageServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/DlqMessageServiceImpl.java @@ -18,27 +18,28 @@ package org.apache.rocketmq.dashboard.service.impl; import com.google.common.base.Throwables; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.client.exception.MQClientException; import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.remoting.protocol.ResponseCode; -import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; -import org.apache.rocketmq.dashboard.model.DlqMessageResendResult; import org.apache.rocketmq.dashboard.model.DlqMessageRequest; +import org.apache.rocketmq.dashboard.model.DlqMessageResendResult; import org.apache.rocketmq.dashboard.model.MessagePage; import org.apache.rocketmq.dashboard.model.MessageView; import org.apache.rocketmq.dashboard.model.request.MessageQuery; import org.apache.rocketmq.dashboard.service.DlqMessageService; import org.apache.rocketmq.dashboard.service.MessageService; +import org.apache.rocketmq.remoting.protocol.ResponseCode; +import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; import org.apache.rocketmq.tools.admin.MQAdminExt; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + @Service @Slf4j public class DlqMessageServiceImpl implements DlqMessageService { diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/LoginServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/LoginServiceImpl.java index c4a07c9..7358382 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/LoginServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/LoginServiceImpl.java @@ -17,18 +17,21 @@ package org.apache.rocketmq.dashboard.service.impl; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.service.LoginService; import org.apache.rocketmq.dashboard.service.UserService; +import org.apache.rocketmq.dashboard.service.provider.UserInfoProvider; +import org.apache.rocketmq.dashboard.util.UserInfoContext; import org.apache.rocketmq.dashboard.util.WebUtil; +import org.apache.rocketmq.remoting.protocol.body.UserInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -43,13 +46,21 @@ public class LoginServiceImpl implements LoginService { @Autowired private UserService userService; + @Autowired + private UserInfoProvider userInfoProvider; + @Override public boolean login(HttpServletRequest request, HttpServletResponse response) { - if (WebUtil.getValueFromSession(request, WebUtil.USER_NAME) != null) { + String username = (String) WebUtil.getValueFromSession(request, WebUtil.USER_NAME); + if (username != null) { + UserInfo userInfo = userInfoProvider.getUserInfoByUsername(username); + if (userInfo == null) { + return false; + } + UserInfoContext.set(WebUtil.USER_NAME, userInfo); return true; } - auth(request, response); return false; } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/MessageServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/MessageServiceImpl.java index 0586447..584ba10 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/MessageServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/MessageServiceImpl.java @@ -25,6 +25,7 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import jakarta.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.acl.common.AclClientRPCHook; import org.apache.rocketmq.acl.common.SessionCredentials; @@ -37,20 +38,20 @@ import org.apache.rocketmq.common.Pair; import org.apache.rocketmq.common.message.MessageClientIDSetter; import org.apache.rocketmq.common.message.MessageExt; import org.apache.rocketmq.common.message.MessageQueue; -import org.apache.rocketmq.dashboard.support.AutoCloseConsumerWrapper; -import org.apache.rocketmq.remoting.protocol.body.Connection; -import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; -import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.exception.ServiceException; -import org.apache.rocketmq.dashboard.model.QueueOffsetInfo; -import org.apache.rocketmq.dashboard.model.MessageView; import org.apache.rocketmq.dashboard.model.MessagePage; import org.apache.rocketmq.dashboard.model.MessagePageTask; import org.apache.rocketmq.dashboard.model.MessageQueryByPage; +import org.apache.rocketmq.dashboard.model.MessageView; +import org.apache.rocketmq.dashboard.model.QueueOffsetInfo; import org.apache.rocketmq.dashboard.model.request.MessageQuery; import org.apache.rocketmq.dashboard.service.MessageService; +import org.apache.rocketmq.dashboard.support.AutoCloseConsumerWrapper; import org.apache.rocketmq.remoting.RPCHook; +import org.apache.rocketmq.remoting.protocol.body.Connection; +import org.apache.rocketmq.remoting.protocol.body.ConsumeMessageDirectlyResult; +import org.apache.rocketmq.remoting.protocol.body.ConsumerConnection; import org.apache.rocketmq.tools.admin.MQAdminExt; import org.apache.rocketmq.tools.admin.api.MessageTrack; import org.slf4j.Logger; @@ -60,14 +61,13 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import java.util.Collections; -import java.util.List; -import java.util.Comparator; import java.util.ArrayList; -import java.util.Set; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.Date; +import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/MessageTraceServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/MessageTraceServiceImpl.java index 89468cd..b07025c 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/MessageTraceServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/MessageTraceServiceImpl.java @@ -19,14 +19,8 @@ package org.apache.rocketmq.dashboard.service.impl; import com.google.common.base.Function; import com.google.common.collect.Lists; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import javax.annotation.Resource; - import com.google.common.collect.Maps; +import jakarta.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.client.trace.TraceType; import org.apache.rocketmq.common.Pair; @@ -35,11 +29,11 @@ import org.apache.rocketmq.common.topic.TopicValidator; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.exception.ServiceException; import org.apache.rocketmq.dashboard.model.MessageTraceView; -import org.apache.rocketmq.dashboard.model.trace.ProducerNode; import org.apache.rocketmq.dashboard.model.trace.MessageTraceGraph; +import org.apache.rocketmq.dashboard.model.trace.MessageTraceStatusEnum; +import org.apache.rocketmq.dashboard.model.trace.ProducerNode; import org.apache.rocketmq.dashboard.model.trace.SubscriptionNode; import org.apache.rocketmq.dashboard.model.trace.TraceNode; -import org.apache.rocketmq.dashboard.model.trace.MessageTraceStatusEnum; import org.apache.rocketmq.dashboard.service.MessageTraceService; import org.apache.rocketmq.tools.admin.MQAdminExt; import org.slf4j.Logger; @@ -48,6 +42,11 @@ import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + @Service public class MessageTraceServiceImpl implements MessageTraceService { diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/MonitorServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/MonitorServiceImpl.java index d0e44c3..3bdd98e 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/MonitorServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/MonitorServiceImpl.java @@ -18,12 +18,8 @@ package org.apache.rocketmq.dashboard.service.impl; import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.base.Throwables; -import java.io.File; -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import javax.annotation.PostConstruct; -import javax.annotation.Resource; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; import org.apache.rocketmq.common.MixAll; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.model.ConsumerMonitorConfig; @@ -31,6 +27,11 @@ import org.apache.rocketmq.dashboard.service.MonitorService; import org.apache.rocketmq.dashboard.util.JsonUtil; import org.springframework.stereotype.Service; +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + @Service public class MonitorServiceImpl implements MonitorService { diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/OpsServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/OpsServiceImpl.java index 368df74..0857c0d 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/OpsServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/OpsServiceImpl.java @@ -17,9 +17,7 @@ package org.apache.rocketmq.dashboard.service.impl; import com.google.common.collect.Maps; -import java.util.List; -import java.util.Map; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.service.AbstractCommonService; @@ -30,6 +28,9 @@ import org.apache.rocketmq.tools.admin.MQAdminExt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Map; + @Service public class OpsServiceImpl extends AbstractCommonService implements OpsService { diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/PermissionServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/PermissionServiceImpl.java index 9f69fd0..2913391 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/PermissionServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/PermissionServiceImpl.java @@ -17,12 +17,7 @@ package org.apache.rocketmq.dashboard.service.impl; import com.alibaba.fastjson.JSONObject; -import java.io.FileReader; -import java.io.InputStream; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.exception.ServiceException; import org.apache.rocketmq.dashboard.model.UserInfo; @@ -32,6 +27,12 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; import org.yaml.snakeyaml.Yaml; +import java.io.FileReader; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import static org.apache.rocketmq.dashboard.permisssion.UserRoleEnum.ADMIN; import static org.apache.rocketmq.dashboard.permisssion.UserRoleEnum.ORDINARY; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/ProducerServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/ProducerServiceImpl.java index 5f5e491..85433f8 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/ProducerServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/ProducerServiceImpl.java @@ -18,9 +18,9 @@ package org.apache.rocketmq.dashboard.service.impl; import com.google.common.base.Throwables; -import javax.annotation.Resource; -import org.apache.rocketmq.remoting.protocol.body.ProducerConnection; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.service.ProducerService; +import org.apache.rocketmq.remoting.protocol.body.ProducerConnection; import org.apache.rocketmq.tools.admin.MQAdminExt; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/ProxyServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/ProxyServiceImpl.java index 07e63b3..52b4a44 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/ProxyServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/ProxyServiceImpl.java @@ -17,13 +17,13 @@ package org.apache.rocketmq.dashboard.service.impl; import com.google.common.collect.Maps; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.dashboard.config.RMQConfigure; import org.apache.rocketmq.dashboard.service.ProxyService; import org.apache.rocketmq.dashboard.service.client.ProxyAdmin; import org.springframework.stereotype.Service; -import javax.annotation.Resource; import java.util.List; import java.util.Map; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/TopicServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/TopicServiceImpl.java index 6d1abc9..a135dff 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/TopicServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/TopicServiceImpl.java @@ -25,10 +25,10 @@ import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.acl.common.AclClientRPCHook; import org.apache.rocketmq.acl.common.SessionCredentials; import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.apache.rocketmq.client.producer.LocalTransactionState; import org.apache.rocketmq.client.producer.SendResult; import org.apache.rocketmq.client.producer.TransactionListener; import org.apache.rocketmq.client.producer.TransactionMQProducer; -import org.apache.rocketmq.client.producer.LocalTransactionState; import org.apache.rocketmq.client.trace.TraceContext; import org.apache.rocketmq.client.trace.TraceDispatcher; import org.apache.rocketmq.common.MixAll; @@ -80,10 +80,6 @@ import static org.apache.rocketmq.common.TopicAttributes.TOPIC_MESSAGE_TYPE_ATTR @Service public class TopicServiceImpl extends AbstractCommonService implements TopicService { - private transient DefaultMQProducer systemTopicProducer; - - private final Object producerLock = new Object(); - private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); @Autowired @@ -92,6 +88,10 @@ public class TopicServiceImpl extends AbstractCommonService implements TopicServ private final ConcurrentMap routeCache = new ConcurrentHashMap<>(); private final Object cacheLock = new Object(); + private transient DefaultMQProducer systemTopicProducer; + + private final Object producerLock = new Object(); + @Autowired private RMQConfigure configure; diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/impl/UserServiceImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/impl/UserServiceImpl.java index 5e628e4..117f1d6 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/service/impl/UserServiceImpl.java +++ b/src/main/java/org/apache/rocketmq/dashboard/service/impl/UserServiceImpl.java @@ -17,102 +17,74 @@ package org.apache.rocketmq.dashboard.service.impl; +import jakarta.annotation.Resource; +import org.apache.rocketmq.auth.authentication.enums.UserType; +import org.apache.rocketmq.dashboard.admin.UserMQAdminPoolManager; import org.apache.rocketmq.dashboard.config.RMQConfigure; -import org.apache.rocketmq.dashboard.exception.ServiceException; import org.apache.rocketmq.dashboard.model.User; import org.apache.rocketmq.dashboard.service.UserService; -import org.springframework.beans.factory.InitializingBean; +import org.apache.rocketmq.dashboard.service.provider.UserInfoProvider; +import org.apache.rocketmq.logging.org.slf4j.Logger; +import org.apache.rocketmq.logging.org.slf4j.LoggerFactory; +import org.apache.rocketmq.remoting.protocol.body.UserInfo; +import org.apache.rocketmq.tools.admin.MQAdminExt; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import javax.validation.constraints.NotNull; -import java.io.FileReader; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; - @Service -public class UserServiceImpl implements UserService, InitializingBean { +public class UserServiceImpl implements UserService { + + private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class); + @Resource private RMQConfigure configure; - private FileBasedUserInfoStore fileBasedUserInfoStore; + @Autowired + private UserInfoProvider userInfoProvider; + + @Autowired + private UserMQAdminPoolManager userMQAdminPoolManager; + @Override public User queryByName(String name) { - return fileBasedUserInfoStore.queryByName(name); + UserInfo userInfo = userInfoProvider.getUserInfoByUsername(name); + if (userInfo == null) { + return null; + } + return new User(userInfo.getUsername(), userInfo.getPassword(), UserType.getByName(userInfo.getUserType()).getCode()); } @Override public User queryByUsernameAndPassword(String username, String password) { - return fileBasedUserInfoStore.queryByUsernameAndPassword(username, password); - } - - @Override - public void afterPropertiesSet() throws Exception { - if (configure.isLoginRequired()) { - fileBasedUserInfoStore = new FileBasedUserInfoStore(configure); - } - } - - public static class FileBasedUserInfoStore extends AbstractFileStore { - private static final String FILE_NAME = "users.properties"; - - private static Map userMap = new ConcurrentHashMap<>(); - - public FileBasedUserInfoStore(RMQConfigure configure) { - super(configure, FILE_NAME); - } - - @Override - public void load(InputStream inputStream) { - Properties prop = new Properties(); - try { - if (inputStream == null) { - prop.load(new FileReader(filePath)); - } else { - prop.load(inputStream); - } - } catch (Exception e) { - log.error("load user.properties failed", e); - throw new ServiceException(0, String.format("Failed to load loginUserInfo property file: %s", filePath)); - } - - Map loadUserMap = new HashMap<>(); - String[] arrs; - int role; - for (String key : prop.stringPropertyNames()) { - String v = prop.getProperty(key); - if (v == null) - continue; - arrs = v.split(",", 2); - if (arrs.length == 0) { - continue; - } else if (arrs.length == 1) { - role = 0; - } else { - role = Integer.parseInt(arrs[1].trim()); - } - - loadUserMap.put(key, new User(key, arrs[0].trim(), role)); - } - - userMap.clear(); - userMap.putAll(loadUserMap); - } - - public User queryByName(String name) { - return userMap.get(name); - } - - public User queryByUsernameAndPassword(@NotNull String username, @NotNull String password) { - User user = queryByName(username); - if (user != null && password.equals(user.getPassword())) { - return user.cloneOne(); - } + User user = queryByName(username); + if (user != null && !user.getPassword().equals(password)) { return null; } + + return user; } + + public MQAdminExt getMQAdminExtForUser(User user) throws Exception { + if (user == null) { + throw new IllegalArgumentException("User object cannot be null when requesting MQAdminExt."); + } + return userMQAdminPoolManager.borrowMQAdminExt(user.getName(), user.getPassword()); + } + + public void returnMQAdminExtForUser(User user, MQAdminExt mqAdminExt) { + if (user == null || mqAdminExt == null) { + log.warn("Attempted to return MQAdminExt with null user or mqAdminExt object."); + return; + } + userMQAdminPoolManager.returnMQAdminExt(user.getName(), mqAdminExt); + } + + public void onUserLogout(User user) { + if (user != null) { + userMQAdminPoolManager.shutdownUserPool(user.getName()); + log.info("User {} logged out, their MQAdminExt pool has been shut down.", user.getName()); + } + } + } diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/provider/UserInfoProvider.java b/src/main/java/org/apache/rocketmq/dashboard/service/provider/UserInfoProvider.java new file mode 100644 index 0000000..cc97aad --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/service/provider/UserInfoProvider.java @@ -0,0 +1,24 @@ +/* + * 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.rocketmq.dashboard.service.provider; + +import org.apache.rocketmq.remoting.protocol.body.UserInfo; + +public interface UserInfoProvider { + UserInfo getUserInfoByUsername(String username); +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/service/provider/UserInfoProviderImpl.java b/src/main/java/org/apache/rocketmq/dashboard/service/provider/UserInfoProviderImpl.java new file mode 100644 index 0000000..2e9d37a --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/service/provider/UserInfoProviderImpl.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.rocketmq.dashboard.service.provider; +import org.apache.rocketmq.dashboard.service.ClusterInfoService; +import org.apache.rocketmq.logging.org.slf4j.Logger; +import org.apache.rocketmq.logging.org.slf4j.LoggerFactory; +import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; +import org.apache.rocketmq.remoting.protocol.body.UserInfo; +import org.apache.rocketmq.remoting.protocol.route.BrokerData; +import org.apache.rocketmq.tools.admin.MQAdminExt; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + + +@Service +public class UserInfoProviderImpl implements UserInfoProvider { + + private static final Logger log = LoggerFactory.getLogger(UserInfoProviderImpl.class); + + @Autowired + private MQAdminExt mqAdminExt; + + @Autowired + private ClusterInfoService clusterInfoService; + + @Override + public UserInfo getUserInfoByUsername(String username) { + ClusterInfo clusterInfo = clusterInfoService.get(); + + if (clusterInfo == null || clusterInfo.getBrokerAddrTable() == null || clusterInfo.getBrokerAddrTable().isEmpty()) { + log.warn("Cluster information is not available or has no broker addresses."); + return null; + } + for (BrokerData brokerLiveInfo : clusterInfo.getBrokerAddrTable().values()) { + if (brokerLiveInfo == null || brokerLiveInfo.getBrokerAddrs() == null || brokerLiveInfo.getBrokerAddrs().isEmpty()) { + continue; + } + String brokerAddr = brokerLiveInfo.getBrokerAddrs().get(0L); // Assuming 0L is the primary address + if (brokerAddr == null) { + continue; + } + try { + UserInfo userInfo = mqAdminExt.getUser(brokerAddr, username); + if (userInfo != null) { + return userInfo; + } + } catch (Exception e) { + log.warn("Failed to get user {} from broker {}. Trying next broker if available. Error: {}", username, brokerAddr, e.getMessage()); + } + } + return null; + } +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/support/AutoCloseConsumerWrapper.java b/src/main/java/org/apache/rocketmq/dashboard/support/AutoCloseConsumerWrapper.java index 3617da8..ce2d034 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/support/AutoCloseConsumerWrapper.java +++ b/src/main/java/org/apache/rocketmq/dashboard/support/AutoCloseConsumerWrapper.java @@ -23,6 +23,7 @@ import org.apache.rocketmq.common.MixAll; import org.apache.rocketmq.remoting.RPCHook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import java.time.Duration; import java.time.Instant; import java.util.concurrent.Executors; @@ -49,7 +50,7 @@ public class AutoCloseConsumerWrapper { } - public DefaultMQPullConsumer getConsumer(RPCHook rpcHook,Boolean useTLS) { + public DefaultMQPullConsumer getConsumer(RPCHook rpcHook, Boolean useTLS) { lastUsedTime = Instant.now(); DefaultMQPullConsumer consumer = CONSUMER_REF.get(); @@ -57,7 +58,7 @@ public class AutoCloseConsumerWrapper { synchronized (this) { consumer = CONSUMER_REF.get(); if (consumer == null) { - consumer = createNewConsumer(rpcHook,useTLS); + consumer = createNewConsumer(rpcHook, useTLS); CONSUMER_REF.set(consumer); } try { diff --git a/src/main/java/org/apache/rocketmq/dashboard/support/GlobalExceptionHandler.java b/src/main/java/org/apache/rocketmq/dashboard/support/GlobalExceptionHandler.java index c7d915e..1b46da2 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/support/GlobalExceptionHandler.java +++ b/src/main/java/org/apache/rocketmq/dashboard/support/GlobalExceptionHandler.java @@ -17,7 +17,7 @@ package org.apache.rocketmq.dashboard.support; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import org.apache.rocketmq.dashboard.exception.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,4 +45,4 @@ public class GlobalExceptionHandler { } return value; } -} \ No newline at end of file +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/support/GlobalRestfulResponseBodyAdvice.java b/src/main/java/org/apache/rocketmq/dashboard/support/GlobalRestfulResponseBodyAdvice.java index fd27528..ec8dbef 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/support/GlobalRestfulResponseBodyAdvice.java +++ b/src/main/java/org/apache/rocketmq/dashboard/support/GlobalRestfulResponseBodyAdvice.java @@ -17,7 +17,6 @@ package org.apache.rocketmq.dashboard.support; -import java.lang.annotation.Annotation; import org.apache.rocketmq.dashboard.aspect.admin.annotation.OriginalControllerReturnValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +28,8 @@ import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; +import java.lang.annotation.Annotation; + @ControllerAdvice(basePackages = "org.apache.rocketmq.dashboard") public class GlobalRestfulResponseBodyAdvice implements ResponseBodyAdvice { diff --git a/src/main/java/org/apache/rocketmq/dashboard/task/CollectTaskRunnble.java b/src/main/java/org/apache/rocketmq/dashboard/task/CollectTaskRunnble.java index a5efa18..c0e5cc0 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/task/CollectTaskRunnble.java +++ b/src/main/java/org/apache/rocketmq/dashboard/task/CollectTaskRunnble.java @@ -18,21 +18,22 @@ package org.apache.rocketmq.dashboard.task; import com.google.common.base.Throwables; import com.google.common.collect.Lists; -import java.math.BigDecimal; -import java.util.Date; -import java.util.List; -import java.util.concurrent.ExecutionException; import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.common.MixAll; import org.apache.rocketmq.common.stats.Stats; +import org.apache.rocketmq.dashboard.service.DashboardCollectService; import org.apache.rocketmq.remoting.protocol.body.BrokerStatsData; import org.apache.rocketmq.remoting.protocol.body.GroupList; import org.apache.rocketmq.remoting.protocol.route.BrokerData; import org.apache.rocketmq.remoting.protocol.route.TopicRouteData; -import org.apache.rocketmq.dashboard.service.DashboardCollectService; import org.apache.rocketmq.tools.admin.MQAdminExt; import org.apache.rocketmq.tools.command.stats.StatsAllSubCommand; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutionException; + @Slf4j public class CollectTaskRunnble implements Runnable { diff --git a/src/main/java/org/apache/rocketmq/dashboard/task/DashboardCollectTask.java b/src/main/java/org/apache/rocketmq/dashboard/task/DashboardCollectTask.java index c9a870c..2691d7c 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/task/DashboardCollectTask.java +++ b/src/main/java/org/apache/rocketmq/dashboard/task/DashboardCollectTask.java @@ -21,6 +21,23 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.io.Files; +import jakarta.annotation.Resource; +import org.apache.rocketmq.common.MixAll; +import org.apache.rocketmq.common.topic.TopicValidator; +import org.apache.rocketmq.dashboard.config.RMQConfigure; +import org.apache.rocketmq.dashboard.service.ConsumerService; +import org.apache.rocketmq.dashboard.service.DashboardCollectService; +import org.apache.rocketmq.dashboard.util.JsonUtil; +import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; +import org.apache.rocketmq.remoting.protocol.body.KVTable; +import org.apache.rocketmq.remoting.protocol.body.TopicList; +import org.apache.rocketmq.remoting.protocol.route.BrokerData; +import org.apache.rocketmq.tools.admin.MQAdminExt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + import java.io.File; import java.io.IOException; import java.math.BigDecimal; @@ -32,22 +49,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; -import javax.annotation.Resource; -import org.apache.rocketmq.common.MixAll; -import org.apache.rocketmq.dashboard.service.ConsumerService; -import org.apache.rocketmq.remoting.protocol.body.ClusterInfo; -import org.apache.rocketmq.remoting.protocol.body.KVTable; -import org.apache.rocketmq.remoting.protocol.body.TopicList; -import org.apache.rocketmq.remoting.protocol.route.BrokerData; -import org.apache.rocketmq.common.topic.TopicValidator; -import org.apache.rocketmq.dashboard.config.RMQConfigure; -import org.apache.rocketmq.dashboard.service.DashboardCollectService; -import org.apache.rocketmq.dashboard.util.JsonUtil; -import org.apache.rocketmq.tools.admin.MQAdminExt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; @Component public class DashboardCollectTask { diff --git a/src/main/java/org/apache/rocketmq/dashboard/task/MonitorTask.java b/src/main/java/org/apache/rocketmq/dashboard/task/MonitorTask.java index 3c8a77e..e960c3e 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/task/MonitorTask.java +++ b/src/main/java/org/apache/rocketmq/dashboard/task/MonitorTask.java @@ -16,8 +16,7 @@ */ package org.apache.rocketmq.dashboard.task; -import java.util.Map; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import org.apache.rocketmq.dashboard.model.ConsumerMonitorConfig; import org.apache.rocketmq.dashboard.model.GroupConsumeInfo; import org.apache.rocketmq.dashboard.service.ConsumerService; @@ -27,6 +26,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; +import java.util.Map; + @Component public class MonitorTask { private Logger logger = LoggerFactory.getLogger(MonitorTask.class); diff --git a/src/main/java/org/apache/rocketmq/dashboard/util/ExcelUtil.java b/src/main/java/org/apache/rocketmq/dashboard/util/ExcelUtil.java index e95d165..58af614 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/util/ExcelUtil.java +++ b/src/main/java/org/apache/rocketmq/dashboard/util/ExcelUtil.java @@ -21,11 +21,12 @@ import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.poi.ss.usermodel.HorizontalAlignment; + import java.io.OutputStream; import java.net.URLEncoder; import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.apache.poi.ss.usermodel.HorizontalAlignment; public class ExcelUtil { diff --git a/src/main/java/org/apache/rocketmq/dashboard/util/JsonUtil.java b/src/main/java/org/apache/rocketmq/dashboard/util/JsonUtil.java index 6100275..6fdb9e0 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/util/JsonUtil.java +++ b/src/main/java/org/apache/rocketmq/dashboard/util/JsonUtil.java @@ -25,12 +25,13 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; import com.google.common.base.Strings; import com.google.common.base.Throwables; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.io.Writer; import java.text.SimpleDateFormat; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @SuppressWarnings("unchecked") public class JsonUtil { diff --git a/src/main/java/org/apache/rocketmq/dashboard/util/MsgTraceDecodeUtil.java b/src/main/java/org/apache/rocketmq/dashboard/util/MsgTraceDecodeUtil.java index db724b8..68ee352 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/util/MsgTraceDecodeUtil.java +++ b/src/main/java/org/apache/rocketmq/dashboard/util/MsgTraceDecodeUtil.java @@ -17,9 +17,6 @@ package org.apache.rocketmq.dashboard.util; -import java.util.ArrayList; -import java.util.List; - import org.apache.rocketmq.client.producer.LocalTransactionState; import org.apache.rocketmq.client.trace.TraceBean; import org.apache.rocketmq.client.trace.TraceConstants; @@ -29,6 +26,9 @@ import org.apache.rocketmq.common.message.MessageType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.List; + import static org.apache.rocketmq.client.trace.TraceType.Pub; public class MsgTraceDecodeUtil { diff --git a/src/main/java/org/apache/rocketmq/dashboard/util/UserInfoContext.java b/src/main/java/org/apache/rocketmq/dashboard/util/UserInfoContext.java new file mode 100644 index 0000000..a4d20a9 --- /dev/null +++ b/src/main/java/org/apache/rocketmq/dashboard/util/UserInfoContext.java @@ -0,0 +1,47 @@ +/* + * 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.rocketmq.dashboard.util; + +import java.util.HashMap; +import java.util.Map; + +public class UserInfoContext { + + private static final ThreadLocal> USER_THREAD_LOCAL = ThreadLocal.withInitial(HashMap::new); + + + public static void set(String key, Object value) { + USER_THREAD_LOCAL.get().put(key, value); + } + + + public static Object get(String key) { + return USER_THREAD_LOCAL.get().get(key); + } + + + public static Map getAll() { + return new HashMap<>(USER_THREAD_LOCAL.get()); + } + + + public static void clear() { + USER_THREAD_LOCAL.remove(); + } + +} diff --git a/src/main/java/org/apache/rocketmq/dashboard/util/WebUtil.java b/src/main/java/org/apache/rocketmq/dashboard/util/WebUtil.java index 49e3fc7..7151320 100644 --- a/src/main/java/org/apache/rocketmq/dashboard/util/WebUtil.java +++ b/src/main/java/org/apache/rocketmq/dashboard/util/WebUtil.java @@ -17,14 +17,14 @@ package org.apache.rocketmq.dashboard.util; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.dashboard.model.User; import org.apache.rocketmq.dashboard.model.UserInfo; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index fe4d283..ddf624a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -16,7 +16,7 @@ # server: - port: 8080 + port: 8082 servlet: encoding: charset: UTF-8 @@ -71,4 +71,4 @@ threadpool: coreSize: 10 maxSize: 10 keepAliveTime: 3000 - queueSize: 5000 \ No newline at end of file + queueSize: 5000