提交 c7c9601d 编写于 作者: 陈永明 提交者: Heng Du

[RIP-15]Add Ipv6 support for RocketMQ (#1352)

* Remove the useless files

* Replace PermSize with MetaspaceSize, details see http://openjdk.java.net/jeps/122

* Update DLedgerCommitLog.java (#1145)

Delete useless code

* Remove the duplicate content

* Polish the comment (#1107)

* Minor Typo fix  (#860)

* [ISSUE #1082] Fix disconnection of HA (#1083)

* fixed the text description in chinese doc (#1339)

* fix /dev/shm not found on some OSs (#1345)

* Refactor the protection logic when pulling

* change the MQVersion variable to rocketmq 4.5.2 version;

* Minor polish

* Fix the wrong package name

* [maven-release-plugin] prepare release rocketmq-all-4.5.2

* [maven-release-plugin] prepare for next development iteration

* [RIP-15]Add Ipv6 support for RocketMQ
上级 be7c6dd2
...@@ -10,7 +10,7 @@ Nor is code the only way to contribute to the project. We strongly value documen ...@@ -10,7 +10,7 @@ Nor is code the only way to contribute to the project. We strongly value documen
To submit a change for inclusion, please do the following: To submit a change for inclusion, please do the following:
#### If the change is non-trivial please include some unit tests that cover the new functionality. #### If the change is non-trivial please include some unit tests that cover the new functionality.
#### If you are introducing a completely new feature or API it is a good idea to start a wiki and get consensus on the basic design first. #### If you are introducing a completely new feature or API it is a good idea to start a [RIP](https://github.com/apache/rocketmq/wiki/RocketMQ-Improvement-Proposal) and get consensus on the basic design first.
#### It is our job to follow up on patches in a timely fashion. Nag us if we aren't doing our job (sometimes we drop things). #### It is our job to follow up on patches in a timely fashion. Nag us if we aren't doing our job (sometimes we drop things).
## Becoming a Committer ## Becoming a Committer
...@@ -19,9 +19,8 @@ We are always interested in adding new contributors. What we look for are series ...@@ -19,9 +19,8 @@ We are always interested in adding new contributors. What we look for are series
Nowadays,we have several important contribution points: Nowadays,we have several important contribution points:
#### Wiki & JavaDoc #### Wiki & JavaDoc
#### RocketMQ Console
#### RocketMQ SDK(C++\.Net\Php\Python\Go\Node.js) #### RocketMQ SDK(C++\.Net\Php\Python\Go\Node.js)
#### RocketMQ MySQL(Oracle\PostgreSQL\Redis\MongoDB\HBase\MSSQL) Replicator #### RocketMQ Connectors
##### Prerequisite ##### Prerequisite
If you want to contribute the above listing points, you must abide our some prerequisites: If you want to contribute the above listing points, you must abide our some prerequisites:
......
...@@ -51,3 +51,23 @@ We always welcome new contributions, whether for trivial cleanups, [big new feat ...@@ -51,3 +51,23 @@ We always welcome new contributions, whether for trivial cleanups, [big new feat
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) Copyright (C) Apache Software Foundation [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) Copyright (C) Apache Software Foundation
----------
## Export Control Notice
This distribution includes cryptographic software. The country in which you currently reside may have
restrictions on the import, possession, use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check your country's laws, regulations and policies concerning
the import, possession, or use, and re-export of encryption software, to see if this is permitted. See
<http://www.wassenaar.org/> for more information.
The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this
software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software
using or performing cryptographic functions with asymmetric algorithms. The form and manner of this Apache
Software Foundation distribution makes it eligible for export under the License Exception ENC Technology
Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for
both object code and source code.
The following provides more details on the included cryptographic software:
This software uses Apache Commons Crypto (https://commons.apache.org/proper/commons-crypto/) to
support authentication, and encryption and decryption of data sent across the network between
services.
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>rocketmq-acl</artifactId> <artifactId>rocketmq-acl</artifactId>
<name>rocketmq-acl ${project.version}</name> <name>rocketmq-acl ${project.version}</name>
...@@ -67,6 +67,10 @@ ...@@ -67,6 +67,10 @@
<artifactId>logback-core</artifactId> <artifactId>logback-core</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>
...@@ -23,6 +23,7 @@ import java.io.FileNotFoundException; ...@@ -23,6 +23,7 @@ import java.io.FileNotFoundException;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.SortedMap; import java.util.SortedMap;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
...@@ -69,24 +70,75 @@ public class AclUtils { ...@@ -69,24 +70,75 @@ public class AclUtils {
return signature; return signature;
} }
public static void IPv6AddressCheck(String netaddress) {
if (isAsterisk(netaddress) || isMinus(netaddress)) {
int asterisk = netaddress.indexOf("*");
int minus = netaddress.indexOf("-");
// '*' must be the end of netaddress if it exists
if (asterisk > -1 && asterisk != netaddress.length() - 1) {
throw new AclException(String.format("Netaddress examine scope Exception netaddress is %s", netaddress));
}
// format like "2::ac5:78:1-200:*" or "2::ac5:78:1-200" is legal
if (minus > -1) {
if (asterisk == -1) {
if (minus <= netaddress.lastIndexOf(":")) {
throw new AclException(String.format("Netaddress examine scope Exception netaddress is %s", netaddress));
}
} else {
if (minus <= netaddress.lastIndexOf(":", netaddress.lastIndexOf(":") - 1)) {
throw new AclException(String.format("Netaddress examine scope Exception netaddress is %s", netaddress));
}
}
}
}
}
public static String v6ipProcess(String netaddress, String[] strArray, int index) {
int part;
String subAddress;
boolean isAsterisk = isAsterisk(netaddress);
boolean isMinus = isMinus(netaddress);
if (isAsterisk && isMinus) {
part = 6;
int lastColon = netaddress.lastIndexOf(':');
int secondLastColon = netaddress.substring(0, lastColon).lastIndexOf(':');
subAddress = netaddress.substring(0, secondLastColon);
} else if (!isAsterisk && !isMinus) {
part = 8;
subAddress = netaddress;
} else {
part = 7;
subAddress = netaddress.substring(0, netaddress.lastIndexOf(':'));
}
return expandIP(subAddress, part);
}
public static void verify(String netaddress, int index) { public static void verify(String netaddress, int index) {
if (!AclUtils.isScope(netaddress, index)) { if (!AclUtils.isScope(netaddress, index)) {
throw new AclException(String.format("Netaddress examine scope Exception netaddress is %s", netaddress)); throw new AclException(String.format("Netaddress examine scope Exception netaddress is %s", netaddress));
} }
} }
public static String[] getAddreeStrArray(String netaddress, String four) { public static String[] getAddreeStrArray(String netaddress, String partialAddress) {
String[] fourStrArray = StringUtils.split(four.substring(1, four.length() - 1), ","); String[] parAddStrArray = StringUtils.split(partialAddress.substring(1, partialAddress.length() - 1), ",");
String address = netaddress.substring(0, netaddress.indexOf("{")); String address = netaddress.substring(0, netaddress.indexOf("{"));
String[] addreeStrArray = new String[fourStrArray.length]; String[] addreeStrArray = new String[parAddStrArray.length];
for (int i = 0; i < fourStrArray.length; i++) { for (int i = 0; i < parAddStrArray.length; i++) {
addreeStrArray[i] = address + fourStrArray[i]; addreeStrArray[i] = address + parAddStrArray[i];
} }
return addreeStrArray; return addreeStrArray;
} }
public static boolean isScope(String num, int index) { public static boolean isScope(String netaddress, int index) {
String[] strArray = StringUtils.split(num, "."); // IPv6 Address
if (isColon(netaddress)) {
netaddress = expandIP(netaddress, 8);
String[] strArray = StringUtils.split(netaddress, ":");
return isIPv6Scope(strArray, index);
}
String[] strArray = StringUtils.split(netaddress, ".");
if (strArray.length != 4) { if (strArray.length != 4) {
return false; return false;
} }
...@@ -107,6 +159,10 @@ public class AclUtils { ...@@ -107,6 +159,10 @@ public class AclUtils {
} }
public static boolean isColon(String netaddress) {
return netaddress.indexOf(':') > -1;
}
public static boolean isScope(String num) { public static boolean isScope(String num) {
return isScope(Integer.valueOf(num.trim())); return isScope(Integer.valueOf(num.trim()));
} }
...@@ -119,7 +175,7 @@ public class AclUtils { ...@@ -119,7 +175,7 @@ public class AclUtils {
return asterisk.indexOf('*') > -1; return asterisk.indexOf('*') > -1;
} }
public static boolean isColon(String colon) { public static boolean isComma(String colon) {
return colon.indexOf(',') > -1; return colon.indexOf(',') > -1;
} }
...@@ -128,6 +184,88 @@ public class AclUtils { ...@@ -128,6 +184,88 @@ public class AclUtils {
} }
public static boolean isIPv6Scope(String[] num, int index) {
for (int i = 0; i < index; i++) {
int value;
try {
value = Integer.parseInt(num[i], 16);
} catch (NumberFormatException e) {
return false;
}
if (!isIPv6Scope(value)) {
return false;
}
}
return true;
}
public static boolean isIPv6Scope(int num) {
int min = Integer.parseInt("0", 16);
int max = Integer.parseInt("ffff", 16);
return num >= min && num <= max;
}
public static String expandIP(String netaddress, int part) {
boolean compress = false;
int compressIndex = -1;
String[] strArray = StringUtils.split(netaddress, ":");
ArrayList<Integer> indexes = new ArrayList<>();
for (int i = 0; i < netaddress.length(); i++) {
if (netaddress.charAt(i) == ':') {
if (indexes.size() > 0 && i - indexes.get(indexes.size() - 1) == 1) {
compressIndex = i;
compress = true;
}
indexes.add(i);
}
}
for (int i = 0; i < strArray.length; i++) {
if (strArray[i].length() < 4) {
strArray[i] = "0000".substring(0, 4 - strArray[i].length()) + strArray[i];
}
}
StringBuilder sb = new StringBuilder();
if (compress) {
int pos = indexes.indexOf(compressIndex);
int index = 0;
if (!netaddress.startsWith(":")) {
for (int i = 0; i < pos; i++) {
sb.append(strArray[index]).append(":");
index += 1;
}
}
int zeroNum = part - strArray.length;
if (netaddress.endsWith(":")) {
for (int i = 0; i < zeroNum; i++) {
sb.append("0000");
if (i != zeroNum - 1) {
sb.append(":");
}
}
} else {
for (int i = 0; i < zeroNum; i++) {
sb.append("0000").append(":");
}
for (int i = index; i < strArray.length; i++) {
sb.append(strArray[i]);
if (i != strArray.length - 1) {
sb.append(":");
}
}
}
} else {
for (int i = 0; i < strArray.length; i++) {
sb.append(strArray[i]);
if (i != strArray.length - 1) {
sb.append(":");
}
}
}
return sb.toString().toUpperCase();
}
public static <T> T getYamlDataObject(String path, Class<T> clazz) { public static <T> T getYamlDataObject(String path, Class<T> clazz) {
Yaml yaml = new Yaml(); Yaml yaml = new Yaml();
FileInputStream fis = null; FileInputStream fis = null;
...@@ -148,7 +286,7 @@ public class AclUtils { ...@@ -148,7 +286,7 @@ public class AclUtils {
} }
} }
public static boolean writeDataObject(String path, Map<String,Object> dataMap) { public static boolean writeDataObject(String path, Map<String, Object> dataMap) {
Yaml yaml = new Yaml(); Yaml yaml = new Yaml();
PrintWriter pw = null; PrintWriter pw = null;
try { try {
...@@ -172,15 +310,15 @@ public class AclUtils { ...@@ -172,15 +310,15 @@ public class AclUtils {
yamlDataObject = AclUtils.getYamlDataObject(fileName, yamlDataObject = AclUtils.getYamlDataObject(fileName,
JSONObject.class); JSONObject.class);
} catch (Exception e) { } catch (Exception e) {
log.error("Convert yaml file to data object error, ",e); log.error("Convert yaml file to data object error, ", e);
return null; return null;
} }
if (yamlDataObject == null || yamlDataObject.isEmpty()) { if (yamlDataObject == null || yamlDataObject.isEmpty()) {
log.warn("Cannot find conf file :{}, acl isn't be enabled." ,fileName); log.warn("Cannot find conf file :{}, acl isn't be enabled.", fileName);
return null; return null;
} }
String accessKey = yamlDataObject.getString(AclConstants.CONFIG_ACCESS_KEY); String accessKey = yamlDataObject.getString(AclConstants.CONFIG_ACCESS_KEY);
String secretKey = yamlDataObject.getString(AclConstants.CONFIG_SECRET_KEY); String secretKey = yamlDataObject.getString(AclConstants.CONFIG_SECRET_KEY);
...@@ -189,7 +327,7 @@ public class AclUtils { ...@@ -189,7 +327,7 @@ public class AclUtils {
return null; return null;
} }
return new AclClientRPCHook(new SessionCredentials(accessKey,secretKey)); return new AclClientRPCHook(new SessionCredentials(accessKey, secretKey));
} }
} }
...@@ -50,7 +50,7 @@ public class PlainAccessValidator implements AccessValidator { ...@@ -50,7 +50,7 @@ public class PlainAccessValidator implements AccessValidator {
public AccessResource parse(RemotingCommand request, String remoteAddr) { public AccessResource parse(RemotingCommand request, String remoteAddr) {
PlainAccessResource accessResource = new PlainAccessResource(); PlainAccessResource accessResource = new PlainAccessResource();
if (remoteAddr != null && remoteAddr.contains(":")) { if (remoteAddr != null && remoteAddr.contains(":")) {
accessResource.setWhiteRemoteAddress(remoteAddr.split(":")[0]); accessResource.setWhiteRemoteAddress(remoteAddr.substring(0, remoteAddr.lastIndexOf(':')));
} else { } else {
accessResource.setWhiteRemoteAddress(remoteAddr); accessResource.setWhiteRemoteAddress(remoteAddr);
} }
......
...@@ -19,6 +19,7 @@ package org.apache.rocketmq.acl.plain; ...@@ -19,6 +19,7 @@ package org.apache.rocketmq.acl.plain;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.validator.routines.InetAddressValidator;
import org.apache.rocketmq.acl.common.AclException; import org.apache.rocketmq.acl.common.AclException;
import org.apache.rocketmq.acl.common.AclUtils; import org.apache.rocketmq.acl.common.AclUtils;
import org.apache.rocketmq.common.constant.LoggerName; import org.apache.rocketmq.common.constant.LoggerName;
...@@ -41,17 +42,26 @@ public class RemoteAddressStrategyFactory { ...@@ -41,17 +42,26 @@ public class RemoteAddressStrategyFactory {
if (StringUtils.isBlank(remoteAddr)) { if (StringUtils.isBlank(remoteAddr)) {
return BLANK_NET_ADDRESS_STRATEGY; return BLANK_NET_ADDRESS_STRATEGY;
} }
if ("*".equals(remoteAddr) || "*.*.*.*".equals(remoteAddr)) { if ("*".equals(remoteAddr) || "*.*.*.*".equals(remoteAddr) || "*:*:*:*:*:*:*:*".equals(remoteAddr)) {
return NULL_NET_ADDRESS_STRATEGY; return NULL_NET_ADDRESS_STRATEGY;
} }
if (remoteAddr.endsWith("}")) { if (remoteAddr.endsWith("}")) {
String[] strArray = StringUtils.split(remoteAddr, "."); if (AclUtils.isColon(remoteAddr)) {
String four = strArray[3]; String[] strArray = StringUtils.split(remoteAddr, ":");
if (!four.startsWith("{")) { String last = strArray[strArray.length - 1];
throw new AclException(String.format("MultipleRemoteAddressStrategy netaddress examine scope Exception netaddress", remoteAddr)); if (!last.startsWith("{")) {
throw new AclException(String.format("MultipleRemoteAddressStrategy netaddress examine scope Exception netaddress", remoteAddr));
}
return new MultipleRemoteAddressStrategy(AclUtils.getAddreeStrArray(remoteAddr, last));
} else {
String[] strArray = StringUtils.split(remoteAddr, ".");
String four = strArray[3];
if (!four.startsWith("{")) {
throw new AclException(String.format("MultipleRemoteAddressStrategy netaddress examine scope Exception netaddress", remoteAddr));
}
return new MultipleRemoteAddressStrategy(AclUtils.getAddreeStrArray(remoteAddr, four));
} }
return new MultipleRemoteAddressStrategy(AclUtils.getAddreeStrArray(remoteAddr, four)); } else if (AclUtils.isComma(remoteAddr)) {
} else if (AclUtils.isColon(remoteAddr)) {
return new MultipleRemoteAddressStrategy(StringUtils.split(remoteAddr, ",")); return new MultipleRemoteAddressStrategy(StringUtils.split(remoteAddr, ","));
} else if (AclUtils.isAsterisk(remoteAddr) || AclUtils.isMinus(remoteAddr)) { } else if (AclUtils.isAsterisk(remoteAddr) || AclUtils.isMinus(remoteAddr)) {
return new RangeRemoteAddressStrategy(remoteAddr); return new RangeRemoteAddressStrategy(remoteAddr);
...@@ -81,15 +91,26 @@ public class RemoteAddressStrategyFactory { ...@@ -81,15 +91,26 @@ public class RemoteAddressStrategyFactory {
private final Set<String> multipleSet = new HashSet<>(); private final Set<String> multipleSet = new HashSet<>();
public MultipleRemoteAddressStrategy(String[] strArray) { public MultipleRemoteAddressStrategy(String[] strArray) {
InetAddressValidator validator = InetAddressValidator.getInstance();
for (String netaddress : strArray) { for (String netaddress : strArray) {
AclUtils.verify(netaddress, 4); if (validator.isValidInet4Address(netaddress)) {
multipleSet.add(netaddress); multipleSet.add(netaddress);
} else if (validator.isValidInet6Address(netaddress)) {
multipleSet.add(AclUtils.expandIP(netaddress, 8));
} else {
throw new AclException(String.format("Netaddress examine Exception netaddress is %s", netaddress));
}
} }
} }
@Override @Override
public boolean match(PlainAccessResource plainAccessResource) { public boolean match(PlainAccessResource plainAccessResource) {
return multipleSet.contains(plainAccessResource.getWhiteRemoteAddress()); InetAddressValidator validator = InetAddressValidator.getInstance();
String whiteRemoteAddress = plainAccessResource.getWhiteRemoteAddress();
if (validator.isValidInet6Address(whiteRemoteAddress)) {
whiteRemoteAddress = AclUtils.expandIP(whiteRemoteAddress, 8);
}
return multipleSet.contains(whiteRemoteAddress);
} }
} }
...@@ -100,12 +121,16 @@ public class RemoteAddressStrategyFactory { ...@@ -100,12 +121,16 @@ public class RemoteAddressStrategyFactory {
public OneRemoteAddressStrategy(String netaddress) { public OneRemoteAddressStrategy(String netaddress) {
this.netaddress = netaddress; this.netaddress = netaddress;
AclUtils.verify(netaddress, 4); InetAddressValidator validator = InetAddressValidator.getInstance();
if (!(validator.isValidInet4Address(netaddress) || validator.isValidInet6Address(netaddress))) {
throw new AclException(String.format("Netaddress examine Exception netaddress is %s", netaddress));
}
} }
@Override @Override
public boolean match(PlainAccessResource plainAccessResource) { public boolean match(PlainAccessResource plainAccessResource) {
return netaddress.equals(plainAccessResource.getWhiteRemoteAddress()); String writeRemoteAddress = AclUtils.expandIP(plainAccessResource.getWhiteRemoteAddress(), 8).toUpperCase();
return AclUtils.expandIP(netaddress, 8).toUpperCase().equals(writeRemoteAddress);
} }
} }
...@@ -121,14 +146,29 @@ public class RemoteAddressStrategyFactory { ...@@ -121,14 +146,29 @@ public class RemoteAddressStrategyFactory {
private int index; private int index;
public RangeRemoteAddressStrategy(String remoteAddr) { public RangeRemoteAddressStrategy(String remoteAddr) {
String[] strArray = StringUtils.split(remoteAddr, "."); // IPv6 Address
if (analysis(strArray, 1) || analysis(strArray, 2) || analysis(strArray, 3)) { if (AclUtils.isColon(remoteAddr)) {
AclUtils.verify(remoteAddr, index - 1); AclUtils.IPv6AddressCheck(remoteAddr);
StringBuffer sb = new StringBuffer().append(strArray[0].trim()).append(".").append(strArray[1].trim()).append("."); String[] strArray = StringUtils.split(remoteAddr, ":");
if (index == 3) { for (int i = 1; i < strArray.length; i++) {
sb.append(strArray[2].trim()).append("."); if (ipv6Analysis(strArray, i)) {
AclUtils.verify(remoteAddr, index - 1);
String preAddress = AclUtils.v6ipProcess(remoteAddr, strArray, index);
this.index = StringUtils.split(preAddress, ":").length;
this.head = preAddress;
break;
}
}
} else {
String[] strArray = StringUtils.split(remoteAddr, ".");
if (analysis(strArray, 1) || analysis(strArray, 2) || analysis(strArray, 3)) {
AclUtils.verify(remoteAddr, index - 1);
StringBuffer sb = new StringBuffer();
for (int j = 0; j < index; j++) {
sb.append(strArray[j].trim()).append(".");
}
this.head = sb.toString();
} }
this.head = sb.toString();
} }
} }
...@@ -152,6 +192,27 @@ public class RemoteAddressStrategyFactory { ...@@ -152,6 +192,27 @@ public class RemoteAddressStrategyFactory {
return this.end > 0 ? true : false; return this.end > 0 ? true : false;
} }
private boolean ipv6Analysis(String[] strArray, int index) {
String value = strArray[index].trim();
this.index = index;
if ("*".equals(value)) {
int min = Integer.parseInt("0", 16);
int max = Integer.parseInt("ffff", 16);
setValue(min, max);
} else if (AclUtils.isMinus(value)) {
if (value.indexOf("-") == 0) {
throw new AclException(String.format("RangeRemoteAddressStrategy netaddress examine scope Exception value %s ", value));
}
String[] valueArray = StringUtils.split(value, "-");
this.start = Integer.parseInt(valueArray[0], 16);
this.end = Integer.parseInt(valueArray[1], 16);
if (!(AclUtils.isIPv6Scope(end) && AclUtils.isIPv6Scope(start) && start <= end)) {
throw new AclException(String.format("RangeRemoteAddressStrategy netaddress examine scope Exception start is %s , end is %s", start, end));
}
}
return this.end > 0 ? true : false;
}
private void setValue(int start, int end) { private void setValue(int start, int end) {
this.start = start; this.start = start;
this.end = end; this.end = end;
...@@ -160,21 +221,33 @@ public class RemoteAddressStrategyFactory { ...@@ -160,21 +221,33 @@ public class RemoteAddressStrategyFactory {
@Override @Override
public boolean match(PlainAccessResource plainAccessResource) { public boolean match(PlainAccessResource plainAccessResource) {
String netAddress = plainAccessResource.getWhiteRemoteAddress(); String netAddress = plainAccessResource.getWhiteRemoteAddress();
if (netAddress.startsWith(this.head)) { InetAddressValidator validator = InetAddressValidator.getInstance();
String value; if (validator.isValidInet4Address(netAddress)) {
if (index == 3) { if (netAddress.startsWith(this.head)) {
value = netAddress.substring(this.head.length()); String value;
} else { if (index == 3) {
value = netAddress.substring(this.head.length(), netAddress.lastIndexOf('.')); value = netAddress.substring(this.head.length());
} else if (index == 2) {
value = netAddress.substring(this.head.length(), netAddress.lastIndexOf('.'));
} else {
value = netAddress.substring(this.head.length(), netAddress.lastIndexOf('.', netAddress.lastIndexOf('.') - 1));
}
Integer address = Integer.valueOf(value);
if (address >= this.start && address <= this.end) {
return true;
}
} }
Integer address = Integer.valueOf(value); } else if (validator.isValidInet6Address(netAddress)) {
if (address >= this.start && address <= this.end) { netAddress = AclUtils.expandIP(netAddress, 8).toUpperCase();
return true; if (netAddress.startsWith(this.head)) {
String value = netAddress.substring(5 * index, 5 * index + 4);
Integer address = Integer.parseInt(value, 16);
if (address >= this.start && address <= this.end) {
return true;
}
} }
} }
return false; return false;
} }
} }
} }
...@@ -46,20 +46,35 @@ public class AclUtilsTest { ...@@ -46,20 +46,35 @@ public class AclUtilsTest {
addressList.add("1.1.1.3"); addressList.add("1.1.1.3");
addressList.add("1.1.1.4"); addressList.add("1.1.1.4");
Assert.assertEquals(newAddressList, addressList); Assert.assertEquals(newAddressList, addressList);
// IPv6 test
String ipv6Address = "1:ac41:9987::bb22:666:{1,2,3,4}";
String[] ipv6AddressArray = AclUtils.getAddreeStrArray(ipv6Address, "{1,2,3,4}");
List<String> newIPv6AddressList = new ArrayList<>();
for (String a : ipv6AddressArray) {
newIPv6AddressList.add(a);
}
List<String> ipv6AddressList = new ArrayList<>();
ipv6AddressList.add("1:ac41:9987::bb22:666:1");
ipv6AddressList.add("1:ac41:9987::bb22:666:2");
ipv6AddressList.add("1:ac41:9987::bb22:666:3");
ipv6AddressList.add("1:ac41:9987::bb22:666:4");
Assert.assertEquals(newIPv6AddressList, ipv6AddressList);
} }
@Test @Test
public void isScopeStringArray() { public void isScopeStringArray() {
String adderss = "12"; String address = "12";
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
boolean isScope = AclUtils.isScope(adderss, 4); boolean isScope = AclUtils.isScope(address, 4);
if (i == 3) { if (i == 3) {
Assert.assertTrue(isScope); Assert.assertTrue(isScope);
} else { } else {
Assert.assertFalse(isScope); Assert.assertFalse(isScope);
} }
adderss = adderss + ".12"; address = address + ".12";
} }
} }
...@@ -77,6 +92,25 @@ public class AclUtilsTest { ...@@ -77,6 +92,25 @@ public class AclUtilsTest {
isScope = AclUtils.isScope(adderss, 3); isScope = AclUtils.isScope(adderss, 3);
Assert.assertFalse(isScope); Assert.assertFalse(isScope);
// IPv6 test
adderss = StringUtils.split("1050:0000:0000:0000:0005:0600:300c:326b", ":");
isScope = AclUtils.isIPv6Scope(adderss, 8);
Assert.assertTrue(isScope);
isScope = AclUtils.isIPv6Scope(adderss, 4);
Assert.assertTrue(isScope);
adderss = StringUtils.split("1050:9876:0000:0000:0005:akkg:300c:326b", ":");
isScope = AclUtils.isIPv6Scope(adderss, 8);
Assert.assertFalse(isScope);
isScope = AclUtils.isIPv6Scope(adderss, 4);
Assert.assertTrue(isScope);
adderss = StringUtils.split(AclUtils.expandIP("1050::0005:akkg:300c:326b", 8), ":");
isScope = AclUtils.isIPv6Scope(adderss, 8);
Assert.assertFalse(isScope);
isScope = AclUtils.isIPv6Scope(adderss, 4);
Assert.assertTrue(isScope);
} }
@Test @Test
...@@ -102,6 +136,18 @@ public class AclUtilsTest { ...@@ -102,6 +136,18 @@ public class AclUtilsTest {
isScope = AclUtils.isScope(256); isScope = AclUtils.isScope(256);
Assert.assertFalse(isScope); Assert.assertFalse(isScope);
// IPv6 test
int min = Integer.parseInt("0", 16);
int max = Integer.parseInt("ffff", 16);
for (int i = min; i < max + 1; i++) {
isScope = AclUtils.isIPv6Scope(i);
Assert.assertTrue(isScope);
}
isScope = AclUtils.isIPv6Scope(-1);
Assert.assertFalse(isScope);
isScope = AclUtils.isIPv6Scope(max + 1);
Assert.assertFalse(isScope);
} }
@Test @Test
...@@ -115,10 +161,10 @@ public class AclUtilsTest { ...@@ -115,10 +161,10 @@ public class AclUtilsTest {
@Test @Test
public void isColonTest() { public void isColonTest() {
boolean isColon = AclUtils.isColon(","); boolean isColon = AclUtils.isComma(",");
Assert.assertTrue(isColon); Assert.assertTrue(isColon);
isColon = AclUtils.isColon("-"); isColon = AclUtils.isComma("-");
Assert.assertFalse(isColon); Assert.assertFalse(isColon);
} }
...@@ -131,6 +177,36 @@ public class AclUtilsTest { ...@@ -131,6 +177,36 @@ public class AclUtilsTest {
Assert.assertFalse(isMinus); Assert.assertFalse(isMinus);
} }
@Test
public void v6ipProcessTest() {
String remoteAddr = "5::7:6:1-200:*";
String[] strArray = StringUtils.split(remoteAddr, ":");
Assert.assertEquals(AclUtils.v6ipProcess(remoteAddr, strArray, 3), "0005:0000:0000:0000:0007:0006");
remoteAddr = "5::7:6:1-200";
strArray = StringUtils.split(remoteAddr, ":");
Assert.assertEquals(AclUtils.v6ipProcess(remoteAddr, strArray, 3), "0005:0000:0000:0000:0000:0007:0006");
remoteAddr = "5::7:6:*";
strArray = StringUtils.split(remoteAddr, ":");
Assert.assertEquals(AclUtils.v6ipProcess(remoteAddr, strArray, 3), "0005:0000:0000:0000:0000:0007:0006");
remoteAddr = "5:7:6:*";
strArray = StringUtils.split(remoteAddr, ":");
Assert.assertEquals(AclUtils.v6ipProcess(remoteAddr, strArray, 3), "0005:0007:0006");
}
@Test
public void expandIPTest() {
Assert.assertEquals(AclUtils.expandIP("::1", 8), "0000:0000:0000:0000:0000:0000:0000:0001");
Assert.assertEquals(AclUtils.expandIP("3::", 8), "0003:0000:0000:0000:0000:0000:0000:0000");
Assert.assertEquals(AclUtils.expandIP("2::2", 8), "0002:0000:0000:0000:0000:0000:0000:0002");
Assert.assertEquals(AclUtils.expandIP("4::aac4:92", 8), "0004:0000:0000:0000:0000:0000:AAC4:0092");
Assert.assertEquals(AclUtils.expandIP("ab23:56:901a::cc6:765:bb:9011", 8), "AB23:0056:901A:0000:0CC6:0765:00BB:9011");
Assert.assertEquals(AclUtils.expandIP("ab23:56:901a:1:cc6:765:bb:9011", 8), "AB23:0056:901A:0001:0CC6:0765:00BB:9011");
Assert.assertEquals(AclUtils.expandIP("5::7:6", 6), "0005:0000:0000:0000:0007:0006");
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
public void getYamlDataObjectTest() { public void getYamlDataObjectTest() {
...@@ -140,7 +216,7 @@ public class AclUtilsTest { ...@@ -140,7 +216,7 @@ public class AclUtilsTest {
} }
@Test @Test
public void writeDataObject2YamlFileTest() throws IOException{ public void writeDataObject2YamlFileTest() throws IOException {
String targetFileName = "src/test/resources/conf/plain_write_acl.yml"; String targetFileName = "src/test/resources/conf/plain_write_acl.yml";
File transport = new File(targetFileName); File transport = new File(targetFileName);
...@@ -153,7 +229,7 @@ public class AclUtilsTest { ...@@ -153,7 +229,7 @@ public class AclUtilsTest {
List<String> globalWhiteRemoteAddrs = new ArrayList<String>(); List<String> globalWhiteRemoteAddrs = new ArrayList<String>();
globalWhiteRemoteAddrs.add("10.10.103.*"); globalWhiteRemoteAddrs.add("10.10.103.*");
globalWhiteRemoteAddrs.add("192.168.0.*"); globalWhiteRemoteAddrs.add("192.168.0.*");
aclYamlMap.put("globalWhiteRemoteAddrs",globalWhiteRemoteAddrs); aclYamlMap.put("globalWhiteRemoteAddrs", globalWhiteRemoteAddrs);
// For accounts element in acl yaml config file // For accounts element in acl yaml config file
List<Map<String, Object>> accounts = new ArrayList<Map<String, Object>>(); List<Map<String, Object>> accounts = new ArrayList<Map<String, Object>>();
...@@ -166,14 +242,14 @@ public class AclUtilsTest { ...@@ -166,14 +242,14 @@ public class AclUtilsTest {
} }
}; };
accounts.add(accountsMap); accounts.add(accountsMap);
aclYamlMap.put("accounts",accounts); aclYamlMap.put("accounts", accounts);
Assert.assertTrue(AclUtils.writeDataObject(targetFileName, aclYamlMap)); Assert.assertTrue(AclUtils.writeDataObject(targetFileName, aclYamlMap));
transport.delete(); transport.delete();
} }
@Test @Test
public void updateExistedYamlFileTest() throws IOException{ public void updateExistedYamlFileTest() throws IOException {
String targetFileName = "src/test/resources/conf/plain_update_acl.yml"; String targetFileName = "src/test/resources/conf/plain_update_acl.yml";
File transport = new File(targetFileName); File transport = new File(targetFileName);
...@@ -186,7 +262,7 @@ public class AclUtilsTest { ...@@ -186,7 +262,7 @@ public class AclUtilsTest {
List<String> globalWhiteRemoteAddrs = new ArrayList<String>(); List<String> globalWhiteRemoteAddrs = new ArrayList<String>();
globalWhiteRemoteAddrs.add("10.10.103.*"); globalWhiteRemoteAddrs.add("10.10.103.*");
globalWhiteRemoteAddrs.add("192.168.0.*"); globalWhiteRemoteAddrs.add("192.168.0.*");
aclYamlMap.put("globalWhiteRemoteAddrs",globalWhiteRemoteAddrs); aclYamlMap.put("globalWhiteRemoteAddrs", globalWhiteRemoteAddrs);
// Write file to yaml file // Write file to yaml file
AclUtils.writeDataObject(targetFileName, aclYamlMap); AclUtils.writeDataObject(targetFileName, aclYamlMap);
...@@ -201,7 +277,7 @@ public class AclUtilsTest { ...@@ -201,7 +277,7 @@ public class AclUtilsTest {
Map<String, Object> readableMap = AclUtils.getYamlDataObject(targetFileName, Map.class); Map<String, Object> readableMap = AclUtils.getYamlDataObject(targetFileName, Map.class);
List<String> updatedGlobalWhiteRemoteAddrs = (List<String>) readableMap.get("globalWhiteRemoteAddrs"); List<String> updatedGlobalWhiteRemoteAddrs = (List<String>) readableMap.get("globalWhiteRemoteAddrs");
Assert.assertEquals("192.168.1.2",updatedGlobalWhiteRemoteAddrs.get(0)); Assert.assertEquals("192.168.1.2", updatedGlobalWhiteRemoteAddrs.get(0));
transport.delete(); transport.delete();
} }
...@@ -235,5 +311,4 @@ public class AclUtilsTest { ...@@ -235,5 +311,4 @@ public class AclUtilsTest {
Assert.assertNull(incompleteContRPCHook); Assert.assertNull(incompleteContRPCHook);
} }
} }
...@@ -39,7 +39,7 @@ public class RemoteAddressStrategyTest { ...@@ -39,7 +39,7 @@ public class RemoteAddressStrategyTest {
plainAccessResource.setWhiteRemoteAddress("*"); plainAccessResource.setWhiteRemoteAddress("*");
RemoteAddressStrategy remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); RemoteAddressStrategy remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy, RemoteAddressStrategyFactory.NULL_NET_ADDRESS_STRATEGY); Assert.assertEquals(remoteAddressStrategy, RemoteAddressStrategyFactory.NULL_NET_ADDRESS_STRATEGY);
plainAccessResource.setWhiteRemoteAddress("*.*.*.*"); plainAccessResource.setWhiteRemoteAddress("*.*.*.*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy, RemoteAddressStrategyFactory.NULL_NET_ADDRESS_STRATEGY); Assert.assertEquals(remoteAddressStrategy, RemoteAddressStrategyFactory.NULL_NET_ADDRESS_STRATEGY);
...@@ -71,6 +71,35 @@ public class RemoteAddressStrategyTest { ...@@ -71,6 +71,35 @@ public class RemoteAddressStrategyTest {
plainAccessResource.setWhiteRemoteAddress(""); plainAccessResource.setWhiteRemoteAddress("");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy.getClass(), RemoteAddressStrategyFactory.BlankRemoteAddressStrategy.class); Assert.assertEquals(remoteAddressStrategy.getClass(), RemoteAddressStrategyFactory.BlankRemoteAddressStrategy.class);
// IPv6 test
plainAccessResource.setWhiteRemoteAddress("*:*:*:*:*:*:*:*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy, RemoteAddressStrategyFactory.NULL_NET_ADDRESS_STRATEGY);
plainAccessResource.setWhiteRemoteAddress("1050:0000:0000:0000:0005:0600:300c:326b");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy.getClass(), RemoteAddressStrategyFactory.OneRemoteAddressStrategy.class);
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:3261,1050::0005:0600:300c:3262,1050::0005:0600:300c:3263");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy.getClass(), RemoteAddressStrategyFactory.MultipleRemoteAddressStrategy.class);
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:3261:{1,2,3}");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy.getClass(), RemoteAddressStrategyFactory.MultipleRemoteAddressStrategy.class);
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:3261:1-200");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy.getClass(), RemoteAddressStrategyFactory.RangeRemoteAddressStrategy.class);
plainAccessResource.setWhiteRemoteAddress("1050:0005:0600:300c:3261:*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy.getClass(), RemoteAddressStrategyFactory.RangeRemoteAddressStrategy.class);
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:3261:1-20:*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
Assert.assertEquals(remoteAddressStrategy.getClass(), RemoteAddressStrategyFactory.RangeRemoteAddressStrategy.class);
} }
@Test(expected = AclException.class) @Test(expected = AclException.class)
...@@ -80,6 +109,8 @@ public class RemoteAddressStrategyTest { ...@@ -80,6 +109,8 @@ public class RemoteAddressStrategyTest {
remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
plainAccessResource.setWhiteRemoteAddress("256.0.0.1"); plainAccessResource.setWhiteRemoteAddress("256.0.0.1");
remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
plainAccessResource.setWhiteRemoteAddress("::1ggg");
remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
} }
@Test @Test
...@@ -94,6 +125,7 @@ public class RemoteAddressStrategyTest { ...@@ -94,6 +125,7 @@ public class RemoteAddressStrategyTest {
Assert.assertFalse(isMatch); Assert.assertFalse(isMatch);
} }
@Test
public void oneNetaddressStrategyTest() { public void oneNetaddressStrategyTest() {
PlainAccessResource plainAccessResource = new PlainAccessResource(); PlainAccessResource plainAccessResource = new PlainAccessResource();
plainAccessResource.setWhiteRemoteAddress("127.0.0.1"); plainAccessResource.setWhiteRemoteAddress("127.0.0.1");
...@@ -109,6 +141,26 @@ public class RemoteAddressStrategyTest { ...@@ -109,6 +141,26 @@ public class RemoteAddressStrategyTest {
plainAccessResource.setWhiteRemoteAddress("127.0.0.1"); plainAccessResource.setWhiteRemoteAddress("127.0.0.1");
match = remoteAddressStrategy.match(plainAccessResource); match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertTrue(match); Assert.assertTrue(match);
// Ipv6 test
plainAccessResource = new PlainAccessResource();
plainAccessResource.setWhiteRemoteAddress("::1");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
plainAccessResource.setWhiteRemoteAddress("");
match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertFalse(match);
plainAccessResource.setWhiteRemoteAddress("::2");
match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertFalse(match);
plainAccessResource.setWhiteRemoteAddress("::1");
match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertTrue(match);
plainAccessResource.setWhiteRemoteAddress("0000:0000:0000:0000:0000:0000:0000:0001");
match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertTrue(match);
} }
@Test @Test
...@@ -122,6 +174,21 @@ public class RemoteAddressStrategyTest { ...@@ -122,6 +174,21 @@ public class RemoteAddressStrategyTest {
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
multipleNetaddressStrategyTest(remoteAddressStrategy); multipleNetaddressStrategyTest(remoteAddressStrategy);
plainAccessResource.setWhiteRemoteAddress("192.100-150.*.*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
plainAccessResource.setWhiteRemoteAddress("192.130.0.2");
boolean match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertTrue(match);
plainAccessResource = new PlainAccessResource();
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:1,1050::0005:0600:300c:2,1050::0005:0600:300c:3");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
multipleIPv6NetaddressStrategyTest(remoteAddressStrategy);
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:{1,2,3}");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
multipleIPv6NetaddressStrategyTest(remoteAddressStrategy);
} }
@Test(expected = AclException.class) @Test(expected = AclException.class)
...@@ -129,6 +196,8 @@ public class RemoteAddressStrategyTest { ...@@ -129,6 +196,8 @@ public class RemoteAddressStrategyTest {
PlainAccessResource plainAccessResource = new PlainAccessResource(); PlainAccessResource plainAccessResource = new PlainAccessResource();
plainAccessResource.setWhiteRemoteAddress("127.0.0.1,2,3}"); plainAccessResource.setWhiteRemoteAddress("127.0.0.1,2,3}");
remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
plainAccessResource.setWhiteRemoteAddress("::1,2,3}");
remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
} }
private void multipleNetaddressStrategyTest(RemoteAddressStrategy remoteAddressStrategy) { private void multipleNetaddressStrategyTest(RemoteAddressStrategy remoteAddressStrategy) {
...@@ -155,6 +224,30 @@ public class RemoteAddressStrategyTest { ...@@ -155,6 +224,30 @@ public class RemoteAddressStrategyTest {
} }
private void multipleIPv6NetaddressStrategyTest(RemoteAddressStrategy remoteAddressStrategy) {
PlainAccessResource plainAccessResource = new PlainAccessResource();
plainAccessResource.setWhiteRemoteAddress("1050:0000:0000:0000:0005:0600:300c:1");
boolean match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertTrue(match);
plainAccessResource.setWhiteRemoteAddress("1050:0000:0000:0000:0005:0600:300c:2");
match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertTrue(match);
plainAccessResource.setWhiteRemoteAddress("1050:0000:0000:0000:0005:0600:300c:3");
match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertTrue(match);
plainAccessResource.setWhiteRemoteAddress("1050:0000:0000:0000:0005:0600:300c:4");
match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertFalse(match);
plainAccessResource.setWhiteRemoteAddress("1050:0000:0000:0000:0005:0600:300c:0");
match = remoteAddressStrategy.match(plainAccessResource);
Assert.assertFalse(match);
}
@Test @Test
public void rangeNetaddressStrategyTest() { public void rangeNetaddressStrategyTest() {
String head = "127.0.0."; String head = "127.0.0.";
...@@ -162,6 +255,7 @@ public class RemoteAddressStrategyTest { ...@@ -162,6 +255,7 @@ public class RemoteAddressStrategyTest {
plainAccessResource.setWhiteRemoteAddress("127.0.0.1-200"); plainAccessResource.setWhiteRemoteAddress("127.0.0.1-200");
RemoteAddressStrategy remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); RemoteAddressStrategy remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeNetaddressStrategyTest(remoteAddressStrategy, head, 1, 200, true); rangeNetaddressStrategyTest(remoteAddressStrategy, head, 1, 200, true);
plainAccessResource.setWhiteRemoteAddress("127.0.0.*"); plainAccessResource.setWhiteRemoteAddress("127.0.0.*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeNetaddressStrategyTest(remoteAddressStrategy, head, 0, 255, true); rangeNetaddressStrategyTest(remoteAddressStrategy, head, 0, 255, true);
...@@ -169,14 +263,40 @@ public class RemoteAddressStrategyTest { ...@@ -169,14 +263,40 @@ public class RemoteAddressStrategyTest {
plainAccessResource.setWhiteRemoteAddress("127.0.1-200.*"); plainAccessResource.setWhiteRemoteAddress("127.0.1-200.*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeNetaddressStrategyThirdlyTest(remoteAddressStrategy, head, 1, 200); rangeNetaddressStrategyThirdlyTest(remoteAddressStrategy, head, 1, 200);
plainAccessResource.setWhiteRemoteAddress("127.*.*.*"); plainAccessResource.setWhiteRemoteAddress("127.*.*.*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeNetaddressStrategyThirdlyTest(remoteAddressStrategy, head, 1, 200); rangeNetaddressStrategyTest(remoteAddressStrategy, head, 0, 255, true);
plainAccessResource.setWhiteRemoteAddress("127.1-150.*.*"); plainAccessResource.setWhiteRemoteAddress("127.1-150.*.*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource); remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeNetaddressStrategyThirdlyTest(remoteAddressStrategy, head, 1, 200); rangeNetaddressStrategyThirdlyTest(remoteAddressStrategy, head, 1, 200);
// IPv6 test
head = "1050::0005:0600:300c:";
plainAccessResource = new PlainAccessResource();
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:1-200");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeIPv6NetaddressStrategyTest(remoteAddressStrategy, head, "1", "200", true);
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeIPv6NetaddressStrategyTest(remoteAddressStrategy, head, "0", "ffff", true);
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:3001:*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeIPv6NetaddressStrategyTest(remoteAddressStrategy, head, "0", "ffff", false);
head = "1050::0005:0600:300c:1:";
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:1-200:*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeIPv6NetaddressStrategyTest(remoteAddressStrategy, head, "0", "ffff", true);
head = "1050::0005:0600:300c:201:";
plainAccessResource.setWhiteRemoteAddress("1050::0005:0600:300c:1-200:*");
remoteAddressStrategy = remoteAddressStrategyFactory.getRemoteAddressStrategy(plainAccessResource);
rangeIPv6NetaddressStrategyTest(remoteAddressStrategy, head, "0", "ffff", false);
} }
private void rangeNetaddressStrategyTest(RemoteAddressStrategy remoteAddressStrategy, String head, int start, private void rangeNetaddressStrategyTest(RemoteAddressStrategy remoteAddressStrategy, String head, int start,
...@@ -206,6 +326,25 @@ public class RemoteAddressStrategyTest { ...@@ -206,6 +326,25 @@ public class RemoteAddressStrategyTest {
} }
} }
private void rangeIPv6NetaddressStrategyTest(RemoteAddressStrategy remoteAddressStrategy, String head, String start,
String end,
boolean isFalse) {
PlainAccessResource plainAccessResource = new PlainAccessResource();
for (int i = -10; i < 65536 + 100; i++) {
String hex = Integer.toHexString(i);
plainAccessResource.setWhiteRemoteAddress(head + hex);
boolean match = remoteAddressStrategy.match(plainAccessResource);
int startNum = Integer.parseInt(start, 16);
int endNum = Integer.parseInt(end, 16);
if (isFalse && i >= startNum && i <= endNum) {
Assert.assertTrue(match);
continue;
}
Assert.assertFalse(match);
}
}
@Test(expected = AclException.class) @Test(expected = AclException.class)
public void rangeNetaddressStrategyExceptionStartGreaterEndTest() { public void rangeNetaddressStrategyExceptionStartGreaterEndTest() {
rangeNetaddressStrategyExceptionTest("127.0.0.2-1"); rangeNetaddressStrategyExceptionTest("127.0.0.2-1");
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -41,8 +41,6 @@ import org.apache.rocketmq.common.constant.PermName; ...@@ -41,8 +41,6 @@ import org.apache.rocketmq.common.constant.PermName;
import org.apache.rocketmq.common.filter.ExpressionType; import org.apache.rocketmq.common.filter.ExpressionType;
import org.apache.rocketmq.common.filter.FilterAPI; import org.apache.rocketmq.common.filter.FilterAPI;
import org.apache.rocketmq.common.help.FAQUrl; import org.apache.rocketmq.common.help.FAQUrl;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.common.message.MessageDecoder; import org.apache.rocketmq.common.message.MessageDecoder;
import org.apache.rocketmq.common.message.MessageQueue; import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.common.protocol.ResponseCode; import org.apache.rocketmq.common.protocol.ResponseCode;
...@@ -52,7 +50,10 @@ import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; ...@@ -52,7 +50,10 @@ import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData; import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData;
import org.apache.rocketmq.common.protocol.topic.OffsetMovedEvent; import org.apache.rocketmq.common.protocol.topic.OffsetMovedEvent;
import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig; import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
import org.apache.rocketmq.common.sysflag.PullSysFlag; import org.apache.rocketmq.common.sysflag.PullSysFlag;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.remoting.common.RemotingHelper; import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.common.RemotingUtil; import org.apache.rocketmq.remoting.common.RemotingUtil;
import org.apache.rocketmq.remoting.exception.RemotingCommandException; import org.apache.rocketmq.remoting.exception.RemotingCommandException;
...@@ -494,7 +495,21 @@ public class PullMessageProcessor implements NettyRequestProcessor { ...@@ -494,7 +495,21 @@ public class PullMessageProcessor implements NettyRequestProcessor {
for (ByteBuffer bb : messageBufferList) { for (ByteBuffer bb : messageBufferList) {
byteBuffer.put(bb); byteBuffer.put(bb);
storeTimestamp = bb.getLong(MessageDecoder.MESSAGE_STORE_TIMESTAMP_POSTION); int sysFlag = bb.getInt(MessageDecoder.SYSFLAG_POSITION);
// bornhost has the IPv4 ip if the MessageSysFlag.BORNHOST_V6_FLAG bit of sysFlag is 0
// IPv4 host = ip(4 byte) + port(4 byte); IPv6 host = ip(16 byte) + port(4 byte)
int bornhostLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 8 : 20;
int msgStoreTimePos = 4 // 1 TOTALSIZE
+ 4 // 2 MAGICCODE
+ 4 // 3 BODYCRC
+ 4 // 4 QUEUEID
+ 4 // 5 FLAG
+ 8 // 6 QUEUEOFFSET
+ 8 // 7 PHYSICALOFFSET
+ 4 // 8 SYSFLAG
+ 8 // 9 BORNTIMESTAMP
+ bornhostLength; // 10 BORNHOST
storeTimestamp = bb.getLong(msgStoreTimePos);
} }
} finally { } finally {
getMessageResult.release(); getMessageResult.release();
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -82,7 +82,7 @@ public interface MQAdmin { ...@@ -82,7 +82,7 @@ public interface MQAdmin {
long earliestMsgStoreTime(final MessageQueue mq) throws MQClientException; long earliestMsgStoreTime(final MessageQueue mq) throws MQClientException;
/** /**
* Query message according tto message id * Query message according to message id
* *
* @param offsetMsgId message id * @param offsetMsgId message id
* @return message * @return message
......
...@@ -94,13 +94,13 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -94,13 +94,13 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
} }
public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException { public void createTopic(String key, String newTopic, int queueNum, int topicSysFlag) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag); this.mQClientFactory.getMQAdminImpl().createTopic(key, newTopic, queueNum, topicSysFlag);
} }
private void makeSureStateOK() throws MQClientException { private void isRunning() throws MQClientException {
if (this.serviceState != ServiceState.RUNNING) { if (this.serviceState != ServiceState.RUNNING) {
throw new MQClientException("The consumer service state not OK, " throw new MQClientException("The consumer is not in running status, "
+ this.serviceState + this.serviceState
+ FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK), + FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK),
null); null);
...@@ -108,12 +108,12 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -108,12 +108,12 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
} }
public long fetchConsumeOffset(MessageQueue mq, boolean fromStore) throws MQClientException { public long fetchConsumeOffset(MessageQueue mq, boolean fromStore) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
return this.offsetStore.readOffset(mq, fromStore ? ReadOffsetType.READ_FROM_STORE : ReadOffsetType.MEMORY_FIRST_THEN_STORE); return this.offsetStore.readOffset(mq, fromStore ? ReadOffsetType.READ_FROM_STORE : ReadOffsetType.MEMORY_FIRST_THEN_STORE);
} }
public Set<MessageQueue> fetchMessageQueuesInBalance(String topic) throws MQClientException { public Set<MessageQueue> fetchMessageQueuesInBalance(String topic) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
if (null == topic) { if (null == topic) {
throw new IllegalArgumentException("topic is null"); throw new IllegalArgumentException("topic is null");
} }
...@@ -130,12 +130,12 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -130,12 +130,12 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
} }
public List<MessageQueue> fetchPublishMessageQueues(String topic) throws MQClientException { public List<MessageQueue> fetchPublishMessageQueues(String topic) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
return this.mQClientFactory.getMQAdminImpl().fetchPublishMessageQueues(topic); return this.mQClientFactory.getMQAdminImpl().fetchPublishMessageQueues(topic);
} }
public Set<MessageQueue> fetchSubscribeMessageQueues(String topic) throws MQClientException { public Set<MessageQueue> fetchSubscribeMessageQueues(String topic) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
// check if has info in memory, otherwise invoke api. // check if has info in memory, otherwise invoke api.
Set<MessageQueue> result = this.rebalanceImpl.getTopicSubscribeInfoTable().get(topic); Set<MessageQueue> result = this.rebalanceImpl.getTopicSubscribeInfoTable().get(topic);
if (null == result) { if (null == result) {
...@@ -156,17 +156,17 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -156,17 +156,17 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
} }
public long earliestMsgStoreTime(MessageQueue mq) throws MQClientException { public long earliestMsgStoreTime(MessageQueue mq) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
return this.mQClientFactory.getMQAdminImpl().earliestMsgStoreTime(mq); return this.mQClientFactory.getMQAdminImpl().earliestMsgStoreTime(mq);
} }
public long maxOffset(MessageQueue mq) throws MQClientException { public long maxOffset(MessageQueue mq) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
return this.mQClientFactory.getMQAdminImpl().maxOffset(mq); return this.mQClientFactory.getMQAdminImpl().maxOffset(mq);
} }
public long minOffset(MessageQueue mq) throws MQClientException { public long minOffset(MessageQueue mq) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
return this.mQClientFactory.getMQAdminImpl().minOffset(mq); return this.mQClientFactory.getMQAdminImpl().minOffset(mq);
} }
...@@ -225,7 +225,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -225,7 +225,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
private PullResult pullSyncImpl(MessageQueue mq, SubscriptionData subscriptionData, long offset, int maxNums, boolean block, private PullResult pullSyncImpl(MessageQueue mq, SubscriptionData subscriptionData, long offset, int maxNums, boolean block,
long timeout) long timeout)
throws MQClientException, RemotingException, MQBrokerException, InterruptedException { throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
this.makeSureStateOK(); this.isRunning();
if (null == mq) { if (null == mq) {
throw new MQClientException("mq is null", null); throw new MQClientException("mq is null", null);
...@@ -261,7 +261,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -261,7 +261,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
null null
); );
this.pullAPIWrapper.processPullResult(mq, pullResult, subscriptionData); this.pullAPIWrapper.processPullResult(mq, pullResult, subscriptionData);
//If namespace not null , reset Topic without namespace. //If namespace is not null , reset Topic without namespace.
this.resetTopic(pullResult.getMsgFoundList()); this.resetTopic(pullResult.getMsgFoundList());
if (!this.consumeMessageHookList.isEmpty()) { if (!this.consumeMessageHookList.isEmpty()) {
ConsumeMessageContext consumeMessageContext = null; ConsumeMessageContext consumeMessageContext = null;
...@@ -383,7 +383,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -383,7 +383,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
@Override @Override
public void persistConsumerOffset() { public void persistConsumerOffset() {
try { try {
this.makeSureStateOK(); this.isRunning();
Set<MessageQueue> mqs = new HashSet<MessageQueue>(); Set<MessageQueue> mqs = new HashSet<MessageQueue>();
Set<MessageQueue> allocateMq = this.rebalanceImpl.getProcessQueueTable().keySet(); Set<MessageQueue> allocateMq = this.rebalanceImpl.getProcessQueueTable().keySet();
mqs.addAll(allocateMq); mqs.addAll(allocateMq);
...@@ -466,7 +466,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -466,7 +466,7 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
final PullCallback pullCallback, final PullCallback pullCallback,
final boolean block, final boolean block,
final long timeout) throws MQClientException, RemotingException, InterruptedException { final long timeout) throws MQClientException, RemotingException, InterruptedException {
this.makeSureStateOK(); this.isRunning();
if (null == mq) { if (null == mq) {
throw new MQClientException("mq is null", null); throw new MQClientException("mq is null", null);
...@@ -543,18 +543,18 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -543,18 +543,18 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
public QueryResult queryMessage(String topic, String key, int maxNum, long begin, long end) public QueryResult queryMessage(String topic, String key, int maxNum, long begin, long end)
throws MQClientException, InterruptedException { throws MQClientException, InterruptedException {
this.makeSureStateOK(); this.isRunning();
return this.mQClientFactory.getMQAdminImpl().queryMessage(topic, key, maxNum, begin, end); return this.mQClientFactory.getMQAdminImpl().queryMessage(topic, key, maxNum, begin, end);
} }
public MessageExt queryMessageByUniqKey(String topic, String uniqKey) public MessageExt queryMessageByUniqKey(String topic, String uniqKey)
throws MQClientException, InterruptedException { throws MQClientException, InterruptedException {
this.makeSureStateOK(); this.isRunning();
return this.mQClientFactory.getMQAdminImpl().queryMessageByUniqKey(topic, uniqKey); return this.mQClientFactory.getMQAdminImpl().queryMessageByUniqKey(topic, uniqKey);
} }
public long searchOffset(MessageQueue mq, long timestamp) throws MQClientException { public long searchOffset(MessageQueue mq, long timestamp) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
return this.mQClientFactory.getMQAdminImpl().searchOffset(mq, timestamp); return this.mQClientFactory.getMQAdminImpl().searchOffset(mq, timestamp);
} }
...@@ -748,13 +748,13 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner { ...@@ -748,13 +748,13 @@ public class DefaultMQPullConsumerImpl implements MQConsumerInner {
} }
public void updateConsumeOffset(MessageQueue mq, long offset) throws MQClientException { public void updateConsumeOffset(MessageQueue mq, long offset) throws MQClientException {
this.makeSureStateOK(); this.isRunning();
this.offsetStore.updateOffset(mq, offset, false); this.offsetStore.updateOffset(mq, offset, false);
} }
public MessageExt viewMessage(String msgId) public MessageExt viewMessage(String msgId)
throws RemotingException, MQBrokerException, InterruptedException, MQClientException { throws RemotingException, MQBrokerException, InterruptedException, MQClientException {
this.makeSureStateOK(); this.isRunning();
return this.mQClientFactory.getMQAdminImpl().viewMessage(msgId); return this.mQClientFactory.getMQAdminImpl().viewMessage(msgId);
} }
......
...@@ -97,7 +97,7 @@ public class PullAPIWrapper { ...@@ -97,7 +97,7 @@ public class PullAPIWrapper {
for (MessageExt msg : msgListFilterAgain) { for (MessageExt msg : msgListFilterAgain) {
String traFlag = msg.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED); String traFlag = msg.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED);
if (traFlag != null && Boolean.parseBoolean(traFlag)) { if (Boolean.parseBoolean(traFlag)) {
msg.setTransactionId(msg.getProperty(MessageConst.PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX)); msg.setTransactionId(msg.getProperty(MessageConst.PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX));
} }
MessageAccessor.putProperty(msg, MessageConst.PROPERTY_MIN_OFFSET, MessageAccessor.putProperty(msg, MessageConst.PROPERTY_MIN_OFFSET,
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
...@@ -41,5 +41,9 @@ ...@@ -41,5 +41,9 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>
...@@ -18,7 +18,7 @@ package org.apache.rocketmq.common; ...@@ -18,7 +18,7 @@ package org.apache.rocketmq.common;
public class MQVersion { public class MQVersion {
public static final int CURRENT_VERSION = Version.V4_5_1.ordinal(); public static final int CURRENT_VERSION = Version.V4_5_2.ordinal();
public static String getVersionDesc(int value) { public static String getVersionDesc(int value) {
int length = Version.values().length; int length = Version.values().length;
......
...@@ -124,8 +124,10 @@ public class MixAll { ...@@ -124,8 +124,10 @@ public class MixAll {
public static String brokerVIPChannel(final boolean isChange, final String brokerAddr) { public static String brokerVIPChannel(final boolean isChange, final String brokerAddr) {
if (isChange) { if (isChange) {
String[] ipAndPort = brokerAddr.split(":"); int split = brokerAddr.lastIndexOf(":");
String brokerAddrNew = ipAndPort[0] + ":" + (Integer.parseInt(ipAndPort[1]) - 2); String ip = brokerAddr.substring(0, split);
String port = brokerAddr.substring(split + 1);
String brokerAddrNew = ip + ":" + (Integer.parseInt(port) - 2);
return brokerAddrNew; return brokerAddrNew;
} else { } else {
return brokerAddr; return brokerAddr;
......
...@@ -23,6 +23,7 @@ import java.io.IOException; ...@@ -23,6 +23,7 @@ import java.io.IOException;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean; import java.lang.management.RuntimeMXBean;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.text.NumberFormat; import java.text.NumberFormat;
...@@ -39,6 +40,7 @@ import java.util.zip.CRC32; ...@@ -39,6 +40,7 @@ import java.util.zip.CRC32;
import java.util.zip.DeflaterOutputStream; import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream; import java.util.zip.InflaterInputStream;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.validator.routines.InetAddressValidator;
import org.apache.rocketmq.common.constant.LoggerName; import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger; import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory; import org.apache.rocketmq.logging.InternalLoggerFactory;
...@@ -438,6 +440,18 @@ public class UtilAll { ...@@ -438,6 +440,18 @@ public class UtilAll {
return false; return false;
} }
public static boolean isInternalV6IP(byte[] ip) {
if (ip.length != 16) {
throw new RuntimeException("illegal ipv6 bytes");
}
//FEC0:0000:0000:0000:0000:0000:0000:0000/10
if (ip[0] == (byte) 254 && ip[1] >= (byte) 192) {
return true;
}
return false;
}
private static boolean ipCheck(byte[] ip) { private static boolean ipCheck(byte[] ip) {
if (ip.length != 4) { if (ip.length != 4) {
throw new RuntimeException("illegal ipv4 bytes"); throw new RuntimeException("illegal ipv4 bytes");
...@@ -474,6 +488,15 @@ public class UtilAll { ...@@ -474,6 +488,15 @@ public class UtilAll {
return false; return false;
} }
private static boolean ipV6Check(byte[] ip) {
if (ip.length != 16) {
throw new RuntimeException("illegal ipv6 bytes");
}
InetAddressValidator validator = InetAddressValidator.getInstance();
return validator.isValidInet6Address(ipToIPv6Str(ip));
}
public static String ipToIPv4Str(byte[] ip) { public static String ipToIPv4Str(byte[] ip) {
if (ip.length != 4) { if (ip.length != 4) {
return null; return null;
...@@ -483,6 +506,25 @@ public class UtilAll { ...@@ -483,6 +506,25 @@ public class UtilAll {
.append(".").append(ip[3] & 0xFF).toString(); .append(".").append(ip[3] & 0xFF).toString();
} }
public static String ipToIPv6Str(byte[] ip) {
if (ip.length != 16) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ip.length; i++) {
String hex = Integer.toHexString(ip[i] & 0xFF);
if (hex.length() < 2) {
sb.append(0);
}
sb.append(hex);
if (i % 2 == 1 && i < ip.length - 1) {
sb.append(":");
}
}
return sb.toString();
}
public static byte[] getIP() { public static byte[] getIP() {
try { try {
Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces(); Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
...@@ -504,6 +546,17 @@ public class UtilAll { ...@@ -504,6 +546,17 @@ public class UtilAll {
} }
} }
} }
} else if (ip != null && ip instanceof Inet6Address) {
byte[] ipByte = ip.getAddress();
if (ipByte.length == 16) {
if (ipV6Check(ipByte)) {
if (!isInternalV6IP(ipByte)) {
return ipByte;
} else if (internalIP == null) {
internalIP = ipByte;
}
}
}
} }
} }
} }
...@@ -532,12 +585,12 @@ public class UtilAll { ...@@ -532,12 +585,12 @@ public class UtilAll {
} }
} }
public static String List2String(List<String> list,String splitor) { public static String List2String(List<String> list, String splitor) {
if (list == null || list.size() == 0) { if (list == null || list.size() == 0) {
return null; return null;
} }
StringBuffer str = new StringBuffer(); StringBuffer str = new StringBuffer();
for (int i = 0;i < list.size();i++) { for (int i = 0; i < list.size(); i++) {
str.append(list.get(i)); str.append(list.get(i));
if (i == list.size() - 1) { if (i == list.size() - 1) {
continue; continue;
...@@ -547,7 +600,7 @@ public class UtilAll { ...@@ -547,7 +600,7 @@ public class UtilAll {
return str.toString(); return str.toString();
} }
public static List<String> String2List(String str,String splitor) { public static List<String> String2List(String str, String splitor) {
if (StringUtils.isEmpty(str)) { if (StringUtils.isEmpty(str)) {
return null; return null;
} }
......
...@@ -31,17 +31,19 @@ public class MessageClientIDSetter { ...@@ -31,17 +31,19 @@ public class MessageClientIDSetter {
private static long nextStartTime; private static long nextStartTime;
static { static {
LEN = 4 + 2 + 4 + 4 + 2; byte[] ip;
ByteBuffer tempBuffer = ByteBuffer.allocate(10);
tempBuffer.position(2);
tempBuffer.putInt(UtilAll.getPid());
tempBuffer.position(0);
try { try {
tempBuffer.put(UtilAll.getIP()); ip = UtilAll.getIP();
} catch (Exception e) { } catch (Exception e) {
tempBuffer.put(createFakeIP()); ip = createFakeIP();
} }
tempBuffer.position(6); LEN = ip.length + 2 + 4 + 4 + 2;
ByteBuffer tempBuffer = ByteBuffer.allocate(ip.length + 2 + 4);
tempBuffer.position(0);
tempBuffer.put(ip);
tempBuffer.position(ip.length);
tempBuffer.putInt(UtilAll.getPid());
tempBuffer.position(ip.length + 2);
tempBuffer.putInt(MessageClientIDSetter.class.getClassLoader().hashCode()); tempBuffer.putInt(MessageClientIDSetter.class.getClassLoader().hashCode());
FIX_STRING = UtilAll.bytes2string(tempBuffer.array()); FIX_STRING = UtilAll.bytes2string(tempBuffer.array());
setStartTime(System.currentTimeMillis()); setStartTime(System.currentTimeMillis());
...@@ -64,11 +66,12 @@ public class MessageClientIDSetter { ...@@ -64,11 +66,12 @@ public class MessageClientIDSetter {
public static Date getNearlyTimeFromID(String msgID) { public static Date getNearlyTimeFromID(String msgID) {
ByteBuffer buf = ByteBuffer.allocate(8); ByteBuffer buf = ByteBuffer.allocate(8);
byte[] bytes = UtilAll.string2bytes(msgID); byte[] bytes = UtilAll.string2bytes(msgID);
int ipLength = bytes.length == 28 ? 16 : 4;
buf.put((byte) 0); buf.put((byte) 0);
buf.put((byte) 0); buf.put((byte) 0);
buf.put((byte) 0); buf.put((byte) 0);
buf.put((byte) 0); buf.put((byte) 0);
buf.put(bytes, 10, 4); buf.put(bytes, ipLength + 2 + 4, 4);
buf.position(0); buf.position(0);
long spanMS = buf.getLong(); long spanMS = buf.getLong();
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
...@@ -89,13 +92,18 @@ public class MessageClientIDSetter { ...@@ -89,13 +92,18 @@ public class MessageClientIDSetter {
public static String getIPStrFromID(String msgID) { public static String getIPStrFromID(String msgID) {
byte[] ipBytes = getIPFromID(msgID); byte[] ipBytes = getIPFromID(msgID);
return UtilAll.ipToIPv4Str(ipBytes); if (ipBytes.length == 16) {
return UtilAll.ipToIPv6Str(ipBytes);
} else {
return UtilAll.ipToIPv4Str(ipBytes);
}
} }
public static byte[] getIPFromID(String msgID) { public static byte[] getIPFromID(String msgID) {
byte[] result = new byte[4];
byte[] bytes = UtilAll.string2bytes(msgID); byte[] bytes = UtilAll.string2bytes(msgID);
System.arraycopy(bytes, 0, result, 0, 4); int ipLength = bytes.length == 28 ? 16 : 4;
byte[] result = new byte[ipLength];
System.arraycopy(bytes, 0, result, 0, ipLength);
return result; return result;
} }
......
...@@ -16,9 +16,7 @@ ...@@ -16,9 +16,7 @@
*/ */
package org.apache.rocketmq.common.message; package org.apache.rocketmq.common.message;
import org.apache.rocketmq.common.UtilAll; import java.net.Inet4Address;
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
...@@ -29,37 +27,41 @@ import java.util.ArrayList; ...@@ -29,37 +27,41 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
public class MessageDecoder { public class MessageDecoder {
public final static int MSG_ID_LENGTH = 8 + 8; // public final static int MSG_ID_LENGTH = 8 + 8;
public final static Charset CHARSET_UTF8 = Charset.forName("UTF-8"); public final static Charset CHARSET_UTF8 = Charset.forName("UTF-8");
public final static int MESSAGE_MAGIC_CODE_POSTION = 4; public final static int MESSAGE_MAGIC_CODE_POSTION = 4;
public final static int MESSAGE_FLAG_POSTION = 16; public final static int MESSAGE_FLAG_POSTION = 16;
public final static int MESSAGE_PHYSIC_OFFSET_POSTION = 28; public final static int MESSAGE_PHYSIC_OFFSET_POSTION = 28;
public final static int MESSAGE_STORE_TIMESTAMP_POSTION = 56; // public final static int MESSAGE_STORE_TIMESTAMP_POSTION = 56;
public final static int MESSAGE_MAGIC_CODE = -626843481; public final static int MESSAGE_MAGIC_CODE = -626843481;
public static final char NAME_VALUE_SEPARATOR = 1; public static final char NAME_VALUE_SEPARATOR = 1;
public static final char PROPERTY_SEPARATOR = 2; public static final char PROPERTY_SEPARATOR = 2;
public static final int PHY_POS_POSITION = 4 + 4 + 4 + 4 + 4 + 8; public static final int PHY_POS_POSITION = 4 + 4 + 4 + 4 + 4 + 8;
public static final int BODY_SIZE_POSITION = 4 // 1 TOTALSIZE public static final int SYSFLAG_POSITION = 4 + 4 + 4 + 4 + 4 + 8 + 8;
+ 4 // 2 MAGICCODE // public static final int BODY_SIZE_POSITION = 4 // 1 TOTALSIZE
+ 4 // 3 BODYCRC // + 4 // 2 MAGICCODE
+ 4 // 4 QUEUEID // + 4 // 3 BODYCRC
+ 4 // 5 FLAG // + 4 // 4 QUEUEID
+ 8 // 6 QUEUEOFFSET // + 4 // 5 FLAG
+ 8 // 7 PHYSICALOFFSET // + 8 // 6 QUEUEOFFSET
+ 4 // 8 SYSFLAG // + 8 // 7 PHYSICALOFFSET
+ 8 // 9 BORNTIMESTAMP // + 4 // 8 SYSFLAG
+ 8 // 10 BORNHOST // + 8 // 9 BORNTIMESTAMP
+ 8 // 11 STORETIMESTAMP // + 8 // 10 BORNHOST
+ 8 // 12 STOREHOSTADDRESS // + 8 // 11 STORETIMESTAMP
+ 4 // 13 RECONSUMETIMES // + 8 // 12 STOREHOSTADDRESS
+ 8; // 14 Prepared Transaction Offset // + 4 // 13 RECONSUMETIMES
// + 8; // 14 Prepared Transaction Offset
public static String createMessageId(final ByteBuffer input, final ByteBuffer addr, final long offset) { public static String createMessageId(final ByteBuffer input, final ByteBuffer addr, final long offset) {
input.flip(); input.flip();
input.limit(MessageDecoder.MSG_ID_LENGTH); int msgIDLength = addr.limit() == 8 ? 16 : 28;
input.limit(msgIDLength);
input.put(addr); input.put(addr);
input.putLong(offset); input.putLong(offset);
...@@ -68,8 +70,9 @@ public class MessageDecoder { ...@@ -68,8 +70,9 @@ public class MessageDecoder {
} }
public static String createMessageId(SocketAddress socketAddress, long transactionIdhashCode) { public static String createMessageId(SocketAddress socketAddress, long transactionIdhashCode) {
ByteBuffer byteBuffer = ByteBuffer.allocate(MessageDecoder.MSG_ID_LENGTH);
InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress;
int msgIDLength = inetSocketAddress.getAddress() instanceof Inet4Address ? 16 : 28;
ByteBuffer byteBuffer = ByteBuffer.allocate(msgIDLength);
byteBuffer.put(inetSocketAddress.getAddress().getAddress()); byteBuffer.put(inetSocketAddress.getAddress().getAddress());
byteBuffer.putInt(inetSocketAddress.getPort()); byteBuffer.putInt(inetSocketAddress.getPort());
byteBuffer.putLong(transactionIdhashCode); byteBuffer.putLong(transactionIdhashCode);
...@@ -80,15 +83,16 @@ public class MessageDecoder { ...@@ -80,15 +83,16 @@ public class MessageDecoder {
public static MessageId decodeMessageId(final String msgId) throws UnknownHostException { public static MessageId decodeMessageId(final String msgId) throws UnknownHostException {
SocketAddress address; SocketAddress address;
long offset; long offset;
int ipLength = msgId.length() == 32 ? 4 * 2 : 16 * 2;
byte[] ip = UtilAll.string2bytes(msgId.substring(0, 8)); byte[] ip = UtilAll.string2bytes(msgId.substring(0, ipLength));
byte[] port = UtilAll.string2bytes(msgId.substring(8, 16)); byte[] port = UtilAll.string2bytes(msgId.substring(ipLength, ipLength + 8));
ByteBuffer bb = ByteBuffer.wrap(port); ByteBuffer bb = ByteBuffer.wrap(port);
int portInt = bb.getInt(0); int portInt = bb.getInt(0);
address = new InetSocketAddress(InetAddress.getByAddress(ip), portInt); address = new InetSocketAddress(InetAddress.getByAddress(ip), portInt);
// offset // offset
byte[] data = UtilAll.string2bytes(msgId.substring(16, 32)); byte[] data = UtilAll.string2bytes(msgId.substring(ipLength + 8, ipLength + 8 + 16));
bb = ByteBuffer.wrap(data); bb = ByteBuffer.wrap(data);
offset = bb.getLong(0); offset = bb.getLong(0);
...@@ -101,7 +105,24 @@ public class MessageDecoder { ...@@ -101,7 +105,24 @@ public class MessageDecoder {
* @param byteBuffer msg commit log buffer. * @param byteBuffer msg commit log buffer.
*/ */
public static Map<String, String> decodeProperties(java.nio.ByteBuffer byteBuffer) { public static Map<String, String> decodeProperties(java.nio.ByteBuffer byteBuffer) {
int topicLengthPosition = BODY_SIZE_POSITION + 4 + byteBuffer.getInt(BODY_SIZE_POSITION); int sysFlag = byteBuffer.getInt(SYSFLAG_POSITION);
int bornhostLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 8 : 20;
int storehostAddressLength = (sysFlag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 8 : 20;
int bodySizePosition = 4 // 1 TOTALSIZE
+ 4 // 2 MAGICCODE
+ 4 // 3 BODYCRC
+ 4 // 4 QUEUEID
+ 4 // 5 FLAG
+ 8 // 6 QUEUEOFFSET
+ 8 // 7 PHYSICALOFFSET
+ 4 // 8 SYSFLAG
+ 8 // 9 BORNTIMESTAMP
+ bornhostLength // 10 BORNHOST
+ 8 // 11 STORETIMESTAMP
+ storehostAddressLength // 12 STOREHOSTADDRESS
+ 4 // 13 RECONSUMETIMES
+ 8; // 14 Prepared Transaction Offset
int topicLengthPosition = bodySizePosition + 4 + byteBuffer.getInt(bodySizePosition);
byte topicLength = byteBuffer.get(topicLengthPosition); byte topicLength = byteBuffer.get(topicLengthPosition);
...@@ -139,6 +160,8 @@ public class MessageDecoder { ...@@ -139,6 +160,8 @@ public class MessageDecoder {
byte[] propertiesBytes = properties.getBytes(CHARSET_UTF8); byte[] propertiesBytes = properties.getBytes(CHARSET_UTF8);
short propertiesLength = (short) propertiesBytes.length; short propertiesLength = (short) propertiesBytes.length;
int sysFlag = messageExt.getSysFlag(); int sysFlag = messageExt.getSysFlag();
int bornhostLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 8 : 20;
int storehostAddressLength = (sysFlag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 8 : 20;
byte[] newBody = messageExt.getBody(); byte[] newBody = messageExt.getBody();
if (needCompress && (sysFlag & MessageSysFlag.COMPRESSED_FLAG) == MessageSysFlag.COMPRESSED_FLAG) { if (needCompress && (sysFlag & MessageSysFlag.COMPRESSED_FLAG) == MessageSysFlag.COMPRESSED_FLAG) {
newBody = UtilAll.compress(body, 5); newBody = UtilAll.compress(body, 5);
...@@ -158,9 +181,9 @@ public class MessageDecoder { ...@@ -158,9 +181,9 @@ public class MessageDecoder {
+ 8 // 7 PHYSICALOFFSET + 8 // 7 PHYSICALOFFSET
+ 4 // 8 SYSFLAG + 4 // 8 SYSFLAG
+ 8 // 9 BORNTIMESTAMP + 8 // 9 BORNTIMESTAMP
+ 8 // 10 BORNHOST + bornhostLength // 10 BORNHOST
+ 8 // 11 STORETIMESTAMP + 8 // 11 STORETIMESTAMP
+ 8 // 12 STOREHOSTADDRESS + storehostAddressLength // 12 STOREHOSTADDRESS
+ 4 // 13 RECONSUMETIMES + 4 // 13 RECONSUMETIMES
+ 8 // 14 Prepared Transaction Offset + 8 // 14 Prepared Transaction Offset
+ 4 + bodyLength // 14 BODY + 4 + bodyLength // 14 BODY
...@@ -291,8 +314,9 @@ public class MessageDecoder { ...@@ -291,8 +314,9 @@ public class MessageDecoder {
msgExt.setBornTimestamp(bornTimeStamp); msgExt.setBornTimestamp(bornTimeStamp);
// 10 BORNHOST // 10 BORNHOST
byte[] bornHost = new byte[4]; int bornhostIPLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 4 : 16;
byteBuffer.get(bornHost, 0, 4); byte[] bornHost = new byte[bornhostIPLength];
byteBuffer.get(bornHost, 0, bornhostIPLength);
int port = byteBuffer.getInt(); int port = byteBuffer.getInt();
msgExt.setBornHost(new InetSocketAddress(InetAddress.getByAddress(bornHost), port)); msgExt.setBornHost(new InetSocketAddress(InetAddress.getByAddress(bornHost), port));
...@@ -301,8 +325,9 @@ public class MessageDecoder { ...@@ -301,8 +325,9 @@ public class MessageDecoder {
msgExt.setStoreTimestamp(storeTimestamp); msgExt.setStoreTimestamp(storeTimestamp);
// 12 STOREHOST // 12 STOREHOST
byte[] storeHost = new byte[4]; int storehostIPLength = (sysFlag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 4 : 16;
byteBuffer.get(storeHost, 0, 4); byte[] storeHost = new byte[storehostIPLength];
byteBuffer.get(storeHost, 0, storehostIPLength);
port = byteBuffer.getInt(); port = byteBuffer.getInt();
msgExt.setStoreHost(new InetSocketAddress(InetAddress.getByAddress(storeHost), port)); msgExt.setStoreHost(new InetSocketAddress(InetAddress.getByAddress(storeHost), port));
...@@ -348,7 +373,8 @@ public class MessageDecoder { ...@@ -348,7 +373,8 @@ public class MessageDecoder {
msgExt.setProperties(map); msgExt.setProperties(map);
} }
ByteBuffer byteBufferMsgId = ByteBuffer.allocate(MSG_ID_LENGTH); int msgIDLength = storehostIPLength + 4 + 8;
ByteBuffer byteBufferMsgId = ByteBuffer.allocate(msgIDLength);
String msgId = createMessageId(byteBufferMsgId, msgExt.getStoreHostBytes(), msgExt.getCommitLogOffset()); String msgId = createMessageId(byteBufferMsgId, msgExt.getStoreHostBytes(), msgExt.getCommitLogOffset());
msgExt.setMsgId(msgId); msgExt.setMsgId(msgId);
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
*/ */
package org.apache.rocketmq.common.message; package org.apache.rocketmq.common.message;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
...@@ -66,14 +68,26 @@ public class MessageExt extends Message { ...@@ -66,14 +68,26 @@ public class MessageExt extends Message {
public static ByteBuffer socketAddress2ByteBuffer(final SocketAddress socketAddress, final ByteBuffer byteBuffer) { public static ByteBuffer socketAddress2ByteBuffer(final SocketAddress socketAddress, final ByteBuffer byteBuffer) {
InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress;
byteBuffer.put(inetSocketAddress.getAddress().getAddress(), 0, 4); InetAddress address = inetSocketAddress.getAddress();
if (address instanceof Inet4Address) {
byteBuffer.put(inetSocketAddress.getAddress().getAddress(), 0, 4);
} else {
byteBuffer.put(inetSocketAddress.getAddress().getAddress(), 0, 16);
}
byteBuffer.putInt(inetSocketAddress.getPort()); byteBuffer.putInt(inetSocketAddress.getPort());
byteBuffer.flip(); byteBuffer.flip();
return byteBuffer; return byteBuffer;
} }
public static ByteBuffer socketAddress2ByteBuffer(SocketAddress socketAddress) { public static ByteBuffer socketAddress2ByteBuffer(SocketAddress socketAddress) {
ByteBuffer byteBuffer = ByteBuffer.allocate(8); InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress;
InetAddress address = inetSocketAddress.getAddress();
ByteBuffer byteBuffer;
if (address instanceof Inet4Address) {
byteBuffer = ByteBuffer.allocate(4 + 4);
} else {
byteBuffer = ByteBuffer.allocate(16 + 4);
}
return socketAddress2ByteBuffer(socketAddress, byteBuffer); return socketAddress2ByteBuffer(socketAddress, byteBuffer);
} }
...@@ -167,6 +181,10 @@ public class MessageExt extends Message { ...@@ -167,6 +181,10 @@ public class MessageExt extends Message {
this.sysFlag = sysFlag; this.sysFlag = sysFlag;
} }
public void setStoreHostAddressV6Flag() { this.sysFlag = this.sysFlag | MessageSysFlag.STOREHOSTADDRESS_V6_FLAG; }
public void setBornHostV6Flag() { this.sysFlag = this.sysFlag | MessageSysFlag.BORNHOST_V6_FLAG; }
public int getBodyCRC() { public int getBodyCRC() {
return bodyCRC; return bodyCRC;
} }
......
...@@ -23,6 +23,8 @@ public class MessageSysFlag { ...@@ -23,6 +23,8 @@ public class MessageSysFlag {
public final static int TRANSACTION_PREPARED_TYPE = 0x1 << 2; public final static int TRANSACTION_PREPARED_TYPE = 0x1 << 2;
public final static int TRANSACTION_COMMIT_TYPE = 0x2 << 2; public final static int TRANSACTION_COMMIT_TYPE = 0x2 << 2;
public final static int TRANSACTION_ROLLBACK_TYPE = 0x3 << 2; public final static int TRANSACTION_ROLLBACK_TYPE = 0x3 << 2;
public final static int BORNHOST_V6_FLAG = 0x1 << 4;
public final static int STOREHOSTADDRESS_V6_FLAG = 0x1 << 5;
public static int getTransactionValue(final int flag) { public static int getTransactionValue(final int flag) {
return flag & TRANSACTION_ROLLBACK_TYPE; return flag & TRANSACTION_ROLLBACK_TYPE;
...@@ -35,4 +37,5 @@ public class MessageSysFlag { ...@@ -35,4 +37,5 @@ public class MessageSysFlag {
public static int clearCompressedFlag(final int flag) { public static int clearCompressedFlag(final int flag) {
return flag & (~COMPRESSED_FLAG); return flag & (~COMPRESSED_FLAG);
} }
} }
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
package org.apache.rocketmq.common.sysflag; package org.apache.rocketmq.common.sysflag;
public class PullSysFlag { public class PullSysFlag {
private final static int FLAG_COMMIT_OFFSET = 0x1 << 0; private final static int FLAG_COMMIT_OFFSET = 0x1;
private final static int FLAG_SUSPEND = 0x1 << 1; private final static int FLAG_SUSPEND = 0x1 << 1;
private final static int FLAG_SUBSCRIPTION = 0x1 << 2; private final static int FLAG_SUBSCRIPTION = 0x1 << 2;
private final static int FLAG_CLASS_FILTER = 0x1 << 3; private final static int FLAG_CLASS_FILTER = 0x1 << 3;
......
...@@ -98,6 +98,15 @@ public class UtilAllTest { ...@@ -98,6 +98,15 @@ public class UtilAllTest {
assertThat(UtilAll.isBlank("Hello")).isFalse(); assertThat(UtilAll.isBlank("Hello")).isFalse();
} }
@Test
public void testIPv6Check() {
byte[] nonInternalIp = UtilAll.string2bytes("24084004018081003FAA1DDE2B3F898A");
byte[] internalIp = UtilAll.string2bytes("FEC0000000000000000000000000FFFF");
assertThat(UtilAll.isInternalV6IP(nonInternalIp)).isFalse();
assertThat(UtilAll.isInternalV6IP(internalIp)).isTrue();
assertThat(UtilAll.ipToIPv6Str(nonInternalIp).toUpperCase()).isEqualTo("2408:4004:0180:8100:3FAA:1DDE:2B3F:898A");
}
static class DemoConfig { static class DemoConfig {
private int demoWidth = 0; private int demoWidth = 0;
private int demoLength = 0; private int demoLength = 0;
......
/*
* 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.common.message;
import java.util.Calendar;
import java.util.Date;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class MessageClientIDSetterTest {
@Test
public void testGetIPStrFromID() {
String ipv4HostMsgId = "C0A803CA00002A9F0000000000031367";
String ipv6HostMsgId = "24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0";
String v4Ip = "192.168.3.202";
String v6Ip = "2408:4004:0180:8100:3faa:1dde:2b3f:898a";
assertThat(MessageClientIDSetter.getIPStrFromID(ipv4HostMsgId)).isEqualTo(v4Ip);
assertThat(MessageClientIDSetter.getIPStrFromID(ipv6HostMsgId)).isEqualTo(v6Ip);
}
@Test
public void testGetNearlyTimeFromID() {
String ipv4HostMsgId = "C0A803CA00002A9F0000000000031367";
String ipv6HostMsgId = "24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0";
Calendar cal = Calendar.getInstance();
cal.set(2019, Calendar.AUGUST, 1);
Date date = cal.getTime();
assertThat(MessageClientIDSetter.getNearlyTimeFromID(ipv4HostMsgId)).isCloseTo(date, 24*60*60*1000);
assertThat(MessageClientIDSetter.getNearlyTimeFromID(ipv6HostMsgId)).isCloseTo(date, 24*60*60*1000);
}
}
...@@ -25,6 +25,7 @@ import java.net.UnknownHostException; ...@@ -25,6 +25,7 @@ import java.net.UnknownHostException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Map; import java.util.Map;
import static org.apache.rocketmq.common.message.MessageDecoder.createMessageId;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public class MessageDecoderTest { public class MessageDecoderTest {
...@@ -77,4 +78,172 @@ public class MessageDecoderTest { ...@@ -77,4 +78,172 @@ public class MessageDecoderTest {
assertThat("hello").isEqualTo(properties.get("b")); assertThat("hello").isEqualTo(properties.get("b"));
assertThat("3.14").isEqualTo(properties.get("c")); assertThat("3.14").isEqualTo(properties.get("c"));
} }
@Test
public void testDecodePropertiesOnIPv6Host() {
MessageExt messageExt = new MessageExt();
messageExt.setMsgId("24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0");
messageExt.setBornHostV6Flag();
messageExt.setStoreHostAddressV6Flag();
messageExt.setTopic("abc");
messageExt.setBody("hello!q!".getBytes());
try {
messageExt.setBornHost(new InetSocketAddress(InetAddress.getByName("1050:0000:0000:0000:0005:0600:300c:326b"), 0));
} catch (UnknownHostException e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
messageExt.setBornTimestamp(System.currentTimeMillis());
messageExt.setCommitLogOffset(123456);
messageExt.setPreparedTransactionOffset(0);
messageExt.setQueueId(0);
messageExt.setQueueOffset(123);
messageExt.setReconsumeTimes(0);
try {
messageExt.setStoreHost(new InetSocketAddress(InetAddress.getByName("::1"), 0));
} catch (UnknownHostException e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
messageExt.putUserProperty("a", "123");
messageExt.putUserProperty("b", "hello");
messageExt.putUserProperty("c", "3.14");
byte[] msgBytes = new byte[0];
try {
msgBytes = MessageDecoder.encode(messageExt, false);
} catch (Exception e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
ByteBuffer byteBuffer = ByteBuffer.allocate(msgBytes.length);
byteBuffer.put(msgBytes);
Map<String, String> properties = MessageDecoder.decodeProperties(byteBuffer);
assertThat(properties).isNotNull();
assertThat("123").isEqualTo(properties.get("a"));
assertThat("hello").isEqualTo(properties.get("b"));
assertThat("3.14").isEqualTo(properties.get("c"));
}
@Test
public void testEncodeAndDecode() {
MessageExt messageExt = new MessageExt();
messageExt.setMsgId("645100FA00002A9F000000489A3AA09E");
messageExt.setTopic("abc");
messageExt.setBody("hello!q!".getBytes());
try {
messageExt.setBornHost(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0));
} catch (UnknownHostException e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
messageExt.setBornTimestamp(System.currentTimeMillis());
messageExt.setCommitLogOffset(123456);
messageExt.setPreparedTransactionOffset(0);
messageExt.setQueueId(1);
messageExt.setQueueOffset(123);
messageExt.setReconsumeTimes(0);
try {
messageExt.setStoreHost(new InetSocketAddress(InetAddress.getLocalHost(), 0));
} catch (UnknownHostException e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
messageExt.putUserProperty("a", "123");
messageExt.putUserProperty("b", "hello");
messageExt.putUserProperty("c", "3.14");
byte[] msgBytes = new byte[0];
try {
msgBytes = MessageDecoder.encode(messageExt, false);
} catch (Exception e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
ByteBuffer byteBuffer = ByteBuffer.allocate(msgBytes.length);
byteBuffer.put(msgBytes);
byteBuffer.clear();
MessageExt decodedMsg = MessageDecoder.decode(byteBuffer);
assertThat(decodedMsg).isNotNull();
assertThat(1).isEqualTo(decodedMsg.getQueueId());
assertThat(123456L).isEqualTo(decodedMsg.getCommitLogOffset());
assertThat("hello!q!".getBytes()).isEqualTo(decodedMsg.getBody());
int msgIDLength = 4 + 4 + 8;
ByteBuffer byteBufferMsgId = ByteBuffer.allocate(msgIDLength);
String msgId = createMessageId(byteBufferMsgId, messageExt.getStoreHostBytes(), messageExt.getCommitLogOffset());
assertThat(msgId).isEqualTo(decodedMsg.getMsgId());
assertThat("abc").isEqualTo(decodedMsg.getTopic());
}
@Test
public void testEncodeAndDecodeOnIPv6Host() {
MessageExt messageExt = new MessageExt();
messageExt.setMsgId("24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0");
messageExt.setBornHostV6Flag();
messageExt.setStoreHostAddressV6Flag();
messageExt.setTopic("abc");
messageExt.setBody("hello!q!".getBytes());
try {
messageExt.setBornHost(new InetSocketAddress(InetAddress.getByName("1050:0000:0000:0000:0005:0600:300c:326b"), 0));
} catch (UnknownHostException e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
messageExt.setBornTimestamp(System.currentTimeMillis());
messageExt.setCommitLogOffset(123456);
messageExt.setPreparedTransactionOffset(0);
messageExt.setQueueId(1);
messageExt.setQueueOffset(123);
messageExt.setReconsumeTimes(0);
try {
messageExt.setStoreHost(new InetSocketAddress(InetAddress.getByName("::1"), 0));
} catch (UnknownHostException e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
messageExt.putUserProperty("a", "123");
messageExt.putUserProperty("b", "hello");
messageExt.putUserProperty("c", "3.14");
byte[] msgBytes = new byte[0];
try {
msgBytes = MessageDecoder.encode(messageExt, false);
} catch (Exception e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
ByteBuffer byteBuffer = ByteBuffer.allocate(msgBytes.length);
byteBuffer.put(msgBytes);
byteBuffer.clear();
MessageExt decodedMsg = MessageDecoder.decode(byteBuffer);
assertThat(decodedMsg).isNotNull();
assertThat(1).isEqualTo(decodedMsg.getQueueId());
assertThat(123456L).isEqualTo(decodedMsg.getCommitLogOffset());
assertThat("hello!q!".getBytes()).isEqualTo(decodedMsg.getBody());
assertThat(48).isEqualTo(decodedMsg.getSysFlag());
int msgIDLength = 16 + 4 + 8;
ByteBuffer byteBufferMsgId = ByteBuffer.allocate(msgIDLength);
String msgId = createMessageId(byteBufferMsgId, messageExt.getStoreHostBytes(), messageExt.getCommitLogOffset());
assertThat(msgId).isEqualTo(decodedMsg.getMsgId());
assertThat("abc").isEqualTo(decodedMsg.getTopic());
}
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.rocketmq.common.protocol; package org.apache.rocketmq.common.protocol.route;
import org.apache.rocketmq.common.protocol.route.BrokerData; import org.apache.rocketmq.common.protocol.route.BrokerData;
......
...@@ -24,13 +24,41 @@ fi ...@@ -24,13 +24,41 @@ fi
BASE_DIR=$(dirname $0)/.. BASE_DIR=$(dirname $0)/..
CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH} CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH}
# The RAMDisk initializing size in MB on Darwin OS for gc-log
DIR_SIZE_IN_MB=600
choose_gc_log_directory()
{
case "`uname`" in
Darwin)
if [ ! -d "/Volumes/RAMDisk" ]; then
# create ram disk on Darwin systems as gc-log directory
DEV=`hdiutil attach -nomount ram://$((2 * 1024 * DIR_SIZE_IN_MB))` > /dev/null
diskutil eraseVolume HFS+ RAMDisk ${DEV} > /dev/null
echo "Create RAMDisk /Volumes/RAMDisk for gc logging on Darwin OS."
fi
GC_LOG_DIR="/Volumes/RAMDisk"
;;
*)
# check if /dev/shm exists on other systems
if [ -d "/dev/shm" ]; then
GC_LOG_DIR="/dev/shm"
else
GC_LOG_DIR=${BASE_DIR}
fi
;;
esac
}
choose_gc_log_directory
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn256m -XX:PermSize=128m -XX:MaxPermSize=320m" JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn256m -XX:PermSize=128m -XX:MaxPermSize=320m"
JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:+DisableExplicitGC" JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:+DisableExplicitGC"
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/rmq_srv_gc.log -XX:+PrintGCDetails" JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${GC_LOG_DIR}/rmq_run_class_gc_%p_%t.log -XX:+PrintGCDetails"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib" JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages" JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
JAVA_OPT="${JAVA_OPT} -XX:+PerfDisableSharedMem" JAVA_OPT="${JAVA_OPT} -XX:+PerfDisableSharedMem"
#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n" #JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}" JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
......
<!--
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.
-->
<java>
<debug>false</debug>
<javahome>${JAVA_HOME}</javahome>
<jvmtype>server</jvmtype>
<mainclass>org.apache.rocketmq.tools.command.MQAdminStartup</mainclass>
<properties>
<java.ext.dirs>${cpd}/../lib</java.ext.dirs>
<rocketmq.home.dir>${cpd}/..</rocketmq.home.dir>
</properties>
<classpaths>
</classpaths>
<options>
<-Xms512m></-Xms512m>
<-Xmx1g></-Xmx1g>
<-XX:NewSize>256M</-XX:NewSize>
<-XX:MaxNewSize>512M</-XX:MaxNewSize>
<-XX:PermSize>128M</-XX:PermSize>
<-XX:MaxPermSize>128M</-XX:MaxPermSize>
</options>
</java>
<!--
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.
-->
<java>
<debug>false</debug>
<javahome>${JAVA_HOME}</javahome>
<jvmtype>server</jvmtype>
<mainclass>org.apache.rocketmq.broker.BrokerStartup</mainclass>
<properties>
<java.ext.dirs>${cpd}/../lib</java.ext.dirs>
<rocketmq.home.dir>${cpd}/..</rocketmq.home.dir>
</properties>
<classpaths>
</classpaths>
<options>
<-Xms512m>
</-Xms512m>
<-Xmx1g>
</-Xmx1g>
<-XX:NewSize>256M</-XX:NewSize>
<-XX:MaxNewSize>512M</-XX:MaxNewSize>
<-XX:PermSize>128M</-XX:PermSize>
<-XX:MaxPermSize>128M</-XX:MaxPermSize>
</options>
</java>
<!--
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.
-->
<java>
<debug>false</debug>
<javahome>${JAVA_HOME}</javahome>
<jvmtype>server</jvmtype>
<mainclass>org.apache.rocketmq.namesrv.NamesrvStartup</mainclass>
<properties>
<java.ext.dirs>${cpd}/../lib</java.ext.dirs>
<rocketmq.home.dir>${cpd}/..</rocketmq.home.dir>
</properties>
<classpaths>
</classpaths>
<options>
<-Xms512m>
</-Xms512m>
<-Xmx1g>
</-Xmx1g>
<-XX:NewSize>256M</-XX:NewSize>
<-XX:MaxNewSize>512M</-XX:MaxNewSize>
<-XX:PermSize>128M</-XX:PermSize>
<-XX:MaxPermSize>128M</-XX:MaxPermSize>
</options>
</java>
...@@ -36,9 +36,37 @@ export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH} ...@@ -36,9 +36,37 @@ export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH}
#=========================================================================================== #===========================================================================================
# JVM Configuration # JVM Configuration
#=========================================================================================== #===========================================================================================
# The RAMDisk initializing size in MB on Darwin OS for gc-log
DIR_SIZE_IN_MB=600
choose_gc_log_directory()
{
case "`uname`" in
Darwin)
if [ ! -d "/Volumes/RAMDisk" ]; then
# create ram disk on Darwin systems as gc-log directory
DEV=`hdiutil attach -nomount ram://$((2 * 1024 * DIR_SIZE_IN_MB))` > /dev/null
diskutil eraseVolume HFS+ RAMDisk ${DEV} > /dev/null
echo "Create RAMDisk /Volumes/RAMDisk for gc logging on Darwin OS."
fi
GC_LOG_DIR="/Volumes/RAMDisk"
;;
*)
# check if /dev/shm exists on other systems
if [ -d "/dev/shm" ]; then
GC_LOG_DIR="/dev/shm"
else
GC_LOG_DIR=${BASE_DIR}
fi
;;
esac
}
choose_gc_log_directory
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g" JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0" JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0"
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${GC_LOG_DIR}/rmq_broker_gc_%p_%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch"
......
...@@ -36,11 +36,40 @@ export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH} ...@@ -36,11 +36,40 @@ export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH}
#=========================================================================================== #===========================================================================================
# JVM Configuration # JVM Configuration
#=========================================================================================== #===========================================================================================
# The RAMDisk initializing size in MB on Darwin OS for gc-log
DIR_SIZE_IN_MB=600
choose_gc_log_directory()
{
case "`uname`" in
Darwin)
if [ ! -d "/Volumes/RAMDisk" ]; then
# create ram disk on Darwin systems as gc-log directory
DEV=`hdiutil attach -nomount ram://$((2 * 1024 * DIR_SIZE_IN_MB))` > /dev/null
diskutil eraseVolume HFS+ RAMDisk ${DEV} > /dev/null
echo "Create RAMDisk /Volumes/RAMDisk for gc logging on Darwin OS."
fi
GC_LOG_DIR="/Volumes/RAMDisk"
;;
*)
# check if /dev/shm exists on other systems
if [ -d "/dev/shm" ]; then
GC_LOG_DIR="/dev/shm"
else
GC_LOG_DIR=${BASE_DIR}
fi
;;
esac
}
choose_gc_log_directory
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC" JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC"
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/rmq_srv_gc.log -XX:+PrintGCDetails" JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${GC_LOG_DIR}/rmq_srv_gc_%p_%t.log -XX:+PrintGCDetails"
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages" JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib" JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib"
#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n" #JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}" JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
......
...@@ -28,7 +28,7 @@ set CLASSPATH=.;%BASE_DIR%conf;%CLASSPATH% ...@@ -28,7 +28,7 @@ set CLASSPATH=.;%BASE_DIR%conf;%CLASSPATH%
rem =========================================================================================== rem ===========================================================================================
rem JVM Configuration rem JVM Configuration
rem =========================================================================================== rem ===========================================================================================
set "JAVA_OPT=%JAVA_OPT% -server -Xms1g -Xmx1g -Xmn256m -XX:PermSize=128m -XX:MaxPermSize=128m" set "JAVA_OPT=%JAVA_OPT% -server -Xms1g -Xmx1g -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m"
set "JAVA_OPT=%JAVA_OPT% -Djava.ext.dirs="%BASE_DIR%\lib";"%JAVA_HOME%\jre\lib\ext";"%JAVA_HOME%\lib\ext"" set "JAVA_OPT=%JAVA_OPT% -Djava.ext.dirs="%BASE_DIR%\lib";"%JAVA_HOME%\jre\lib\ext";"%JAVA_HOME%\lib\ext""
set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%"" set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%""
......
...@@ -36,7 +36,7 @@ export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH} ...@@ -36,7 +36,7 @@ export CLASSPATH=.:${BASE_DIR}/conf:${CLASSPATH}
#=========================================================================================== #===========================================================================================
# JVM Configuration # JVM Configuration
#=========================================================================================== #===========================================================================================
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn256m -XX:PermSize=128m -XX:MaxPermSize=128m" JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m"
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib:${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext" JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib:${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}" JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>rocketmq-distribution</artifactId> <artifactId>rocketmq-distribution</artifactId>
<name>rocketmq-distribution ${project.version}</name> <name>rocketmq-distribution ${project.version}</name>
......
Apache RocketMQ开发者指南 Apache RocketMQ开发者指南
-------- --------
##### 这个开发者指南是帮忙您快速了解,并使用 Apache RocketMQ ##### 这个开发者指南是帮忙您快速了解,并使用 Apache RocketMQ
...@@ -14,7 +14,7 @@ Apache RocketMQ开发者指南 ...@@ -14,7 +14,7 @@ Apache RocketMQ开发者指南
- [架构(Architecture)](architecture.md):介绍RocketMQ部署架构和技术架构。 - [架构(Architecture)](architecture.md):介绍RocketMQ部署架构和技术架构。
- [设计(Design)](design.md):介绍RocketMQ关键机制的设计原理,主要包括消息存储、通信机制、消息过滤、负载均衡、事消息等。 - [设计(Design)](design.md):介绍RocketMQ关键机制的设计原理,主要包括消息存储、通信机制、消息过滤、负载均衡、事消息等。
### 3. 样例 ### 3. 样例
......
...@@ -289,7 +289,6 @@ DefaultMQProducer、TransactionMQProducer、DefaultMQPushConsumer、DefaultMQPul ...@@ -289,7 +289,6 @@ DefaultMQProducer、TransactionMQProducer、DefaultMQPushConsumer、DefaultMQPul
| offsetStore | | 消费进度存储 | | offsetStore | | 消费进度存储 |
| consumeThreadMin | 10 | 消费线程池最小线程数 | | consumeThreadMin | 10 | 消费线程池最小线程数 |
| consumeThreadMax | 20 | 消费线程池最大线程数 | | consumeThreadMax | 20 | 消费线程池最大线程数 |
| | | |
| consumeConcurrentlyMaxSpan | 2000 | 单队列并行消费允许的最大跨度 | | consumeConcurrentlyMaxSpan | 2000 | 单队列并行消费允许的最大跨度 |
| pullThresholdForQueue | 1000 | 拉消息本地队列缓存消息最大数 | | pullThresholdForQueue | 1000 | 拉消息本地队列缓存消息最大数 |
| pullInterval | 0 | 拉消息间隔,由于是长轮询,所以为0,但是如果应用为了流控,也可以设置大于0的值,单位毫秒 | | pullInterval | 0 | 拉消息间隔,由于是长轮询,所以为0,但是如果应用为了流控,也可以设置大于0的值,单位毫秒 |
......
...@@ -43,11 +43,8 @@ RocketMQ主要由 Producer、Broker、Consumer 三部分组成,其中Producer ...@@ -43,11 +43,8 @@ RocketMQ主要由 Producer、Broker、Consumer 三部分组成,其中Producer
## 14 严格顺序消息(Strictly Ordered Message) ## 14 严格顺序消息(Strictly Ordered Message)
严格顺序消息模式下,消费者收到的所有消息均是有顺序的。 严格顺序消息模式下,消费者收到的所有消息均是有顺序的。
## 15 代理服务器(Broker Server) ## 15 消息(Message)
消息中转角色,负责存储消息、转发消息。代理服务器在RocketMQ系统中负责接收从生产者发送来的消息并存储、同时为消费者的拉取请求作准备。代理服务器也存储消息相关的元数据,包括消费者组、消费进度偏移和主题和队列消息等。
## 16 消息(Message)
消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。RocketMQ中每个消息拥有唯一的Message ID,且可以携带具有业务标识的Key。系统提供了通过Message ID和Key查询消息的功能。 消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。RocketMQ中每个消息拥有唯一的Message ID,且可以携带具有业务标识的Key。系统提供了通过Message ID和Key查询消息的功能。
## 17 标签(Tag) ## 16 标签(Tag)
为消息设置的标志,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。 为消息设置的标志,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
- 分区顺序 - 分区顺序
对于指定的一个 Topic,所有消息根据 sharding key 进行区块分区。 同一个分区内的消息按照严格的 FIFO 顺序进行发布和消费。 Sharding key 是顺序消息中用来区分不同分区的关键字段,和普通消息的 Key 是完全不同的概念。 对于指定的一个 Topic,所有消息根据 sharding key 进行区块分区。 同一个分区内的消息按照严格的 FIFO 顺序进行发布和消费。 Sharding key 是顺序消息中用来区分不同分区的关键字段,和普通消息的 Key 是完全不同的概念。
适用场景:性能要求高,以 sharding key 作为分区字段,在同一个区块中严格的按照 FIFO 原则进行消息发布和消费的场景。 适用场景:性能要求高,以 sharding key 作为分区字段,在同一个区块中严格的按照 FIFO 原则进行消息发布和消费的场景。
##3 消息过滤 ## 3 消息过滤
RocketMQ的消费者可以根据Tag进行消息过滤,也支持自定义属性过滤。消息过滤目前是在Broker端实现的,优点是减少了对于Consumer无用消息的网络传输,缺点是增加了Broker的负担、而且实现相对复杂。 RocketMQ的消费者可以根据Tag进行消息过滤,也支持自定义属性过滤。消息过滤目前是在Broker端实现的,优点是减少了对于Consumer无用消息的网络传输,缺点是增加了Broker的负担、而且实现相对复杂。
## 4 消息可靠性 ## 4 消息可靠性
RocketMQ支持消息的高可靠,影响消息可靠性的几种情况: RocketMQ支持消息的高可靠,影响消息可靠性的几种情况:
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
...@@ -51,12 +51,12 @@ ...@@ -51,12 +51,12 @@
<dependency> <dependency>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-openmessaging</artifactId> <artifactId>rocketmq-openmessaging</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-acl</artifactId> <artifactId>rocketmq-acl</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<parent> <parent>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>rocketmq-logappender</artifactId> <artifactId>rocketmq-logappender</artifactId>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<parent> <parent>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
limitations under the License. limitations under the License.
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent> <parent>
<groupId>org.apache</groupId> <groupId>org.apache</groupId>
...@@ -29,7 +30,7 @@ ...@@ -29,7 +30,7 @@
<inceptionYear>2012</inceptionYear> <inceptionYear>2012</inceptionYear>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Apache RocketMQ ${project.version}</name> <name>Apache RocketMQ ${project.version}</name>
<url>http://rocketmq.apache.org/</url> <url>http://rocketmq.apache.org/</url>
...@@ -158,7 +159,7 @@ ...@@ -158,7 +159,7 @@
</executions> </executions>
<configuration> <configuration>
<rules> <rules>
<banCircularDependencies /> <banCircularDependencies/>
</rules> </rules>
<fail>true</fail> <fail>true</fail>
</configuration> </configuration>
...@@ -607,6 +608,13 @@ ...@@ -607,6 +608,13 @@
<artifactId>log4j-slf4j-impl</artifactId> <artifactId>log4j-slf4j-impl</artifactId>
<version>2.7</version> <version>2.7</version>
</dependency> </dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.6</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
</project> </project>
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -17,18 +17,17 @@ ...@@ -17,18 +17,17 @@
package org.apache.rocketmq.remoting.common; package org.apache.rocketmq.remoting.common;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import org.apache.rocketmq.remoting.exception.RemotingConnectException;
import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.remoting.exception.RemotingConnectException;
import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
import org.apache.rocketmq.remoting.protocol.RemotingCommand;
public class RemotingHelper { public class RemotingHelper {
public static final String ROCKETMQ_REMOTING = "RocketmqRemoting"; public static final String ROCKETMQ_REMOTING = "RocketmqRemoting";
...@@ -53,8 +52,10 @@ public class RemotingHelper { ...@@ -53,8 +52,10 @@ public class RemotingHelper {
} }
public static SocketAddress string2SocketAddress(final String addr) { public static SocketAddress string2SocketAddress(final String addr) {
String[] s = addr.split(":"); int split = addr.lastIndexOf(":");
InetSocketAddress isa = new InetSocketAddress(s[0], Integer.parseInt(s[1])); String host = addr.substring(0, split);
String port = addr.substring(split + 1);
InetSocketAddress isa = new InetSocketAddress(host, Integer.parseInt(port));
return isa; return isa;
} }
......
...@@ -31,7 +31,6 @@ import java.nio.channels.SocketChannel; ...@@ -31,7 +31,6 @@ import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider; import java.nio.channels.spi.SelectorProvider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import org.apache.rocketmq.logging.InternalLogger; import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory; import org.apache.rocketmq.logging.InternalLoggerFactory;
...@@ -145,8 +144,10 @@ public class RemotingUtil { ...@@ -145,8 +144,10 @@ public class RemotingUtil {
} }
public static SocketAddress string2SocketAddress(final String addr) { public static SocketAddress string2SocketAddress(final String addr) {
String[] s = addr.split(":"); int split = addr.lastIndexOf(":");
InetSocketAddress isa = new InetSocketAddress(s[0], Integer.parseInt(s[1])); String host = addr.substring(0, split);
String port = addr.substring(split + 1);
InetSocketAddress isa = new InetSocketAddress(host, Integer.parseInt(port));
return isa; return isa;
} }
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
*/ */
package org.apache.rocketmq.store; package org.apache.rocketmq.store;
import java.net.Inet6Address;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
...@@ -26,14 +28,14 @@ import java.util.concurrent.TimeUnit; ...@@ -26,14 +28,14 @@ import java.util.concurrent.TimeUnit;
import org.apache.rocketmq.common.ServiceThread; import org.apache.rocketmq.common.ServiceThread;
import org.apache.rocketmq.common.UtilAll; import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.constant.LoggerName; import org.apache.rocketmq.common.constant.LoggerName;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.common.message.MessageAccessor; import org.apache.rocketmq.common.message.MessageAccessor;
import org.apache.rocketmq.common.message.MessageConst; import org.apache.rocketmq.common.message.MessageConst;
import org.apache.rocketmq.common.message.MessageDecoder; import org.apache.rocketmq.common.message.MessageDecoder;
import org.apache.rocketmq.common.message.MessageExt; import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageExtBatch; import org.apache.rocketmq.common.message.MessageExtBatch;
import org.apache.rocketmq.common.sysflag.MessageSysFlag; import org.apache.rocketmq.common.sysflag.MessageSysFlag;
import org.apache.rocketmq.logging.InternalLogger;
import org.apache.rocketmq.logging.InternalLoggerFactory;
import org.apache.rocketmq.store.config.BrokerRole; import org.apache.rocketmq.store.config.BrokerRole;
import org.apache.rocketmq.store.config.FlushDiskType; import org.apache.rocketmq.store.config.FlushDiskType;
import org.apache.rocketmq.store.ha.HAService; import org.apache.rocketmq.store.ha.HAService;
...@@ -270,11 +272,21 @@ public class CommitLog { ...@@ -270,11 +272,21 @@ public class CommitLog {
long bornTimeStamp = byteBuffer.getLong(); long bornTimeStamp = byteBuffer.getLong();
ByteBuffer byteBuffer1 = byteBuffer.get(bytesContent, 0, 8); ByteBuffer byteBuffer1;
if ((sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0) {
byteBuffer1 = byteBuffer.get(bytesContent, 0, 4 + 4);
} else {
byteBuffer1 = byteBuffer.get(bytesContent, 0, 16 + 4);
}
long storeTimestamp = byteBuffer.getLong(); long storeTimestamp = byteBuffer.getLong();
ByteBuffer byteBuffer2 = byteBuffer.get(bytesContent, 0, 8); ByteBuffer byteBuffer2;
if ((sysFlag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0) {
byteBuffer2 = byteBuffer.get(bytesContent, 0, 4 + 4);
} else {
byteBuffer2 = byteBuffer.get(bytesContent, 0, 16 + 4);
}
int reconsumeTimes = byteBuffer.getInt(); int reconsumeTimes = byteBuffer.getInt();
...@@ -339,7 +351,7 @@ public class CommitLog { ...@@ -339,7 +351,7 @@ public class CommitLog {
} }
} }
int readLength = calMsgLength(bodyLen, topicLen, propertiesLength); int readLength = calMsgLength(sysFlag, bodyLen, topicLen, propertiesLength);
if (totalSize != readLength) { if (totalSize != readLength) {
doNothingForDeadCode(reconsumeTimes); doNothingForDeadCode(reconsumeTimes);
doNothingForDeadCode(flag); doNothingForDeadCode(flag);
...@@ -372,7 +384,9 @@ public class CommitLog { ...@@ -372,7 +384,9 @@ public class CommitLog {
return new DispatchRequest(-1, false /* success */); return new DispatchRequest(-1, false /* success */);
} }
protected static int calMsgLength(int bodyLength, int topicLength, int propertiesLength) { protected static int calMsgLength(int sysFlag, int bodyLength, int topicLength, int propertiesLength) {
int bornhostLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 8 : 20;
int storehostAddressLength = (sysFlag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 8 : 20;
final int msgLen = 4 //TOTALSIZE final int msgLen = 4 //TOTALSIZE
+ 4 //MAGICCODE + 4 //MAGICCODE
+ 4 //BODYCRC + 4 //BODYCRC
...@@ -382,9 +396,9 @@ public class CommitLog { ...@@ -382,9 +396,9 @@ public class CommitLog {
+ 8 //PHYSICALOFFSET + 8 //PHYSICALOFFSET
+ 4 //SYSFLAG + 4 //SYSFLAG
+ 8 //BORNTIMESTAMP + 8 //BORNTIMESTAMP
+ 8 //BORNHOST + bornhostLength //BORNHOST
+ 8 //STORETIMESTAMP + 8 //STORETIMESTAMP
+ 8 //STOREHOSTADDRESS + storehostAddressLength //STOREHOSTADDRESS
+ 4 //RECONSUMETIMES + 4 //RECONSUMETIMES
+ 8 //Prepared Transaction Offset + 8 //Prepared Transaction Offset
+ 4 + (bodyLength > 0 ? bodyLength : 0) //BODY + 4 + (bodyLength > 0 ? bodyLength : 0) //BODY
...@@ -496,7 +510,10 @@ public class CommitLog { ...@@ -496,7 +510,10 @@ public class CommitLog {
return false; return false;
} }
long storeTimestamp = byteBuffer.getLong(MessageDecoder.MESSAGE_STORE_TIMESTAMP_POSTION); int sysFlag = byteBuffer.getInt(MessageDecoder.SYSFLAG_POSITION);
int bornhostLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 8 : 20;
int msgStoreTimePos = 4 + 4 + 4 + 4 + 4 + 8 + 8 + 4 + 8 + bornhostLength;
long storeTimestamp = byteBuffer.getLong(msgStoreTimePos);
if (0 == storeTimestamp) { if (0 == storeTimestamp) {
return false; return false;
} }
...@@ -569,7 +586,18 @@ public class CommitLog { ...@@ -569,7 +586,18 @@ public class CommitLog {
} }
} }
long elapsedTimeInLock = 0; InetSocketAddress bornSocketAddress = (InetSocketAddress) msg.getBornHost();
if (bornSocketAddress.getAddress() instanceof Inet6Address) {
msg.setBornHostV6Flag();
}
InetSocketAddress storeSocketAddress = (InetSocketAddress) msg.getStoreHost();
if (storeSocketAddress.getAddress() instanceof Inet6Address) {
msg.setStoreHostAddressV6Flag();
}
long eclipsedTimeInLock = 0;
MappedFile unlockMappedFile = null; MappedFile unlockMappedFile = null;
MappedFile mappedFile = this.mappedFileQueue.getLastMappedFile(); MappedFile mappedFile = this.mappedFileQueue.getLastMappedFile();
...@@ -619,14 +647,14 @@ public class CommitLog { ...@@ -619,14 +647,14 @@ public class CommitLog {
return new PutMessageResult(PutMessageStatus.UNKNOWN_ERROR, result); return new PutMessageResult(PutMessageStatus.UNKNOWN_ERROR, result);
} }
elapsedTimeInLock = this.defaultMessageStore.getSystemClock().now() - beginLockTimestamp; eclipsedTimeInLock = this.defaultMessageStore.getSystemClock().now() - beginLockTimestamp;
beginTimeInLock = 0; beginTimeInLock = 0;
} finally { } finally {
putMessageLock.unlock(); putMessageLock.unlock();
} }
if (elapsedTimeInLock > 500) { if (eclipsedTimeInLock > 500) {
log.warn("[NOTIFYME]putMessage in lock cost time(ms)={}, bodyLength={} AppendMessageResult={}", elapsedTimeInLock, msg.getBody().length, result); log.warn("[NOTIFYME]putMessage in lock cost time(ms)={}, bodyLength={} AppendMessageResult={}", eclipsedTimeInLock, msg.getBody().length, result);
} }
if (null != unlockMappedFile && this.defaultMessageStore.getMessageStoreConfig().isWarmMapedFileEnable()) { if (null != unlockMappedFile && this.defaultMessageStore.getMessageStoreConfig().isWarmMapedFileEnable()) {
...@@ -714,7 +742,17 @@ public class CommitLog { ...@@ -714,7 +742,17 @@ public class CommitLog {
return new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, null); return new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, null);
} }
long elapsedTimeInLock = 0; InetSocketAddress bornSocketAddress = (InetSocketAddress) messageExtBatch.getBornHost();
if (bornSocketAddress.getAddress() instanceof Inet6Address) {
messageExtBatch.setBornHostV6Flag();
}
InetSocketAddress storeSocketAddress = (InetSocketAddress) messageExtBatch.getStoreHost();
if (storeSocketAddress.getAddress() instanceof Inet6Address) {
messageExtBatch.setStoreHostAddressV6Flag();
}
long eclipsedTimeInLock = 0;
MappedFile unlockMappedFile = null; MappedFile unlockMappedFile = null;
MappedFile mappedFile = this.mappedFileQueue.getLastMappedFile(); MappedFile mappedFile = this.mappedFileQueue.getLastMappedFile();
...@@ -769,14 +807,14 @@ public class CommitLog { ...@@ -769,14 +807,14 @@ public class CommitLog {
return new PutMessageResult(PutMessageStatus.UNKNOWN_ERROR, result); return new PutMessageResult(PutMessageStatus.UNKNOWN_ERROR, result);
} }
elapsedTimeInLock = this.defaultMessageStore.getSystemClock().now() - beginLockTimestamp; eclipsedTimeInLock = this.defaultMessageStore.getSystemClock().now() - beginLockTimestamp;
beginTimeInLock = 0; beginTimeInLock = 0;
} finally { } finally {
putMessageLock.unlock(); putMessageLock.unlock();
} }
if (elapsedTimeInLock > 500) { if (eclipsedTimeInLock > 500) {
log.warn("[NOTIFYME]putMessages in lock cost time(ms)={}, bodyLength={} AppendMessageResult={}", elapsedTimeInLock, messageExtBatch.getBody().length, result); log.warn("[NOTIFYME]putMessages in lock cost time(ms)={}, bodyLength={} AppendMessageResult={}", eclipsedTimeInLock, messageExtBatch.getBody().length, result);
} }
if (null != unlockMappedFile && this.defaultMessageStore.getMessageStoreConfig().isWarmMapedFileEnable()) { if (null != unlockMappedFile && this.defaultMessageStore.getMessageStoreConfig().isWarmMapedFileEnable()) {
...@@ -804,7 +842,10 @@ public class CommitLog { ...@@ -804,7 +842,10 @@ public class CommitLog {
SelectMappedBufferResult result = this.getMessage(offset, size); SelectMappedBufferResult result = this.getMessage(offset, size);
if (null != result) { if (null != result) {
try { try {
return result.getByteBuffer().getLong(MessageDecoder.MESSAGE_STORE_TIMESTAMP_POSTION); int sysFlag = result.getByteBuffer().getInt(MessageDecoder.SYSFLAG_POSITION);
int bornhostLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 8 : 20;
int msgStoreTimePos = 4 + 4 + 4 + 4 + 4 + 8 + 8 + 4 + 8 + bornhostLength;
return result.getByteBuffer().getLong(msgStoreTimePos);
} finally { } finally {
result.release(); result.release();
} }
...@@ -1170,6 +1211,7 @@ public class CommitLog { ...@@ -1170,6 +1211,7 @@ public class CommitLog {
// File at the end of the minimum fixed length empty // File at the end of the minimum fixed length empty
private static final int END_FILE_MIN_BLANK_LENGTH = 4 + 4; private static final int END_FILE_MIN_BLANK_LENGTH = 4 + 4;
private final ByteBuffer msgIdMemory; private final ByteBuffer msgIdMemory;
private final ByteBuffer msgIdV6Memory;
// Store the message content // Store the message content
private final ByteBuffer msgStoreItemMemory; private final ByteBuffer msgStoreItemMemory;
// The maximum length of the message // The maximum length of the message
...@@ -1179,10 +1221,9 @@ public class CommitLog { ...@@ -1179,10 +1221,9 @@ public class CommitLog {
private final StringBuilder msgIdBuilder = new StringBuilder(); private final StringBuilder msgIdBuilder = new StringBuilder();
private final ByteBuffer hostHolder = ByteBuffer.allocate(8);
DefaultAppendMessageCallback(final int size) { DefaultAppendMessageCallback(final int size) {
this.msgIdMemory = ByteBuffer.allocate(MessageDecoder.MSG_ID_LENGTH); this.msgIdMemory = ByteBuffer.allocate(4 + 4 + 8);
this.msgIdV6Memory = ByteBuffer.allocate(16 + 4 + 8);
this.msgStoreItemMemory = ByteBuffer.allocate(size + END_FILE_MIN_BLANK_LENGTH); this.msgStoreItemMemory = ByteBuffer.allocate(size + END_FILE_MIN_BLANK_LENGTH);
this.maxMessageSize = size; this.maxMessageSize = size;
} }
...@@ -1198,8 +1239,20 @@ public class CommitLog { ...@@ -1198,8 +1239,20 @@ public class CommitLog {
// PHY OFFSET // PHY OFFSET
long wroteOffset = fileFromOffset + byteBuffer.position(); long wroteOffset = fileFromOffset + byteBuffer.position();
this.resetByteBuffer(hostHolder, 8); int sysflag = msgInner.getSysFlag();
String msgId = MessageDecoder.createMessageId(this.msgIdMemory, msgInner.getStoreHostBytes(hostHolder), wroteOffset);
int bornHostLength = (sysflag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 4 + 4 : 16 + 4;
int storeHostLength = (sysflag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 4 + 4 : 16 + 4;
ByteBuffer bornHostHolder = ByteBuffer.allocate(bornHostLength);
ByteBuffer storeHostHolder = ByteBuffer.allocate(storeHostLength);
this.resetByteBuffer(storeHostHolder, storeHostLength);
String msgId;
if ((sysflag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0) {
msgId = MessageDecoder.createMessageId(this.msgIdMemory, msgInner.getStoreHostBytes(storeHostHolder), wroteOffset);
} else {
msgId = MessageDecoder.createMessageId(this.msgIdV6Memory, msgInner.getStoreHostBytes(storeHostHolder), wroteOffset);
}
// Record ConsumeQueue information // Record ConsumeQueue information
keyBuilder.setLength(0); keyBuilder.setLength(0);
...@@ -1246,7 +1299,7 @@ public class CommitLog { ...@@ -1246,7 +1299,7 @@ public class CommitLog {
final int bodyLength = msgInner.getBody() == null ? 0 : msgInner.getBody().length; final int bodyLength = msgInner.getBody() == null ? 0 : msgInner.getBody().length;
final int msgLen = calMsgLength(bodyLength, topicLength, propertiesLength); final int msgLen = calMsgLength(msgInner.getSysFlag(), bodyLength, topicLength, propertiesLength);
// Exceeds the maximum message // Exceeds the maximum message
if (msgLen > this.maxMessageSize) { if (msgLen > this.maxMessageSize) {
...@@ -1291,14 +1344,13 @@ public class CommitLog { ...@@ -1291,14 +1344,13 @@ public class CommitLog {
// 9 BORNTIMESTAMP // 9 BORNTIMESTAMP
this.msgStoreItemMemory.putLong(msgInner.getBornTimestamp()); this.msgStoreItemMemory.putLong(msgInner.getBornTimestamp());
// 10 BORNHOST // 10 BORNHOST
this.resetByteBuffer(hostHolder, 8); this.resetByteBuffer(bornHostHolder, bornHostLength);
this.msgStoreItemMemory.put(msgInner.getBornHostBytes(hostHolder)); this.msgStoreItemMemory.put(msgInner.getBornHostBytes(bornHostHolder));
// 11 STORETIMESTAMP // 11 STORETIMESTAMP
this.msgStoreItemMemory.putLong(msgInner.getStoreTimestamp()); this.msgStoreItemMemory.putLong(msgInner.getStoreTimestamp());
// 12 STOREHOSTADDRESS // 12 STOREHOSTADDRESS
this.resetByteBuffer(hostHolder, 8); this.resetByteBuffer(storeHostHolder, storeHostLength);
this.msgStoreItemMemory.put(msgInner.getStoreHostBytes(hostHolder)); this.msgStoreItemMemory.put(msgInner.getStoreHostBytes(storeHostHolder));
//this.msgBatchMemory.put(msgInner.getStoreHostBytes());
// 13 RECONSUMETIMES // 13 RECONSUMETIMES
this.msgStoreItemMemory.putInt(msgInner.getReconsumeTimes()); this.msgStoreItemMemory.putInt(msgInner.getReconsumeTimes());
// 14 Prepared Transaction Offset // 14 Prepared Transaction Offset
...@@ -1359,8 +1411,13 @@ public class CommitLog { ...@@ -1359,8 +1411,13 @@ public class CommitLog {
msgIdBuilder.setLength(0); msgIdBuilder.setLength(0);
final long beginTimeMills = CommitLog.this.defaultMessageStore.now(); final long beginTimeMills = CommitLog.this.defaultMessageStore.now();
ByteBuffer messagesByteBuff = messageExtBatch.getEncodedBuff(); ByteBuffer messagesByteBuff = messageExtBatch.getEncodedBuff();
this.resetByteBuffer(hostHolder, 8);
ByteBuffer storeHostBytes = messageExtBatch.getStoreHostBytes(hostHolder); int sysFlag = messageExtBatch.getSysFlag();
int storeHostLength = (sysFlag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 4 + 4 : 16 + 4;
ByteBuffer storeHostHolder = ByteBuffer.allocate(storeHostLength);
this.resetByteBuffer(storeHostHolder, storeHostLength);
ByteBuffer storeHostBytes = messageExtBatch.getStoreHostBytes(storeHostHolder);
messagesByteBuff.mark(); messagesByteBuff.mark();
while (messagesByteBuff.hasRemaining()) { while (messagesByteBuff.hasRemaining()) {
// 1 TOTALSIZE // 1 TOTALSIZE
...@@ -1396,7 +1453,13 @@ public class CommitLog { ...@@ -1396,7 +1453,13 @@ public class CommitLog {
messagesByteBuff.putLong(wroteOffset + totalMsgLen - msgLen); messagesByteBuff.putLong(wroteOffset + totalMsgLen - msgLen);
storeHostBytes.rewind(); storeHostBytes.rewind();
String msgId = MessageDecoder.createMessageId(this.msgIdMemory, storeHostBytes, wroteOffset + totalMsgLen - msgLen); String msgId;
if ((sysFlag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0) {
msgId = MessageDecoder.createMessageId(this.msgIdMemory, storeHostBytes, wroteOffset + totalMsgLen - msgLen);
} else {
msgId = MessageDecoder.createMessageId(this.msgIdV6Memory, storeHostBytes, wroteOffset + totalMsgLen - msgLen);
}
if (msgIdBuilder.length() > 0) { if (msgIdBuilder.length() > 0) {
msgIdBuilder.append(',').append(msgId); msgIdBuilder.append(',').append(msgId);
} else { } else {
...@@ -1432,8 +1495,6 @@ public class CommitLog { ...@@ -1432,8 +1495,6 @@ public class CommitLog {
// The maximum length of the message // The maximum length of the message
private final int maxMessageSize; private final int maxMessageSize;
private final ByteBuffer hostHolder = ByteBuffer.allocate(8);
MessageExtBatchEncoder(final int size) { MessageExtBatchEncoder(final int size) {
this.msgBatchMemory = ByteBuffer.allocateDirect(size); this.msgBatchMemory = ByteBuffer.allocateDirect(size);
this.maxMessageSize = size; this.maxMessageSize = size;
...@@ -1443,6 +1504,13 @@ public class CommitLog { ...@@ -1443,6 +1504,13 @@ public class CommitLog {
msgBatchMemory.clear(); //not thread-safe msgBatchMemory.clear(); //not thread-safe
int totalMsgLen = 0; int totalMsgLen = 0;
ByteBuffer messagesByteBuff = messageExtBatch.wrap(); ByteBuffer messagesByteBuff = messageExtBatch.wrap();
int sysFlag = messageExtBatch.getSysFlag();
int bornHostLength = (sysFlag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 4 + 4 : 16 + 4;
int storeHostLength = (sysFlag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 4 + 4 : 16 + 4;
ByteBuffer bornHostHolder = ByteBuffer.allocate(bornHostLength);
ByteBuffer storeHostHolder = ByteBuffer.allocate(storeHostLength);
while (messagesByteBuff.hasRemaining()) { while (messagesByteBuff.hasRemaining()) {
// 1 TOTALSIZE // 1 TOTALSIZE
messagesByteBuff.getInt(); messagesByteBuff.getInt();
...@@ -1466,7 +1534,7 @@ public class CommitLog { ...@@ -1466,7 +1534,7 @@ public class CommitLog {
final int topicLength = topicData.length; final int topicLength = topicData.length;
final int msgLen = calMsgLength(bodyLen, topicLength, propertiesLen); final int msgLen = calMsgLength(messageExtBatch.getSysFlag(), bodyLen, topicLength, propertiesLen);
// Exceeds the maximum message // Exceeds the maximum message
if (msgLen > this.maxMessageSize) { if (msgLen > this.maxMessageSize) {
...@@ -1500,13 +1568,13 @@ public class CommitLog { ...@@ -1500,13 +1568,13 @@ public class CommitLog {
// 9 BORNTIMESTAMP // 9 BORNTIMESTAMP
this.msgBatchMemory.putLong(messageExtBatch.getBornTimestamp()); this.msgBatchMemory.putLong(messageExtBatch.getBornTimestamp());
// 10 BORNHOST // 10 BORNHOST
this.resetByteBuffer(hostHolder, 8); this.resetByteBuffer(bornHostHolder, bornHostLength);
this.msgBatchMemory.put(messageExtBatch.getBornHostBytes(hostHolder)); this.msgBatchMemory.put(messageExtBatch.getBornHostBytes(bornHostHolder));
// 11 STORETIMESTAMP // 11 STORETIMESTAMP
this.msgBatchMemory.putLong(messageExtBatch.getStoreTimestamp()); this.msgBatchMemory.putLong(messageExtBatch.getStoreTimestamp());
// 12 STOREHOSTADDRESS // 12 STOREHOSTADDRESS
this.resetByteBuffer(hostHolder, 8); this.resetByteBuffer(storeHostHolder, storeHostLength);
this.msgBatchMemory.put(messageExtBatch.getStoreHostBytes(hostHolder)); this.msgBatchMemory.put(messageExtBatch.getStoreHostBytes(storeHostHolder));
// 13 RECONSUMETIMES // 13 RECONSUMETIMES
this.msgBatchMemory.putInt(messageExtBatch.getReconsumeTimes()); this.msgBatchMemory.putInt(messageExtBatch.getReconsumeTimes());
// 14 Prepared Transaction Offset, batch does not support transaction // 14 Prepared Transaction Offset, batch does not support transaction
......
...@@ -19,6 +19,8 @@ package org.apache.rocketmq.store; ...@@ -19,6 +19,8 @@ package org.apache.rocketmq.store;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.net.Inet6Address;
import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
...@@ -285,8 +287,6 @@ public class DefaultMessageStore implements MessageStore { ...@@ -285,8 +287,6 @@ public class DefaultMessageStore implements MessageStore {
this.shutdown = false; this.shutdown = false;
} }
public void shutdown() { public void shutdown() {
if (!this.shutdown) { if (!this.shutdown) {
this.shutdown = true; this.shutdown = true;
...@@ -469,7 +469,7 @@ public class DefaultMessageStore implements MessageStore { ...@@ -469,7 +469,7 @@ public class DefaultMessageStore implements MessageStore {
long diff = this.systemClock.now() - begin; long diff = this.systemClock.now() - begin;
return diff < 10000000 return diff < 10000000
&& diff > this.messageStoreConfig.getOsPageCacheBusyTimeOutMills(); && diff > this.messageStoreConfig.getOsPageCacheBusyTimeOutMills();
} }
@Override @Override
...@@ -1042,7 +1042,9 @@ public class DefaultMessageStore implements MessageStore { ...@@ -1042,7 +1042,9 @@ public class DefaultMessageStore implements MessageStore {
int i = 0; int i = 0;
for (; i < bufferConsumeQueue.getSize(); i += ConsumeQueue.CQ_STORE_UNIT_SIZE) { for (; i < bufferConsumeQueue.getSize(); i += ConsumeQueue.CQ_STORE_UNIT_SIZE) {
long offsetPy = bufferConsumeQueue.getByteBuffer().getLong(); long offsetPy = bufferConsumeQueue.getByteBuffer().getLong();
final ByteBuffer msgIdMemory = ByteBuffer.allocate(MessageDecoder.MSG_ID_LENGTH); InetSocketAddress inetSocketAddress = (InetSocketAddress) storeHost;
int msgIdLength = (inetSocketAddress.getAddress() instanceof Inet6Address) ? 16 + 4 + 8 : 4 + 4 + 8;
final ByteBuffer msgIdMemory = ByteBuffer.allocate(msgIdLength);
String msgId = String msgId =
MessageDecoder.createMessageId(msgIdMemory, MessageExt.socketAddress2ByteBuffer(storeHost), offsetPy); MessageDecoder.createMessageId(msgIdMemory, MessageExt.socketAddress2ByteBuffer(storeHost), offsetPy);
messageIds.put(msgId, nextOffset++); messageIds.put(msgId, nextOffset++);
......
...@@ -80,7 +80,7 @@ public class MessageStoreConfig { ...@@ -80,7 +80,7 @@ public class MessageStoreConfig {
private int fileReservedTime = 72; private int fileReservedTime = 72;
// Flow control for ConsumeQueue // Flow control for ConsumeQueue
private int putMsgIndexHightWater = 600000; private int putMsgIndexHightWater = 600000;
// The maximum size of a single log file,default is 512K // The maximum size of message,default is 4M
private int maxMessageSize = 1024 * 1024 * 4; private int maxMessageSize = 1024 * 1024 * 4;
// Whether check the CRC32 of the records consumed. // Whether check the CRC32 of the records consumed.
// This ensures no on-the-wire or on-disk corruption to the messages occurred. // This ensures no on-the-wire or on-disk corruption to the messages occurred.
......
...@@ -68,12 +68,11 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -68,12 +68,11 @@ public class DLedgerCommitLog extends CommitLog {
//This offset separate the old commitlog from dledger commitlog //This offset separate the old commitlog from dledger commitlog
private long dividedCommitlogOffset = -1; private long dividedCommitlogOffset = -1;
private boolean isInrecoveringOldCommitlog = false; private boolean isInrecoveringOldCommitlog = false;
public DLedgerCommitLog(final DefaultMessageStore defaultMessageStore) { public DLedgerCommitLog(final DefaultMessageStore defaultMessageStore) {
super(defaultMessageStore); super(defaultMessageStore);
dLedgerConfig = new DLedgerConfig(); dLedgerConfig = new DLedgerConfig();
dLedgerConfig.setEnableDiskForceClean(defaultMessageStore.getMessageStoreConfig().isCleanFileForciblyEnable()); dLedgerConfig.setEnableDiskForceClean(defaultMessageStore.getMessageStoreConfig().isCleanFileForciblyEnable());
dLedgerConfig.setStoreType(DLedgerConfig.FILE); dLedgerConfig.setStoreType(DLedgerConfig.FILE);
dLedgerConfig.setSelfId(defaultMessageStore.getMessageStoreConfig().getdLegerSelfId()); dLedgerConfig.setSelfId(defaultMessageStore.getMessageStoreConfig().getdLegerSelfId());
...@@ -99,12 +98,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -99,12 +98,7 @@ public class DLedgerCommitLog extends CommitLog {
@Override @Override
public boolean load() { public boolean load() {
boolean result = super.load(); return super.load();
if (!result) {
return false;
}
return true;
} }
private void refreshConfig() { private void refreshConfig() {
...@@ -163,8 +157,6 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -163,8 +157,6 @@ public class DLedgerCommitLog extends CommitLog {
log.warn("Should not set confirm offset {} for dleger commitlog", phyOffset); log.warn("Should not set confirm offset {} for dleger commitlog", phyOffset);
} }
@Override @Override
public long remainHowManyDataToCommit() { public long remainHowManyDataToCommit() {
return dLedgerFileList.remainHowManyDataToCommit(); return dLedgerFileList.remainHowManyDataToCommit();
...@@ -185,7 +177,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -185,7 +177,7 @@ public class DLedgerCommitLog extends CommitLog {
if (mappedFileQueue.getMappedFiles().isEmpty()) { if (mappedFileQueue.getMappedFiles().isEmpty()) {
refreshConfig(); refreshConfig();
//To prevent too much log in defaultMessageStore //To prevent too much log in defaultMessageStore
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} else { } else {
disableDeleteDledger(); disableDeleteDledger();
} }
...@@ -206,7 +198,6 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -206,7 +198,6 @@ public class DLedgerCommitLog extends CommitLog {
return 1; return 1;
} }
public SelectMappedBufferResult convertSbr(SelectMmapBufferResult sbr) { public SelectMappedBufferResult convertSbr(SelectMmapBufferResult sbr) {
if (sbr == null) { if (sbr == null) {
return null; return null;
...@@ -237,7 +228,6 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -237,7 +228,6 @@ public class DLedgerCommitLog extends CommitLog {
return this.getData(offset, offset == 0); return this.getData(offset, offset == 0);
} }
@Override @Override
public SelectMappedBufferResult getData(final long offset, final boolean returnFirstOnNotFound) { public SelectMappedBufferResult getData(final long offset, final boolean returnFirstOnNotFound) {
if (offset < dividedCommitlogOffset) { if (offset < dividedCommitlogOffset) {
...@@ -251,7 +241,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -251,7 +241,7 @@ public class DLedgerCommitLog extends CommitLog {
if (mappedFile != null) { if (mappedFile != null) {
int pos = (int) (offset % mappedFileSize); int pos = (int) (offset % mappedFileSize);
SelectMmapBufferResult sbr = mappedFile.selectMappedBuffer(pos); SelectMmapBufferResult sbr = mappedFile.selectMappedBuffer(pos);
return convertSbr(truncate(sbr)); return convertSbr(truncate(sbr));
} }
return null; return null;
...@@ -283,7 +273,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -283,7 +273,7 @@ public class DLedgerCommitLog extends CommitLog {
if (mappedFile == null) { if (mappedFile == null) {
return; return;
} }
ByteBuffer byteBuffer = mappedFile.sliceByteBuffer(); ByteBuffer byteBuffer = mappedFile.sliceByteBuffer();
byteBuffer.position(mappedFile.getWrotePosition()); byteBuffer.position(mappedFile.getWrotePosition());
boolean needWriteMagicCode = true; boolean needWriteMagicCode = true;
// 1 TOTAL SIZE // 1 TOTAL SIZE
...@@ -316,7 +306,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -316,7 +306,7 @@ public class DLedgerCommitLog extends CommitLog {
} }
@Override @Override
public void recoverAbnormally(long maxPhyOffsetOfConsumeQueue) { public void recoverAbnormally(long maxPhyOffsetOfConsumeQueue) {
recover(maxPhyOffsetOfConsumeQueue); recover(maxPhyOffsetOfConsumeQueue);
} }
...@@ -334,9 +324,9 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -334,9 +324,9 @@ public class DLedgerCommitLog extends CommitLog {
try { try {
int bodyOffset = DLedgerEntry.BODY_OFFSET; int bodyOffset = DLedgerEntry.BODY_OFFSET;
int pos = byteBuffer.position(); int pos = byteBuffer.position();
int magic = byteBuffer.getInt(); int magic = byteBuffer.getInt();
//In dledger, this field is size, it must be gt 0, so it could prevent collision //In dledger, this field is size, it must be gt 0, so it could prevent collision
int magicOld = byteBuffer.getInt(); int magicOld = byteBuffer.getInt();
if (magicOld == CommitLog.BLANK_MAGIC_CODE || magicOld == CommitLog.MESSAGE_MAGIC_CODE) { if (magicOld == CommitLog.BLANK_MAGIC_CODE || magicOld == CommitLog.MESSAGE_MAGIC_CODE) {
byteBuffer.position(pos); byteBuffer.position(pos);
return super.checkMessageAndReturnSize(byteBuffer, checkCRC, readBody); return super.checkMessageAndReturnSize(byteBuffer, checkCRC, readBody);
...@@ -414,10 +404,10 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -414,10 +404,10 @@ public class DLedgerCommitLog extends CommitLog {
long elapsedTimeInLock; long elapsedTimeInLock;
long queueOffset; long queueOffset;
try { try {
beginTimeInDledgerLock = this.defaultMessageStore.getSystemClock().now(); beginTimeInDledgerLock = this.defaultMessageStore.getSystemClock().now();
encodeResult = this.messageSerializer.serialize(msg); encodeResult = this.messageSerializer.serialize(msg);
queueOffset = topicQueueTable.get(encodeResult.queueOffsetKey); queueOffset = topicQueueTable.get(encodeResult.queueOffsetKey);
if (encodeResult.status != AppendMessageStatus.PUT_OK) { if (encodeResult.status != AppendMessageStatus.PUT_OK) {
return new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, new AppendMessageResult(encodeResult.status)); return new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, new AppendMessageResult(encodeResult.status));
} }
AppendEntryRequest request = new AppendEntryRequest(); AppendEntryRequest request = new AppendEntryRequest();
...@@ -428,8 +418,11 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -428,8 +418,11 @@ public class DLedgerCommitLog extends CommitLog {
if (dledgerFuture.getPos() == -1) { if (dledgerFuture.getPos() == -1) {
return new PutMessageResult(PutMessageStatus.OS_PAGECACHE_BUSY, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)); return new PutMessageResult(PutMessageStatus.OS_PAGECACHE_BUSY, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR));
} }
long wroteOffset = dledgerFuture.getPos() + DLedgerEntry.BODY_OFFSET; long wroteOffset = dledgerFuture.getPos() + DLedgerEntry.BODY_OFFSET;
ByteBuffer buffer = ByteBuffer.allocate(MessageDecoder.MSG_ID_LENGTH);
int msgIdLength = (msg.getSysFlag() & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 4 + 4 + 8 : 16 + 4 + 8;
ByteBuffer buffer = ByteBuffer.allocate(msgIdLength);
String msgId = MessageDecoder.createMessageId(buffer, msg.getStoreHostBytes(), wroteOffset); String msgId = MessageDecoder.createMessageId(buffer, msg.getStoreHostBytes(), wroteOffset);
elapsedTimeInLock = this.defaultMessageStore.getSystemClock().now() - beginTimeInDledgerLock; elapsedTimeInLock = this.defaultMessageStore.getSystemClock().now() - beginTimeInDledgerLock;
appendResult = new AppendMessageResult(AppendMessageStatus.PUT_OK, wroteOffset, encodeResult.data.length, msgId, System.currentTimeMillis(), queueOffset, elapsedTimeInLock); appendResult = new AppendMessageResult(AppendMessageStatus.PUT_OK, wroteOffset, encodeResult.data.length, msgId, System.currentTimeMillis(), queueOffset, elapsedTimeInLock);
...@@ -496,8 +489,6 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -496,8 +489,6 @@ public class DLedgerCommitLog extends CommitLog {
return new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, null); return new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, null);
} }
@Override @Override
public SelectMappedBufferResult getMessage(final long offset, final int size) { public SelectMappedBufferResult getMessage(final long offset, final int size) {
if (offset < dividedCommitlogOffset) { if (offset < dividedCommitlogOffset) {
...@@ -507,7 +498,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -507,7 +498,7 @@ public class DLedgerCommitLog extends CommitLog {
MmapFile mappedFile = this.dLedgerFileList.findMappedFileByOffset(offset, offset == 0); MmapFile mappedFile = this.dLedgerFileList.findMappedFileByOffset(offset, offset == 0);
if (mappedFile != null) { if (mappedFile != null) {
int pos = (int) (offset % mappedFileSize); int pos = (int) (offset % mappedFileSize);
return convertSbr(mappedFile.selectMappedBuffer(pos, size)); return convertSbr(mappedFile.selectMappedBuffer(pos, size));
} }
return null; return null;
} }
...@@ -564,6 +555,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -564,6 +555,7 @@ public class DLedgerCommitLog extends CommitLog {
private String queueOffsetKey; private String queueOffsetKey;
private byte[] data; private byte[] data;
private AppendMessageStatus status; private AppendMessageStatus status;
public EncodeResult(AppendMessageStatus status, byte[] data, String queueOffsetKey) { public EncodeResult(AppendMessageStatus status, byte[] data, String queueOffsetKey) {
this.data = data; this.data = data;
this.status = status; this.status = status;
...@@ -575,6 +567,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -575,6 +567,7 @@ public class DLedgerCommitLog extends CommitLog {
// File at the end of the minimum fixed length empty // File at the end of the minimum fixed length empty
private static final int END_FILE_MIN_BLANK_LENGTH = 4 + 4; private static final int END_FILE_MIN_BLANK_LENGTH = 4 + 4;
private final ByteBuffer msgIdMemory; private final ByteBuffer msgIdMemory;
private final ByteBuffer msgIdV6Memory;
// Store the message content // Store the message content
private final ByteBuffer msgStoreItemMemory; private final ByteBuffer msgStoreItemMemory;
// The maximum length of the message // The maximum length of the message
...@@ -584,10 +577,11 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -584,10 +577,11 @@ public class DLedgerCommitLog extends CommitLog {
private final StringBuilder msgIdBuilder = new StringBuilder(); private final StringBuilder msgIdBuilder = new StringBuilder();
private final ByteBuffer hostHolder = ByteBuffer.allocate(8); // private final ByteBuffer hostHolder = ByteBuffer.allocate(8);
MessageSerializer(final int size) { MessageSerializer(final int size) {
this.msgIdMemory = ByteBuffer.allocate(MessageDecoder.MSG_ID_LENGTH); this.msgIdMemory = ByteBuffer.allocate(4 + 4 + 8);
this.msgIdV6Memory = ByteBuffer.allocate(16 + 4 + 8);
this.msgStoreItemMemory = ByteBuffer.allocate(size + END_FILE_MIN_BLANK_LENGTH); this.msgStoreItemMemory = ByteBuffer.allocate(size + END_FILE_MIN_BLANK_LENGTH);
this.maxMessageSize = size; this.maxMessageSize = size;
} }
...@@ -602,7 +596,13 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -602,7 +596,13 @@ public class DLedgerCommitLog extends CommitLog {
// PHY OFFSET // PHY OFFSET
long wroteOffset = 0; long wroteOffset = 0;
this.resetByteBuffer(hostHolder, 8); int sysflag = msgInner.getSysFlag();
int bornHostLength = (sysflag & MessageSysFlag.BORNHOST_V6_FLAG) == 0 ? 4 + 4 : 16 + 4;
int storeHostLength = (sysflag & MessageSysFlag.STOREHOSTADDRESS_V6_FLAG) == 0 ? 4 + 4 : 16 + 4;
ByteBuffer bornHostHolder = ByteBuffer.allocate(bornHostLength);
ByteBuffer storeHostHolder = ByteBuffer.allocate(storeHostLength);
// Record ConsumeQueue information // Record ConsumeQueue information
keyBuilder.setLength(0); keyBuilder.setLength(0);
keyBuilder.append(msgInner.getTopic()); keyBuilder.append(msgInner.getTopic());
...@@ -649,7 +649,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -649,7 +649,7 @@ public class DLedgerCommitLog extends CommitLog {
final int bodyLength = msgInner.getBody() == null ? 0 : msgInner.getBody().length; final int bodyLength = msgInner.getBody() == null ? 0 : msgInner.getBody().length;
final int msgLen = calMsgLength(bodyLength, topicLength, propertiesLength); final int msgLen = calMsgLength(msgInner.getSysFlag(), bodyLength, topicLength, propertiesLength);
// Exceeds the maximum message // Exceeds the maximum message
if (msgLen > this.maxMessageSize) { if (msgLen > this.maxMessageSize) {
...@@ -678,13 +678,13 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -678,13 +678,13 @@ public class DLedgerCommitLog extends CommitLog {
// 9 BORNTIMESTAMP // 9 BORNTIMESTAMP
this.msgStoreItemMemory.putLong(msgInner.getBornTimestamp()); this.msgStoreItemMemory.putLong(msgInner.getBornTimestamp());
// 10 BORNHOST // 10 BORNHOST
this.resetByteBuffer(hostHolder, 8); this.resetByteBuffer(bornHostHolder, bornHostLength);
this.msgStoreItemMemory.put(msgInner.getBornHostBytes(hostHolder)); this.msgStoreItemMemory.put(msgInner.getBornHostBytes(bornHostHolder));
// 11 STORETIMESTAMP // 11 STORETIMESTAMP
this.msgStoreItemMemory.putLong(msgInner.getStoreTimestamp()); this.msgStoreItemMemory.putLong(msgInner.getStoreTimestamp());
// 12 STOREHOSTADDRESS // 12 STOREHOSTADDRESS
this.resetByteBuffer(hostHolder, 8); this.resetByteBuffer(storeHostHolder, storeHostLength);
this.msgStoreItemMemory.put(msgInner.getStoreHostBytes(hostHolder)); this.msgStoreItemMemory.put(msgInner.getStoreHostBytes(storeHostHolder));
//this.msgBatchMemory.put(msgInner.getStoreHostBytes()); //this.msgBatchMemory.put(msgInner.getStoreHostBytes());
// 13 RECONSUMETIMES // 13 RECONSUMETIMES
this.msgStoreItemMemory.putInt(msgInner.getReconsumeTimes()); this.msgStoreItemMemory.putInt(msgInner.getReconsumeTimes());
...@@ -719,6 +719,7 @@ public class DLedgerCommitLog extends CommitLog { ...@@ -719,6 +719,7 @@ public class DLedgerCommitLog extends CommitLog {
public static class DLedgerSelectMappedBufferResult extends SelectMappedBufferResult { public static class DLedgerSelectMappedBufferResult extends SelectMappedBufferResult {
private SelectMmapBufferResult sbr; private SelectMmapBufferResult sbr;
public DLedgerSelectMappedBufferResult(SelectMmapBufferResult sbr) { public DLedgerSelectMappedBufferResult(SelectMmapBufferResult sbr) {
super(sbr.getStartOffset(), sbr.getByteBuffer(), sbr.getSize(), null); super(sbr.getStartOffset(), sbr.getByteBuffer(), sbr.getSize(), null);
this.sbr = sbr; this.sbr = sbr;
......
...@@ -374,6 +374,7 @@ public class HAService { ...@@ -374,6 +374,7 @@ public class HAService {
} }
} }
lastWriteTimestamp = HAService.this.defaultMessageStore.getSystemClock().now();
return !this.reportOffset.hasRemaining(); return !this.reportOffset.hasRemaining();
} }
...@@ -406,7 +407,6 @@ public class HAService { ...@@ -406,7 +407,6 @@ public class HAService {
try { try {
int readSize = this.socketChannel.read(this.byteBufferRead); int readSize = this.socketChannel.read(this.byteBufferRead);
if (readSize > 0) { if (readSize > 0) {
lastWriteTimestamp = HAService.this.defaultMessageStore.getSystemClock().now();
readSizeZeroTimes = 0; readSizeZeroTimes = 0;
boolean result = this.dispatchReadRequest(); boolean result = this.dispatchReadRequest();
if (!result) { if (!result) {
......
...@@ -97,6 +97,43 @@ public class AppendCallbackTest { ...@@ -97,6 +97,43 @@ public class AppendCallbackTest {
assertTrue(result.getMsgId().length() > 0); //should have already constructed some message ids assertTrue(result.getMsgId().length() > 0); //should have already constructed some message ids
} }
@Test
public void testAppendIPv6HostMessageBatchEndOfFile() throws Exception {
List<Message> messages = new ArrayList<>();
String topic = "test-topic";
int queue = 0;
for (int i = 0; i < 10; i++) {
Message msg = new Message();
msg.setBody("body".getBytes());
msg.setTopic(topic);
msg.setTags("abc");
messages.add(msg);
}
MessageExtBatch messageExtBatch = new MessageExtBatch();
messageExtBatch.setTopic(topic);
messageExtBatch.setQueueId(queue);
messageExtBatch.setBornTimestamp(System.currentTimeMillis());
messageExtBatch.setMsgId("24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0");
messageExtBatch.setSysFlag(0);
messageExtBatch.setBornHostV6Flag();
messageExtBatch.setStoreHostAddressV6Flag();
messageExtBatch.setBornHost(new InetSocketAddress("1050:0000:0000:0000:0005:0600:300c:326b", 123));
messageExtBatch.setStoreHost(new InetSocketAddress("::1", 124));
messageExtBatch.setBody(MessageDecoder.encodeMessages(messages));
messageExtBatch.setEncodedBuff(batchEncoder.encode(messageExtBatch));
ByteBuffer buff = ByteBuffer.allocate(1024 * 10);
//encounter end of file when append half of the data
AppendMessageResult result = callback.doAppend(0, buff, 1000, messageExtBatch);
assertEquals(AppendMessageStatus.END_OF_FILE, result.getStatus());
assertEquals(0, result.getWroteOffset());
assertEquals(0, result.getLogicsOffset());
assertEquals(1000, result.getWroteBytes());
assertEquals(8, buff.position()); //write blank size and magic value
assertTrue(result.getMsgId().length() > 0); //should have already constructed some message ids
}
@Test @Test
public void testAppendMessageBatchSucc() throws Exception { public void testAppendMessageBatchSucc() throws Exception {
List<Message> messages = new ArrayList<>(); List<Message> messages = new ArrayList<>();
...@@ -153,4 +190,64 @@ public class AppendCallbackTest { ...@@ -153,4 +190,64 @@ public class AppendCallbackTest {
} }
@Test
public void testAppendIPv6HostMessageBatchSucc() throws Exception {
List<Message> messages = new ArrayList<>();
String topic = "test-topic";
int queue = 0;
for (int i = 0; i < 10; i++) {
Message msg = new Message();
msg.setBody("body".getBytes());
msg.setTopic(topic);
msg.setTags("abc");
messages.add(msg);
}
MessageExtBatch messageExtBatch = new MessageExtBatch();
messageExtBatch.setTopic(topic);
messageExtBatch.setQueueId(queue);
messageExtBatch.setBornTimestamp(System.currentTimeMillis());
messageExtBatch.setMsgId("24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0");
messageExtBatch.setSysFlag(0);
messageExtBatch.setBornHostV6Flag();
messageExtBatch.setStoreHostAddressV6Flag();
messageExtBatch.setBornHost(new InetSocketAddress("1050:0000:0000:0000:0005:0600:300c:326b", 123));
messageExtBatch.setStoreHost(new InetSocketAddress("::1", 124));
messageExtBatch.setBody(MessageDecoder.encodeMessages(messages));
messageExtBatch.setEncodedBuff(batchEncoder.encode(messageExtBatch));
ByteBuffer buff = ByteBuffer.allocate(1024 * 10);
AppendMessageResult allresult = callback.doAppend(0, buff, 1024 * 10, messageExtBatch);
assertEquals(AppendMessageStatus.PUT_OK, allresult.getStatus());
assertEquals(0, allresult.getWroteOffset());
assertEquals(0, allresult.getLogicsOffset());
assertEquals(buff.position(), allresult.getWroteBytes());
assertEquals(messages.size(), allresult.getMsgNum());
Set<String> msgIds = new HashSet<>();
for (String msgId : allresult.getMsgId().split(",")) {
assertEquals(56, msgId.length());
msgIds.add(msgId);
}
assertEquals(messages.size(), msgIds.size());
List<MessageExt> decodeMsgs = MessageDecoder.decodes((ByteBuffer) buff.flip());
assertEquals(decodeMsgs.size(), decodeMsgs.size());
long queueOffset = decodeMsgs.get(0).getQueueOffset();
long storeTimeStamp = decodeMsgs.get(0).getStoreTimestamp();
for (int i = 0; i < messages.size(); i++) {
assertEquals(messages.get(i).getTopic(), decodeMsgs.get(i).getTopic());
assertEquals(new String(messages.get(i).getBody()), new String(decodeMsgs.get(i).getBody()));
assertEquals(messages.get(i).getTags(), decodeMsgs.get(i).getTags());
assertEquals(messageExtBatch.getBornHostNameString(), decodeMsgs.get(i).getBornHostNameString());
assertEquals(messageExtBatch.getBornTimestamp(), decodeMsgs.get(i).getBornTimestamp());
assertEquals(storeTimeStamp, decodeMsgs.get(i).getStoreTimestamp());
assertEquals(queueOffset++, decodeMsgs.get(i).getQueueOffset());
}
}
} }
...@@ -23,6 +23,7 @@ import org.apache.rocketmq.common.message.Message; ...@@ -23,6 +23,7 @@ import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageDecoder; import org.apache.rocketmq.common.message.MessageDecoder;
import org.apache.rocketmq.common.message.MessageExt; import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageExtBatch; import org.apache.rocketmq.common.message.MessageExtBatch;
import org.apache.rocketmq.common.sysflag.MessageSysFlag;
import org.apache.rocketmq.store.config.FlushDiskType; import org.apache.rocketmq.store.config.FlushDiskType;
import org.apache.rocketmq.store.config.MessageStoreConfig; import org.apache.rocketmq.store.config.MessageStoreConfig;
import org.apache.rocketmq.store.stats.BrokerStatsManager; import org.apache.rocketmq.store.stats.BrokerStatsManager;
...@@ -125,6 +126,58 @@ public class BatchPutMessageTest { ...@@ -125,6 +126,58 @@ public class BatchPutMessageTest {
} }
@Test
public void testPutIPv6HostMessages() throws Exception {
List<Message> messages = new ArrayList<>();
String topic = "batch-write-topic";
int queue = 0;
int[] msgLengthArr = new int[11];
msgLengthArr[0] = 0;
int j = 1;
for (int i = 0; i < 10; i++) {
Message msg = new Message();
msg.setBody(("body" + i).getBytes());
msg.setTopic(topic);
msg.setTags("TAG1");
msg.setKeys(String.valueOf(System.currentTimeMillis()));
messages.add(msg);
String properties = messageProperties2String(msg.getProperties());
byte[] propertiesBytes = properties.getBytes(CHARSET_UTF8);
short propertiesLength = (short) propertiesBytes.length;
final byte[] topicData = msg.getTopic().getBytes(MessageDecoder.CHARSET_UTF8);
final int topicLength = topicData.length;
msgLengthArr[j] = calIPv6HostMsgLength(msg.getBody().length, topicLength, propertiesLength) + msgLengthArr[j - 1];
j++;
}
byte[] batchMessageBody = MessageDecoder.encodeMessages(messages);
MessageExtBatch messageExtBatch = new MessageExtBatch();
messageExtBatch.setTopic(topic);
messageExtBatch.setQueueId(queue);
messageExtBatch.setBody(batchMessageBody);
messageExtBatch.setMsgId("24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0");
messageExtBatch.setBornTimestamp(System.currentTimeMillis());
messageExtBatch.setSysFlag(0);
messageExtBatch.setBornHostV6Flag();
messageExtBatch.setStoreHostAddressV6Flag();
messageExtBatch.setStoreHost(new InetSocketAddress("1050:0000:0000:0000:0005:0600:300c:326b", 125));
messageExtBatch.setBornHost(new InetSocketAddress("::1", 126));
PutMessageResult putMessageResult = messageStore.putMessages(messageExtBatch);
assertThat(putMessageResult.isOk()).isTrue();
Thread.sleep(3 * 1000);
for (long i = 0; i < 10; i++) {
MessageExt messageExt = messageStore.lookMessageByOffset(msgLengthArr[(int) i]);
assertThat(messageExt).isNotNull();
GetMessageResult result = messageStore.getMessage("batch_write_group", topic, queue, i, 1024 * 1024, null);
assertThat(result).isNotNull();
assertThat(result.getStatus()).isEqualTo(GetMessageStatus.FOUND);
result.release();
}
}
private int calMsgLength(int bodyLength, int topicLength, int propertiesLength) { private int calMsgLength(int bodyLength, int topicLength, int propertiesLength) {
final int msgLen = 4 //TOTALSIZE final int msgLen = 4 //TOTALSIZE
+ 4 //MAGICCODE + 4 //MAGICCODE
...@@ -147,6 +200,28 @@ public class BatchPutMessageTest { ...@@ -147,6 +200,28 @@ public class BatchPutMessageTest {
return msgLen; return msgLen;
} }
private int calIPv6HostMsgLength(int bodyLength, int topicLength, int propertiesLength) {
final int msgLen = 4 //TOTALSIZE
+ 4 //MAGICCODE
+ 4 //BODYCRC
+ 4 //QUEUEID
+ 4 //FLAG
+ 8 //QUEUEOFFSET
+ 8 //PHYSICALOFFSET
+ 4 //SYSFLAG
+ 8 //BORNTIMESTAMP
+ 20 //BORNHOST
+ 8 //STORETIMESTAMP
+ 20 //STOREHOSTADDRESS
+ 4 //RECONSUMETIMES
+ 8 //Prepared Transaction Offset
+ 4 + (bodyLength > 0 ? bodyLength : 0) //BODY
+ 1 + topicLength //TOPIC
+ 2 + (propertiesLength > 0 ? propertiesLength : 0) //propertiesLength
+ 0;
return msgLen;
}
public String messageProperties2String(Map<String, String> properties) { public String messageProperties2String(Map<String, String> properties) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (properties != null) { if (properties != null) {
......
...@@ -83,6 +83,29 @@ public class ConsumeQueueTest { ...@@ -83,6 +83,29 @@ public class ConsumeQueueTest {
return msg; return msg;
} }
public MessageExtBrokerInner buildIPv6HostMessage() {
MessageExtBrokerInner msg = new MessageExtBrokerInner();
msg.setTopic(topic);
msg.setTags("TAG1");
msg.setKeys("Hello");
msg.setBody(msgBody);
msg.setMsgId("24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0");
msg.setKeys(String.valueOf(System.currentTimeMillis()));
msg.setQueueId(queueId);
msg.setSysFlag(0);
msg.setBornHostV6Flag();
msg.setStoreHostAddressV6Flag();
msg.setBornTimestamp(System.currentTimeMillis());
msg.setBornHost(new InetSocketAddress("1050:0000:0000:0000:0005:0600:300c:326b", 123));
msg.setStoreHost(new InetSocketAddress("::1", 124));
for (int i = 0; i < 1; i++) {
msg.putUserProperty(String.valueOf(i), "imagoodperson" + i);
}
msg.setPropertiesString(MessageDecoder.messageProperties2String(msg.getProperties()));
return msg;
}
public MessageStoreConfig buildStoreConfig(int commitLogFileSize, int cqFileSize, public MessageStoreConfig buildStoreConfig(int commitLogFileSize, int cqFileSize,
boolean enableCqExt, int cqExtFileSize) { boolean enableCqExt, int cqExtFileSize) {
MessageStoreConfig messageStoreConfig = new MessageStoreConfig(); MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
...@@ -127,7 +150,11 @@ public class ConsumeQueueTest { ...@@ -127,7 +150,11 @@ public class ConsumeQueueTest {
long totalMsgs = 200; long totalMsgs = 200;
for (long i = 0; i < totalMsgs; i++) { for (long i = 0; i < totalMsgs; i++) {
master.putMessage(buildMessage()); if (i < totalMsgs / 2) {
master.putMessage(buildMessage());
} else {
master.putMessage(buildIPv6HostMessage());
}
} }
} }
......
...@@ -24,6 +24,7 @@ import java.lang.reflect.Method; ...@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer; import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
...@@ -116,13 +117,19 @@ public class DefaultMessageStoreTest { ...@@ -116,13 +117,19 @@ public class DefaultMessageStoreTest {
@Test @Test
public void testWriteAndRead() { public void testWriteAndRead() {
long totalMsgs = 10; long ipv4HostMsgs = 10;
long ipv6HostMsgs = 10;
long totalMsgs = ipv4HostMsgs + ipv6HostMsgs;
QUEUE_TOTAL = 1; QUEUE_TOTAL = 1;
MessageBody = StoreMessage.getBytes(); MessageBody = StoreMessage.getBytes();
for (long i = 0; i < totalMsgs; i++) { for (long i = 0; i < ipv4HostMsgs; i++) {
messageStore.putMessage(buildMessage()); messageStore.putMessage(buildMessage());
} }
for (long i = 0; i < ipv6HostMsgs; i++) {
messageStore.putMessage(buildIPv6HostMessage());
}
StoreTestUtil.waitCommitLogReput((DefaultMessageStore) messageStore); StoreTestUtil.waitCommitLogReput((DefaultMessageStore) messageStore);
for (long i = 0; i < totalMsgs; i++) { for (long i = 0; i < totalMsgs; i++) {
...@@ -134,7 +141,7 @@ public class DefaultMessageStoreTest { ...@@ -134,7 +141,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_look_message_successfully_when_offset_is_first() { public void testLookMessageByOffset_OffsetIsFirst() {
final int totalCount = 10; final int totalCount = 10;
int queueId = new Random().nextInt(10); int queueId = new Random().nextInt(10);
String topic = "FooBar"; String topic = "FooBar";
...@@ -150,7 +157,7 @@ public class DefaultMessageStoreTest { ...@@ -150,7 +157,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_look_message_successfully_when_offset_is_last() { public void testLookMessageByOffset_OffsetIsLast() {
final int totalCount = 10; final int totalCount = 10;
int queueId = new Random().nextInt(10); int queueId = new Random().nextInt(10);
String topic = "FooBar"; String topic = "FooBar";
...@@ -164,7 +171,7 @@ public class DefaultMessageStoreTest { ...@@ -164,7 +171,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_look_message_failed_and_return_null_when_offset_is_out_of_bound() { public void testLookMessageByOffset_OffsetIsOutOfBound() {
final int totalCount = 10; final int totalCount = 10;
int queueId = new Random().nextInt(10); int queueId = new Random().nextInt(10);
String topic = "FooBar"; String topic = "FooBar";
...@@ -177,7 +184,7 @@ public class DefaultMessageStoreTest { ...@@ -177,7 +184,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_get_consume_queue_offset_successfully_when_incomming_by_timestamp() throws InterruptedException { public void testGetOffsetInQueueByTime() {
final int totalCount = 10; final int totalCount = 10;
int queueId = 0; int queueId = 0;
String topic = "FooBar"; String topic = "FooBar";
...@@ -196,7 +203,7 @@ public class DefaultMessageStoreTest { ...@@ -196,7 +203,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_get_consume_queue_offset_successfully_when_timestamp_is_skewing() throws InterruptedException { public void testGetOffsetInQueueByTime_TimestampIsSkewing() {
final int totalCount = 10; final int totalCount = 10;
int queueId = 0; int queueId = 0;
String topic = "FooBar"; String topic = "FooBar";
...@@ -221,7 +228,7 @@ public class DefaultMessageStoreTest { ...@@ -221,7 +228,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_get_min_of_max_consume_queue_offset_when_timestamp_s_skewing_is_large() throws InterruptedException { public void testGetOffsetInQueueByTime_TimestampSkewingIsLarge() {
final int totalCount = 10; final int totalCount = 10;
int queueId = 0; int queueId = 0;
String topic = "FooBar"; String topic = "FooBar";
...@@ -247,7 +254,7 @@ public class DefaultMessageStoreTest { ...@@ -247,7 +254,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_return_zero_when_consume_queue_not_found() throws InterruptedException { public void testGetOffsetInQueueByTime_ConsumeQueueNotFound1() {
final int totalCount = 10; final int totalCount = 10;
int queueId = 0; int queueId = 0;
int wrongQueueId = 1; int wrongQueueId = 1;
...@@ -263,7 +270,7 @@ public class DefaultMessageStoreTest { ...@@ -263,7 +270,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_return_negative_one_when_invoke_getMessageStoreTimeStamp_if_consume_queue_not_found() throws InterruptedException { public void testGetOffsetInQueueByTime_ConsumeQueueNotFound2() {
final int totalCount = 10; final int totalCount = 10;
int queueId = 0; int queueId = 0;
int wrongQueueId = 1; int wrongQueueId = 1;
...@@ -278,7 +285,7 @@ public class DefaultMessageStoreTest { ...@@ -278,7 +285,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_return_negative_one_when_invoke_getMessageStoreTimeStamp_if_consumeQueueOffset_not_exist() throws InterruptedException { public void testGetOffsetInQueueByTime_ConsumeQueueOffsetNotExist() {
final int totalCount = 10; final int totalCount = 10;
int queueId = 0; int queueId = 0;
int wrongQueueId = 1; int wrongQueueId = 1;
...@@ -293,9 +300,8 @@ public class DefaultMessageStoreTest { ...@@ -293,9 +300,8 @@ public class DefaultMessageStoreTest {
assertThat(messageStoreTimeStamp).isEqualTo(-1); assertThat(messageStoreTimeStamp).isEqualTo(-1);
} }
@Test @Test
public void should_get_message_store_timestamp_successfully_when_incomming_by_topic_queueId_and_consumeQueueOffset() throws InterruptedException { public void testGetMessageStoreTimeStamp() {
final int totalCount = 10; final int totalCount = 10;
int queueId = 0; int queueId = 0;
String topic = "FooBar"; String topic = "FooBar";
...@@ -304,7 +310,7 @@ public class DefaultMessageStoreTest { ...@@ -304,7 +310,7 @@ public class DefaultMessageStoreTest {
StoreTestUtil.waitCommitLogReput((DefaultMessageStore) messageStore); StoreTestUtil.waitCommitLogReput((DefaultMessageStore) messageStore);
ConsumeQueue consumeQueue = getDefaultMessageStore().findConsumeQueue(topic, queueId); ConsumeQueue consumeQueue = getDefaultMessageStore().findConsumeQueue(topic, queueId);
int minOffsetInQueue = (int)consumeQueue.getMinOffsetInQueue(); int minOffsetInQueue = (int) consumeQueue.getMinOffsetInQueue();
for (int i = minOffsetInQueue; i < consumeQueue.getMaxOffsetInQueue(); i++) { for (int i = minOffsetInQueue; i < consumeQueue.getMaxOffsetInQueue(); i++) {
long messageStoreTimeStamp = messageStore.getMessageStoreTimeStamp(topic, queueId, i); long messageStoreTimeStamp = messageStore.getMessageStoreTimeStamp(topic, queueId, i);
assertThat(messageStoreTimeStamp).isEqualTo(appendMessageResults[i].getStoreTimestamp()); assertThat(messageStoreTimeStamp).isEqualTo(appendMessageResults[i].getStoreTimestamp());
...@@ -312,14 +318,14 @@ public class DefaultMessageStoreTest { ...@@ -312,14 +318,14 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_return_negative_one_when_invoke_getStoreTime_if_incomming_param_is_null() { public void testGetStoreTime_ParamIsNull() {
long storeTime = getStoreTime(null); long storeTime = getStoreTime(null);
assertThat(storeTime).isEqualTo(-1); assertThat(storeTime).isEqualTo(-1);
} }
@Test @Test
public void should_get_store_time_successfully_when_invoke_getStoreTime_if_everything_is_ok() throws InterruptedException { public void testGetStoreTime_EverythingIsOk() {
final int totalCount = 10; final int totalCount = 10;
int queueId = 0; int queueId = 0;
String topic = "FooBar"; String topic = "FooBar";
...@@ -337,7 +343,7 @@ public class DefaultMessageStoreTest { ...@@ -337,7 +343,7 @@ public class DefaultMessageStoreTest {
} }
@Test @Test
public void should_return_negative_one_when_invoke_getStoreTime_if_phyOffset_is_less_than_commitLog_s_minOffset() { public void testGetStoreTime_PhyOffsetIsLessThanCommitLogMinOffset() {
long phyOffset = -10; long phyOffset = -10;
int size = 138; int size = 138;
ByteBuffer byteBuffer = ByteBuffer.allocate(100); ByteBuffer byteBuffer = ByteBuffer.allocate(100);
...@@ -354,7 +360,7 @@ public class DefaultMessageStoreTest { ...@@ -354,7 +360,7 @@ public class DefaultMessageStoreTest {
} }
private DefaultMessageStore getDefaultMessageStore() { private DefaultMessageStore getDefaultMessageStore() {
return (DefaultMessageStore)this.messageStore; return (DefaultMessageStore) this.messageStore;
} }
private AppendMessageResult[] putMessages(int totalCount, String topic, int queueId) { private AppendMessageResult[] putMessages(int totalCount, String topic, int queueId) {
...@@ -365,7 +371,9 @@ public class DefaultMessageStoreTest { ...@@ -365,7 +371,9 @@ public class DefaultMessageStoreTest {
AppendMessageResult[] appendMessageResultArray = new AppendMessageResult[totalCount]; AppendMessageResult[] appendMessageResultArray = new AppendMessageResult[totalCount];
for (int i = 0; i < totalCount; i++) { for (int i = 0; i < totalCount; i++) {
String messageBody = buildMessageBodyByOffset(StoreMessage, i); String messageBody = buildMessageBodyByOffset(StoreMessage, i);
MessageExtBrokerInner msgInner = buildMessage(messageBody.getBytes(), topic);
MessageExtBrokerInner msgInner =
i < totalCount / 2 ? buildMessage(messageBody.getBytes(), topic) : buildIPv6HostMessage(messageBody.getBytes(), topic);
msgInner.setQueueId(queueId); msgInner.setQueueId(queueId);
PutMessageResult result = messageStore.putMessage(msgInner); PutMessageResult result = messageStore.putMessage(msgInner);
appendMessageResultArray[i] = result.getAppendMessageResult(); appendMessageResultArray[i] = result.getAppendMessageResult();
...@@ -374,7 +382,7 @@ public class DefaultMessageStoreTest { ...@@ -374,7 +382,7 @@ public class DefaultMessageStoreTest {
try { try {
Thread.sleep(10); Thread.sleep(10);
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException("Thread sleep ERROR"); throw new RuntimeException("Thread sleep ERROR");
} }
} }
} }
...@@ -397,7 +405,7 @@ public class DefaultMessageStoreTest { ...@@ -397,7 +405,7 @@ public class DefaultMessageStoreTest {
try { try {
Method getStoreTime = getDefaultMessageStore().getClass().getDeclaredMethod("getStoreTime", SelectMappedBufferResult.class); Method getStoreTime = getDefaultMessageStore().getClass().getDeclaredMethod("getStoreTime", SelectMappedBufferResult.class);
getStoreTime.setAccessible(true); getStoreTime.setAccessible(true);
return (long)getStoreTime.invoke(getDefaultMessageStore(), result); return (long) getStoreTime.invoke(getDefaultMessageStore(), result);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
...@@ -418,10 +426,43 @@ public class DefaultMessageStoreTest { ...@@ -418,10 +426,43 @@ public class DefaultMessageStoreTest {
return msg; return msg;
} }
private MessageExtBrokerInner buildIPv6HostMessage(byte[] messageBody, String topic) {
MessageExtBrokerInner msg = new MessageExtBrokerInner();
msg.setTopic(topic);
msg.setTags("TAG1");
msg.setKeys("Hello");
msg.setBody(messageBody);
msg.setMsgId("24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0");
msg.setKeys(String.valueOf(System.currentTimeMillis()));
msg.setQueueId(Math.abs(QueueId.getAndIncrement()) % QUEUE_TOTAL);
msg.setSysFlag(0);
msg.setBornHostV6Flag();
msg.setStoreHostAddressV6Flag();
msg.setBornTimestamp(System.currentTimeMillis());
try {
msg.setBornHost(new InetSocketAddress(InetAddress.getByName("1050:0000:0000:0000:0005:0600:300c:326b"), 0));
} catch (UnknownHostException e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
try {
msg.setStoreHost(new InetSocketAddress(InetAddress.getByName("::1"), 0));
} catch (UnknownHostException e) {
e.printStackTrace();
assertThat(Boolean.FALSE).isTrue();
}
return msg;
}
private MessageExtBrokerInner buildMessage() { private MessageExtBrokerInner buildMessage() {
return buildMessage(MessageBody, "FooBar"); return buildMessage(MessageBody, "FooBar");
} }
private MessageExtBrokerInner buildIPv6HostMessage() {
return buildIPv6HostMessage(MessageBody, "FooBar");
}
private void verifyThatMasterIsFunctional(long totalMsgs, MessageStore master) { private void verifyThatMasterIsFunctional(long totalMsgs, MessageStore master) {
for (long i = 0; i < totalMsgs; i++) { for (long i = 0; i < totalMsgs; i++) {
master.putMessage(buildMessage()); master.putMessage(buildMessage());
...@@ -477,7 +518,7 @@ public class DefaultMessageStoreTest { ...@@ -477,7 +518,7 @@ public class DefaultMessageStoreTest {
messageStore.putMessage(messageExtBrokerInner); messageStore.putMessage(messageExtBrokerInner);
} }
// Thread.sleep(100);//wait for build consumer queue // Thread.sleep(100);//wait for build consumer queue
StoreTestUtil.waitCommitLogReput((DefaultMessageStore) messageStore); StoreTestUtil.waitCommitLogReput((DefaultMessageStore) messageStore);
long maxPhyOffset = messageStore.getMaxPhyOffset(); long maxPhyOffset = messageStore.getMaxPhyOffset();
...@@ -587,7 +628,7 @@ public class DefaultMessageStoreTest { ...@@ -587,7 +628,7 @@ public class DefaultMessageStoreTest {
private class MyMessageArrivingListener implements MessageArrivingListener { private class MyMessageArrivingListener implements MessageArrivingListener {
@Override @Override
public void arriving(String topic, int queueId, long logicOffset, long tagsCode, long msgStoreTime, public void arriving(String topic, int queueId, long logicOffset, long tagsCode, long msgStoreTime,
byte[] filterBitMap, Map<String, String> properties) { byte[] filterBitMap, Map<String, String> properties) {
} }
} }
} }
...@@ -20,12 +20,12 @@ import java.io.File; ...@@ -20,12 +20,12 @@ import java.io.File;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.apache.rocketmq.common.UtilAll; import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.store.config.StorePathConfigHelper;
import org.junit.After; import org.junit.After;
public class StoreTestBase { public class StoreTestBase {
...@@ -59,6 +59,33 @@ public class StoreTestBase { ...@@ -59,6 +59,33 @@ public class StoreTestBase {
return msg; return msg;
} }
protected MessageExtBrokerInner buildIPv6HostMessage() {
MessageExtBrokerInner msg = new MessageExtBrokerInner();
msg.setTopic("StoreTest");
msg.setTags("TAG1");
msg.setKeys("Hello");
msg.setBody(MessageBody);
msg.setMsgId("24084004018081003FAA1DDE2B3F898A00002A9F0000000000000CA0");
msg.setKeys(String.valueOf(System.currentTimeMillis()));
msg.setQueueId(Math.abs(QueueId.getAndIncrement()) % QUEUE_TOTAL);
msg.setSysFlag(0);
msg.setBornHostV6Flag();
msg.setStoreHostAddressV6Flag();
msg.setBornTimestamp(System.currentTimeMillis());
try {
msg.setBornHost(new InetSocketAddress(InetAddress.getByName("1050:0000:0000:0000:0005:0600:300c:326b"), 8123));
} catch (UnknownHostException e) {
e.printStackTrace();
}
try {
msg.setStoreHost(new InetSocketAddress(InetAddress.getByName("::1"), 8123));
} catch (UnknownHostException e) {
e.printStackTrace();
}
return msg;
}
public static String createBaseDir() { public static String createBaseDir() {
String baseDir = System.getProperty("user.home") + File.separator + "unitteststore" + File.separator + UUID.randomUUID(); String baseDir = System.getProperty("user.home") + File.separator + "unitteststore" + File.separator + UUID.randomUUID();
final File file = new File(baseDir); final File file = new File(baseDir);
...@@ -74,7 +101,6 @@ public class StoreTestBase { ...@@ -74,7 +101,6 @@ public class StoreTestBase {
return file.createNewFile(); return file.createNewFile();
} }
public static void deleteFile(String fileName) { public static void deleteFile(String fileName) {
deleteFile(new File(fileName)); deleteFile(new File(fileName));
} }
......
...@@ -145,7 +145,8 @@ public class DLedgerCommitlogTest extends MessageStoreTestBase { ...@@ -145,7 +145,8 @@ public class DLedgerCommitlogTest extends MessageStoreTestBase {
List<PutMessageResult> results = new ArrayList<>(); List<PutMessageResult> results = new ArrayList<>();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
MessageExtBrokerInner msgInner = buildMessage(); MessageExtBrokerInner msgInner =
i < 5 ? buildMessage() : buildIPv6HostMessage();
msgInner.setTopic(topic); msgInner.setTopic(topic);
msgInner.setQueueId(0); msgInner.setQueueId(0);
PutMessageResult putMessageResult = messageStore.putMessage(msgInner); PutMessageResult putMessageResult = messageStore.putMessage(msgInner);
...@@ -209,5 +210,39 @@ public class DLedgerCommitlogTest extends MessageStoreTestBase { ...@@ -209,5 +210,39 @@ public class DLedgerCommitlogTest extends MessageStoreTestBase {
followerStore.shutdown(); followerStore.shutdown();
} }
@Test
public void testIPv6HostMsgCommittedPos() throws Exception {
String peers = String.format("n0-localhost:%d;n1-localhost:%d", nextPort(), nextPort());
String group = UUID.randomUUID().toString();
DefaultMessageStore leaderStore = createDledgerMessageStore(createBaseDir(), group,"n0", peers, "n0", false, 0);
String topic = UUID.randomUUID().toString();
MessageExtBrokerInner msgInner = buildIPv6HostMessage();
msgInner.setTopic(topic);
msgInner.setQueueId(0);
PutMessageResult putMessageResult = leaderStore.putMessage(msgInner);
Assert.assertEquals(PutMessageStatus.OS_PAGECACHE_BUSY, putMessageResult.getPutMessageStatus());
Thread.sleep(1000);
Assert.assertEquals(0, leaderStore.getCommitLog().getMaxOffset());
Assert.assertEquals(0, leaderStore.getMaxOffsetInQueue(topic, 0));
DefaultMessageStore followerStore = createDledgerMessageStore(createBaseDir(), group,"n1", peers, "n0", false, 0);
Thread.sleep(2000);
Assert.assertEquals(1, leaderStore.getMaxOffsetInQueue(topic, 0));
Assert.assertEquals(1, followerStore.getMaxOffsetInQueue(topic, 0));
Assert.assertTrue(leaderStore.getCommitLog().getMaxOffset() > 0);
leaderStore.destroy();
followerStore.destroy();
leaderStore.shutdown();
followerStore.shutdown();
}
} }
...@@ -19,6 +19,7 @@ package org.apache.rocketmq.store.dledger; ...@@ -19,6 +19,7 @@ package org.apache.rocketmq.store.dledger;
import io.openmessaging.storage.dledger.DLedgerConfig; import io.openmessaging.storage.dledger.DLedgerConfig;
import io.openmessaging.storage.dledger.DLedgerServer; import io.openmessaging.storage.dledger.DLedgerServer;
import java.io.File; import java.io.File;
import java.net.UnknownHostException;
import java.util.Arrays; import java.util.Arrays;
import org.apache.rocketmq.common.BrokerConfig; import org.apache.rocketmq.common.BrokerConfig;
import org.apache.rocketmq.common.message.MessageDecoder; import org.apache.rocketmq.common.message.MessageDecoder;
...@@ -118,7 +119,7 @@ public class MessageStoreTestBase extends StoreTestBase { ...@@ -118,7 +119,7 @@ public class MessageStoreTestBase extends StoreTestBase {
return defaultMessageStore; return defaultMessageStore;
} }
protected void doPutMessages(MessageStore messageStore, String topic, int queueId, int num, long beginLogicsOffset) { protected void doPutMessages(MessageStore messageStore, String topic, int queueId, int num, long beginLogicsOffset) throws UnknownHostException {
for (int i = 0; i < num; i++) { for (int i = 0; i < num; i++) {
MessageExtBrokerInner msgInner = buildMessage(); MessageExtBrokerInner msgInner = buildMessage();
msgInner.setTopic(topic); msgInner.setTopic(topic);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<parent> <parent>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<parent> <parent>
<groupId>org.apache.rocketmq</groupId> <groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-all</artifactId> <artifactId>rocketmq-all</artifactId>
<version>4.5.2-SNAPSHOT</version> <version>4.6.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册