caigy commented on a change in pull request #3761:
URL: https://github.com/apache/rocketmq/pull/3761#discussion_r791329030
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -30,51 +43,108 @@
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
-import org.apache.rocketmq.srvutil.FileWatchService;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import org.apache.rocketmq.srvutil.AclFileWatchService;
public class PlainPermissionManager {
private static final InternalLogger log =
InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
- private static final String DEFAULT_PLAIN_ACL_FILE = "/conf/plain_acl.yml";
-
private String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY,
System.getenv(MixAll.ROCKETMQ_HOME_ENV));
- private String fileName = System.getProperty("rocketmq.acl.plain.file",
DEFAULT_PLAIN_ACL_FILE);
+ private String defaultAclDir = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf");
+
+ private String defaultAclFile = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf") + File.separator +
"plain_acl.yml";
- private Map<String/** AccessKey **/, PlainAccessResource>
plainAccessResourceMap = new HashMap<>();
+ private Map<String/** aclFileName **/, Map<String/** AccessKey **/,
PlainAccessResource>> aclPlainAccessResourceMap = new HashMap<>();
Review comment:
Is 'file full path' more precise than 'aclFileName'?
##########
File path:
tools/src/main/java/org/apache/rocketmq/tools/command/acl/ClusterAclConfigVersionListSubCommand.java
##########
@@ -112,20 +112,19 @@ private void printClusterBaseInfo(
final DefaultMQAdminExt defaultMQAdminExt, final String addr) throws
InterruptedException, MQBrokerException, RemotingException,
MQClientException {
-
ClusterAclVersionInfo clusterAclVersionInfo =
defaultMQAdminExt.examineBrokerClusterAclVersionInfo(addr);
- DataVersion aclDataVersion =
clusterAclVersionInfo.getAclConfigDataVersion();
- String versionNum = String.valueOf(aclDataVersion.getCounter());
-
+ Map<String, DataVersion> aclDataVersion =
clusterAclVersionInfo.getAllAclConfigDataVersion();
DateFormat sdf = new SimpleDateFormat(UtilAll.YYYY_MM_DD_HH_MM_SS);
- String timeStampStr = sdf.format(new
Timestamp(aclDataVersion.getTimestamp()));
-
- System.out.printf("%-16s %-22s %-22s %-20s %-22s%n",
- clusterAclVersionInfo.getClusterName(),
- clusterAclVersionInfo.getBrokerName(),
- clusterAclVersionInfo.getBrokerAddr(),
- versionNum,
- timeStampStr
- );
+ for (Map.Entry<String, DataVersion> entry : aclDataVersion.entrySet())
{
Review comment:
Would `AccessValidator.getAllAclConfigVersion()` return an empty set?
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -30,51 +43,108 @@
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
-import org.apache.rocketmq.srvutil.FileWatchService;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import org.apache.rocketmq.srvutil.AclFileWatchService;
public class PlainPermissionManager {
private static final InternalLogger log =
InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
- private static final String DEFAULT_PLAIN_ACL_FILE = "/conf/plain_acl.yml";
-
private String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY,
System.getenv(MixAll.ROCKETMQ_HOME_ENV));
- private String fileName = System.getProperty("rocketmq.acl.plain.file",
DEFAULT_PLAIN_ACL_FILE);
+ private String defaultAclDir = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf");
+
+ private String defaultAclFile = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf") + File.separator +
"plain_acl.yml";
- private Map<String/** AccessKey **/, PlainAccessResource>
plainAccessResourceMap = new HashMap<>();
+ private Map<String/** aclFileName **/, Map<String/** AccessKey **/,
PlainAccessResource>> aclPlainAccessResourceMap = new HashMap<>();
+
+ private Map<String/** AccessKey **/, String/** aclFileName **/>
accessKeyTable = new HashMap<>();
private List<RemoteAddressStrategy> globalWhiteRemoteAddressStrategy = new
ArrayList<>();
private RemoteAddressStrategyFactory remoteAddressStrategyFactory = new
RemoteAddressStrategyFactory();
+ private Map<String/** aclFileName **/, List<RemoteAddressStrategy>>
globalWhiteRemoteAddressStrategyMap = new HashMap<>();
+
private boolean isWatchStart;
+ private Map<String/** aclFileName **/, DataVersion> dataVersionMap = new
HashMap<>();
+
+ @Deprecated
private final DataVersion dataVersion = new DataVersion();
+ private List<String> fileList = new ArrayList<>();
+
public PlainPermissionManager() {
load();
watch();
}
+ public void getAllAclFiles(String path) {
+ File file = new File(path);
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ String fileName = files[i].getAbsolutePath();
+ File f = new File(fileName);
+ if (fileName.endsWith(".yml")) {
Review comment:
'.yaml' is also a suffix to yaml files
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -30,51 +43,108 @@
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
-import org.apache.rocketmq.srvutil.FileWatchService;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import org.apache.rocketmq.srvutil.AclFileWatchService;
public class PlainPermissionManager {
private static final InternalLogger log =
InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
- private static final String DEFAULT_PLAIN_ACL_FILE = "/conf/plain_acl.yml";
-
private String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY,
System.getenv(MixAll.ROCKETMQ_HOME_ENV));
- private String fileName = System.getProperty("rocketmq.acl.plain.file",
DEFAULT_PLAIN_ACL_FILE);
+ private String defaultAclDir = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf");
+
+ private String defaultAclFile = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf") + File.separator +
"plain_acl.yml";
- private Map<String/** AccessKey **/, PlainAccessResource>
plainAccessResourceMap = new HashMap<>();
+ private Map<String/** aclFileName **/, Map<String/** AccessKey **/,
PlainAccessResource>> aclPlainAccessResourceMap = new HashMap<>();
+
+ private Map<String/** AccessKey **/, String/** aclFileName **/>
accessKeyTable = new HashMap<>();
private List<RemoteAddressStrategy> globalWhiteRemoteAddressStrategy = new
ArrayList<>();
private RemoteAddressStrategyFactory remoteAddressStrategyFactory = new
RemoteAddressStrategyFactory();
+ private Map<String/** aclFileName **/, List<RemoteAddressStrategy>>
globalWhiteRemoteAddressStrategyMap = new HashMap<>();
+
private boolean isWatchStart;
+ private Map<String/** aclFileName **/, DataVersion> dataVersionMap = new
HashMap<>();
+
+ @Deprecated
private final DataVersion dataVersion = new DataVersion();
+ private List<String> fileList = new ArrayList<>();
+
public PlainPermissionManager() {
load();
watch();
}
+ public void getAllAclFiles(String path) {
+ File file = new File(path);
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ String fileName = files[i].getAbsolutePath();
+ File f = new File(fileName);
+ if (fileName.endsWith(".yml")) {
+ fileList.add(fileName);
+ } else if (!f.isFile()) {
+ getAllAclFiles(fileName);
+ }
+ }
+ }
+
public void load() {
+ if (fileHome == null || fileHome.isEmpty()) {
+ //throw new AclException(String.format("%s file is empty",
fileHome));
+ return;
+ }
+ if (fileList.size() > 0) {
+ fileList.clear();
+ }
+ getAllAclFiles(defaultAclDir);
+ if (fileList == null || fileList.size() == 0)
+ return;
+
+ if (aclPlainAccessResourceMap.size() != 0 && accessKeyTable.size() !=
0) {
+ aclPlainAccessResourceMap.clear();
+ accessKeyTable.clear();
+ }
+ if (globalWhiteRemoteAddressStrategy.size() != 0) {
+ globalWhiteRemoteAddressStrategy.clear();
+ }
+ if (globalWhiteRemoteAddressStrategyMap.size() != 0) {
+ globalWhiteRemoteAddressStrategyMap.clear();
+ }
+ for (int i = 0; i < fileList.size(); i++) {
+ load(fileList.get(i));
+ }
+ if (dataVersionMap.size() != fileList.size()) {
+ Iterator<Map.Entry<String, DataVersion>> it =
dataVersionMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, DataVersion> entry = it.next();
+ if (!fileList.contains(entry.getKey()))
+ it.remove();
+ }
+ }
+ if (dataVersionMap.size() == 1) {
+ for (Map.Entry<String, DataVersion> entry :
dataVersionMap.entrySet()) {
+ dataVersion.assignNewOne(entry.getValue());
+ }
+ }
Review comment:
Would dataVersion be empty or updated if there are multiple ACL config
files?
##########
File path: acl/src/main/java/org/apache/rocketmq/acl/AccessValidator.java
##########
@@ -60,17 +63,27 @@
*
* @return
*/
+ @Deprecated
String getAclConfigVersion();
Review comment:
Pls add more description about:
- the reason to deprecate `String getAclConfigVersion()` and replace it with
`Map<String, DataVersion> getAllAclConfigVersion()`
- What is the object or scope that **version** describe? In previous
implementation, **version** is used to mark the whole config. In this
multi-filed feature, each config file has its own **version**. And if ACL
config are stored in DB, each record may have its own **version**. We should
define **version** precisely.
- In `Map<String, DataVersion> getAllAclConfigVersion()`, what is the key
of Map? Users may curious of it. If this is the full path of config files, it
brings implementation to interface.
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -85,43 +155,76 @@ public void load() {
}
}
+ if (this.globalWhiteRemoteAddressStrategyMap.get(aclFilePath) != null)
{
+ List<RemoteAddressStrategy> remoteAddressStrategyList =
this.globalWhiteRemoteAddressStrategyMap.get(aclFilePath);
+ for (int i = 0; i < remoteAddressStrategyList.size(); i++) {
+
this.globalWhiteRemoteAddressStrategy.remove(remoteAddressStrategyList.get(i));
+ }
+ this.globalWhiteRemoteAddressStrategyMap.remove(aclFilePath);
Review comment:
Removing items in `globalWhiteRemoteAddressStrategy` may cause ACL check
failures.
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -30,51 +43,108 @@
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
-import org.apache.rocketmq.srvutil.FileWatchService;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import org.apache.rocketmq.srvutil.AclFileWatchService;
public class PlainPermissionManager {
private static final InternalLogger log =
InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
- private static final String DEFAULT_PLAIN_ACL_FILE = "/conf/plain_acl.yml";
-
private String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY,
System.getenv(MixAll.ROCKETMQ_HOME_ENV));
- private String fileName = System.getProperty("rocketmq.acl.plain.file",
DEFAULT_PLAIN_ACL_FILE);
+ private String defaultAclDir = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf");
+
+ private String defaultAclFile = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf") + File.separator +
"plain_acl.yml";
- private Map<String/** AccessKey **/, PlainAccessResource>
plainAccessResourceMap = new HashMap<>();
+ private Map<String/** aclFileName **/, Map<String/** AccessKey **/,
PlainAccessResource>> aclPlainAccessResourceMap = new HashMap<>();
+
+ private Map<String/** AccessKey **/, String/** aclFileName **/>
accessKeyTable = new HashMap<>();
private List<RemoteAddressStrategy> globalWhiteRemoteAddressStrategy = new
ArrayList<>();
private RemoteAddressStrategyFactory remoteAddressStrategyFactory = new
RemoteAddressStrategyFactory();
+ private Map<String/** aclFileName **/, List<RemoteAddressStrategy>>
globalWhiteRemoteAddressStrategyMap = new HashMap<>();
+
private boolean isWatchStart;
+ private Map<String/** aclFileName **/, DataVersion> dataVersionMap = new
HashMap<>();
+
+ @Deprecated
private final DataVersion dataVersion = new DataVersion();
+ private List<String> fileList = new ArrayList<>();
+
public PlainPermissionManager() {
load();
watch();
}
+ public void getAllAclFiles(String path) {
+ File file = new File(path);
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ String fileName = files[i].getAbsolutePath();
+ File f = new File(fileName);
+ if (fileName.endsWith(".yml")) {
+ fileList.add(fileName);
+ } else if (!f.isFile()) {
Review comment:
Maybe it should be `file.isDirectory()`?
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -267,54 +394,107 @@ public boolean updateGlobalWhiteAddrsConfig(List<String>
globalWhiteAddrsList) {
}
// Update globalWhiteRemoteAddr element in memory map firstly
aclAccessConfigMap.put(AclConstants.CONFIG_GLOBAL_WHITE_ADDRS,
globalWhiteRemoteAddrList);
- if (AclUtils.writeDataObject(fileHome + File.separator + fileName,
updateAclConfigFileVersion(aclAccessConfigMap))) {
- return true;
- }
+ return AclUtils.writeDataObject(defaultAclFile,
updateAclConfigFileVersion(aclAccessConfigMap));
+ }
+
+ log.error("Users must ensure that the acl yaml config file has
globalWhiteRemoteAddresses flag in the {} firstly", defaultAclFile);
+ return false;
+ }
+
+ public boolean updateGlobalWhiteAddrsConfig(List<String>
globalWhiteAddrsList, String fileName) {
+ if (globalWhiteAddrsList == null) {
+ log.error("Parameter value globalWhiteAddrsList is null,Please
check your parameter");
return false;
}
- log.error("Users must ensure that the acl yaml config file has
globalWhiteRemoteAddresses flag firstly");
+ File file = new File(fileName);
+ if (!file.exists() || file.isDirectory()) {
+ log.error("Parameter value fileName is not exist or is a
directory,Please check your parameter");
+ return false;
+ }
+
+ Map<String, Object> aclAccessConfigMap =
AclUtils.getYamlDataObject(fileName, Map.class);
+ if (aclAccessConfigMap == null || aclAccessConfigMap.isEmpty()) {
+ throw new AclException(String.format("the %s file is not found or
empty", fileName));
+ }
+ List<String> globalWhiteRemoteAddrList = (List<String>)
aclAccessConfigMap.get(AclConstants.CONFIG_GLOBAL_WHITE_ADDRS);
+ if (globalWhiteRemoteAddrList != null) {
+ globalWhiteRemoteAddrList.clear();
+ if (globalWhiteAddrsList != null) {
+ globalWhiteRemoteAddrList.addAll(globalWhiteAddrsList);
Review comment:
Combination of `clear()` and `addAll()` is not atomic, which may cause
ACL failure in this process.
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -30,51 +43,108 @@
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
-import org.apache.rocketmq.srvutil.FileWatchService;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import org.apache.rocketmq.srvutil.AclFileWatchService;
public class PlainPermissionManager {
private static final InternalLogger log =
InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
- private static final String DEFAULT_PLAIN_ACL_FILE = "/conf/plain_acl.yml";
-
private String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY,
System.getenv(MixAll.ROCKETMQ_HOME_ENV));
- private String fileName = System.getProperty("rocketmq.acl.plain.file",
DEFAULT_PLAIN_ACL_FILE);
+ private String defaultAclDir = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf");
+
+ private String defaultAclFile = fileHome + File.separator
+ + System.getProperty("rocketmq.acl.dir", "/conf") + File.separator +
"plain_acl.yml";
- private Map<String/** AccessKey **/, PlainAccessResource>
plainAccessResourceMap = new HashMap<>();
+ private Map<String/** aclFileName **/, Map<String/** AccessKey **/,
PlainAccessResource>> aclPlainAccessResourceMap = new HashMap<>();
+
+ private Map<String/** AccessKey **/, String/** aclFileName **/>
accessKeyTable = new HashMap<>();
private List<RemoteAddressStrategy> globalWhiteRemoteAddressStrategy = new
ArrayList<>();
private RemoteAddressStrategyFactory remoteAddressStrategyFactory = new
RemoteAddressStrategyFactory();
+ private Map<String/** aclFileName **/, List<RemoteAddressStrategy>>
globalWhiteRemoteAddressStrategyMap = new HashMap<>();
+
private boolean isWatchStart;
+ private Map<String/** aclFileName **/, DataVersion> dataVersionMap = new
HashMap<>();
+
+ @Deprecated
private final DataVersion dataVersion = new DataVersion();
+ private List<String> fileList = new ArrayList<>();
+
public PlainPermissionManager() {
load();
watch();
}
+ public void getAllAclFiles(String path) {
+ File file = new File(path);
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ String fileName = files[i].getAbsolutePath();
+ File f = new File(fileName);
+ if (fileName.endsWith(".yml")) {
+ fileList.add(fileName);
+ } else if (!f.isFile()) {
+ getAllAclFiles(fileName);
+ }
+ }
+ }
+
public void load() {
+ if (fileHome == null || fileHome.isEmpty()) {
+ //throw new AclException(String.format("%s file is empty",
fileHome));
+ return;
+ }
+ if (fileList.size() > 0) {
+ fileList.clear();
+ }
+ getAllAclFiles(defaultAclDir);
+ if (fileList == null || fileList.size() == 0)
+ return;
+
+ if (aclPlainAccessResourceMap.size() != 0 && accessKeyTable.size() !=
0) {
+ aclPlainAccessResourceMap.clear();
+ accessKeyTable.clear();
+ }
+ if (globalWhiteRemoteAddressStrategy.size() != 0) {
+ globalWhiteRemoteAddressStrategy.clear();
+ }
+ if (globalWhiteRemoteAddressStrategyMap.size() != 0) {
+ globalWhiteRemoteAddressStrategyMap.clear();
+ }
Review comment:
Clearing globalWhiteRemoteAddressStrategy or
globalWhiteRemoteAddressStrategyMap may cause ACL check failures before load()
finished.
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -30,51 +43,108 @@
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
-import org.apache.rocketmq.srvutil.FileWatchService;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import org.apache.rocketmq.srvutil.AclFileWatchService;
public class PlainPermissionManager {
private static final InternalLogger log =
InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
- private static final String DEFAULT_PLAIN_ACL_FILE = "/conf/plain_acl.yml";
-
private String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY,
System.getenv(MixAll.ROCKETMQ_HOME_ENV));
- private String fileName = System.getProperty("rocketmq.acl.plain.file",
DEFAULT_PLAIN_ACL_FILE);
+ private String defaultAclDir = fileHome + File.separator
Review comment:
Can users specify their own acl dir?
##########
File path:
acl/src/main/java/org/apache/rocketmq/acl/plain/PlainPermissionManager.java
##########
@@ -30,51 +41,74 @@
import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
-import org.apache.rocketmq.srvutil.FileWatchService;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import org.apache.rocketmq.srvutil.AclFileWatchService;
public class PlainPermissionManager {
private static final InternalLogger log =
InternalLoggerFactory.getLogger(LoggerName.COMMON_LOGGER_NAME);
- private static final String DEFAULT_PLAIN_ACL_FILE = "/conf/plain_acl.yml";
-
private String fileHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY,
System.getenv(MixAll.ROCKETMQ_HOME_ENV));
- private String fileName = System.getProperty("rocketmq.acl.plain.file",
DEFAULT_PLAIN_ACL_FILE);
Review comment:
It seems users can't specify config file by property
`rocketmq.acl.plain.file`?
##########
File path:
common/src/main/java/org/apache/rocketmq/common/protocol/header/GetBrokerAclConfigResponseHeader.java
##########
@@ -16,15 +16,28 @@
*/
package org.apache.rocketmq.common.protocol.header;
+import org.apache.rocketmq.common.DataVersion;
import org.apache.rocketmq.remoting.CommandCustomHeader;
import org.apache.rocketmq.remoting.annotation.CFNotNull;
import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import java.util.Map;
+
public class GetBrokerAclConfigResponseHeader implements CommandCustomHeader {
@CFNotNull
private String version;
+ private Map<String, DataVersion> versions;
Review comment:
`version` and `versions` are too similar and confusing, maybe we should
name them more clearly.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]