You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2019/01/14 01:06:15 UTC
[servicecomb-java-chassis] branch master updated: [SCB-1101]
support IPv6 address format
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new a6f9221 [SCB-1101] support IPv6 address format
a6f9221 is described below
commit a6f9221d3e2d43956eac1e9a5e8c8d9a9ead543a
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Thu Jan 10 15:45:56 2019 +0800
[SCB-1101] support IPv6 address format
---
.../core/transport/TestAbstractTransport.java | 22 +++---
.../foundation/common/net/NetUtils.java | 80 ++++++++++++++++------
.../foundation/common/net/TestNetUtils.java | 78 +++++++++++++++++++--
.../servicecomb/serviceregistry/RegistryUtils.java | 7 +-
.../config/ServiceRegistryConfig.java | 2 +-
5 files changed, 146 insertions(+), 43 deletions(-)
diff --git a/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java b/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java
index 7490caa..c420f77 100644
--- a/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java
+++ b/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java
@@ -61,12 +61,12 @@ public class TestAbstractTransport {
}
@Override
- public boolean init() throws Exception {
+ public boolean init() {
return true;
}
@Override
- public void send(Invocation invocation, AsyncResponse asyncResp) throws Exception {
+ public void send(Invocation invocation, AsyncResponse asyncResp) {
}
}
@@ -104,7 +104,7 @@ public class TestAbstractTransport {
}
@Test
- public void testSetListenAddressWithoutSchemaChineseSpaceOldSC() throws UnsupportedEncodingException {
+ public void testSetListenAddressWithoutSchemaChineseSpaceOldSC() {
MyAbstractTransport transport = new MyAbstractTransport();
try {
transport.setListenAddressWithoutSchema("127.0.0.1:9090", Collections.singletonMap("country", "中 国"));
@@ -120,14 +120,14 @@ public class TestAbstractTransport {
}
@Test
- public void testSetListenAddressWithoutSchemaNormalNotEncode() throws UnsupportedEncodingException {
+ public void testSetListenAddressWithoutSchemaNormalNotEncode() {
MyAbstractTransport transport = new MyAbstractTransport();
transport.setListenAddressWithoutSchema("127.0.0.1:9090", Collections.singletonMap("country", "chinese"));
Assert.assertEquals("my://127.0.0.1:9090?country=chinese", transport.getEndpoint().getEndpoint());
}
@Test
- public void testSetListenAddressWithoutSchemaAlreadyHaveQuery() throws UnsupportedEncodingException {
+ public void testSetListenAddressWithoutSchemaAlreadyHaveQuery() {
MyAbstractTransport transport = new MyAbstractTransport();
transport.setListenAddressWithoutSchema("127.0.0.1:9090?a=aValue",
Collections.singletonMap("country", "chinese"));
@@ -135,7 +135,7 @@ public class TestAbstractTransport {
}
@Test
- public void testMyAbstractTransport() throws Exception {
+ public void testMyAbstractTransport() {
MyAbstractTransport transport = new MyAbstractTransport();
transport.setListenAddressWithoutSchema("127.0.0.1:9090");
Assert.assertEquals("my", transport.getName());
@@ -149,8 +149,8 @@ public class TestAbstractTransport {
Assert.assertEquals(30000, AbstractTransport.getReqTimeout("sayHi", "hello", "test"));
}
- @Test(expected = NumberFormatException.class)
- public void testMyAbstractTransportException(@Mocked TransportManager manager) throws Exception {
+ @Test(expected = IllegalArgumentException.class)
+ public void testMyAbstractTransportException(@Mocked TransportManager manager) {
MyAbstractTransport transport = new MyAbstractTransport();
transport.setListenAddressWithoutSchema(":127.0.0.1:9090");
@@ -160,7 +160,7 @@ public class TestAbstractTransport {
* Tests the request call timeout for service level timeout value
*/
@Test
- public void testRequestCfgService() throws Exception {
+ public void testRequestCfgService() {
System.setProperty("servicecomb.request.hello1.timeout", "3000");
//check for service level timeout value
Assert.assertEquals(3000, AbstractTransport.getReqTimeout("sayHello1", "sayHelloSchema1", "hello1"));
@@ -171,7 +171,7 @@ public class TestAbstractTransport {
* Tests the request call timeout for schema level timeout value
*/
@Test
- public void testRequestCfgSchema() throws Exception {
+ public void testRequestCfgSchema() {
System.setProperty("servicecomb.request.hello2.sayHelloSchema2.timeout", "2000");
Assert.assertEquals(2000, AbstractTransport.getReqTimeout("sayHello2", "sayHelloSchema2", "hello2"));
@@ -182,7 +182,7 @@ public class TestAbstractTransport {
* Tests the request call timeout for operatation level timeout value
*/
@Test
- public void testRequestCfgOperation() throws Exception {
+ public void testRequestCfgOperation() {
System.setProperty("servicecomb.request.hello3.sayHelloSchema3.sayHello3.timeout", "1000");
Assert.assertEquals(1000, AbstractTransport.getReqTimeout("sayHello3", "sayHelloSchema3", "hello3"));
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/NetUtils.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/NetUtils.java
index 30f8e29..fa7d52b 100644
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/NetUtils.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/NetUtils.java
@@ -70,6 +70,7 @@ public final class NetUtils {
hostAddress = availabelAddress.getHostAddress();
LOGGER.warn("cannot find a proper host address, choose {}, may not be correct.", hostAddress);
} else {
+ LOGGER.info("get localhost address: {}", localHost.getHostAddress());
hostAddress = localHost.getHostAddress();
}
@@ -124,32 +125,77 @@ public final class NetUtils {
}
/**
- * address ip:port格式
+ * The format of address should be {@code IPv4:port} or {@code [IPv6]:port}, or {@code host:port},
+ * or you will not get expected result.
+ *
+ * Note that the IPv6 address should be wrapped by square brackets.
+ * @return IpPort parsed from input param, or {@code null} if the param is null.
*/
public static IpPort parseIpPort(String address) {
if (address == null) {
return null;
}
- int idx = address.indexOf(':');
- if (idx == -1) {
- return null;
+ URI uri = URI.create("http://" + address);
+ return parseIpPort(uri, true);
+ }
+
+ /**
+ * Parse a {@link URI} into an {@link IpPort}.
+ *
+ * <p>
+ * A uri without port is allowed, in which case the port will be inferred from the scheme. {@code http} is 80, and
+ * {@code https} is 443.
+ * </p>
+ * <p>
+ * The host of the {@code uri} should not be null, or it will be treated as an illegal param,
+ * and an {@link IllegalArgumentException} will be thrown.
+ * </p>
+ */
+ public static IpPort parseIpPort(URI uri) {
+ return parseIpPort(uri, false);
+ }
+
+ /**
+ * Parse a {@link URI} into an {@link IpPort}
+ * @param uri a uri representing {@link IpPort}
+ * @param ignorePortUndefined whether the port should be inferred from scheme, when the port part of {@code uri} is {@code -1}.
+ * If {@code true} the undefined port is ignored;
+ * otherwise a port will be inferred from scheme: {@code http} is 80, and {@code https} is 443.
+ */
+ public static IpPort parseIpPort(URI uri, boolean ignorePortUndefined) {
+ if (null == uri.getHost()) {
+ // if the format of address is legal but the value is out of range, URI#create(String) will not throw exception
+ // but return a URI with null host.
+ throw new IllegalArgumentException("Illegal uri: [" + uri + "]");
}
- String hostOrIp = address.substring(0, idx);
- int port = Integer.parseInt(address.substring(idx + 1));
- return new IpPort(hostOrIp, port);
+ IpPort ipPort = new IpPort(uri.getHost(), uri.getPort());
+ if (-1 != ipPort.getPort() || ignorePortUndefined) {
+ return ipPort;
+ }
+
+ if (uri.getScheme().equals("http")) {
+ ipPort.setPort(80);
+ }
+ if (uri.getScheme().equals("https")) {
+ ipPort.setPort(443);
+ }
+
+ return ipPort;
}
+ /**
+ * @param uriAddress the address containing IP and port info.
+ * @return IpPort parsed from input param, or {@code null} if the param is null.
+ */
public static IpPort parseIpPortFromURI(String uriAddress) {
if (uriAddress == null) {
return null;
}
try {
- URI uri = new URI(uriAddress);
- String authority = uri.getAuthority();
- return parseIpPort(uri.getScheme(), authority);
+ return parseIpPort(new URI(uriAddress));
} catch (URISyntaxException e) {
return null;
}
@@ -159,17 +205,7 @@ public final class NetUtils {
if (authority == null) {
return null;
}
- int idx = authority.indexOf(':');
- if (idx != -1) {
- return parseIpPort(authority);
- }
- if (scheme.equals("http")) {
- return new IpPort(authority, 80);
- }
- if (scheme.equals("https")) {
- return new IpPort(authority, 443);
- }
- return null;
+ return parseIpPort(URI.create(scheme + "://" + authority));
}
/**
@@ -184,7 +220,7 @@ public final class NetUtils {
}
try {
URI originalURI = new URI(schema + "://" + address);
- IpPort ipPort = NetUtils.parseIpPort(originalURI.getAuthority());
+ IpPort ipPort = NetUtils.parseIpPort(originalURI);
if (ipPort == null) {
LOGGER.error("address {} is not valid.", address);
return null;
diff --git a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/net/TestNetUtils.java b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/net/TestNetUtils.java
index 15e157f..a363747 100644
--- a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/net/TestNetUtils.java
+++ b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/net/TestNetUtils.java
@@ -17,11 +17,14 @@
package org.apache.servicecomb.foundation.common.net;
+import static org.junit.Assert.fail;
+
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.Consumer;
import org.junit.Assert;
import org.junit.Test;
@@ -41,18 +44,69 @@ public class TestNetUtils {
}
@Test
- public void testNetutils() {
+ public void testNetUtils() {
Assert.assertEquals("127.0.0.1", NetUtils.parseIpPort("127.0.0.1:8080").getHostOrIp());
Assert.assertEquals(8080, NetUtils.parseIpPort("127.0.0.1:8080").getPort());
- Assert.assertEquals(null, NetUtils.parseIpPort(null));
- Assert.assertEquals(null, NetUtils.parseIpPort("127.0.0.18080"));
+ Assert.assertEquals("127.0.0.1", NetUtils.parseIpPort("127.0.0.1").getHostOrIp());
+ Assert.assertEquals(-1, NetUtils.parseIpPort("127.0.0.1").getPort());
+ Assert.assertEquals(null, NetUtils.parseIpPort((String) null));
Assert.assertEquals(null, NetUtils.parseIpPortFromURI(null));
- Assert.assertEquals(null, NetUtils.parseIpPortFromURI("ss"));
Assert.assertEquals("127.0.0.1", NetUtils.parseIpPortFromURI("rest://127.0.0.1:8080").getHostOrIp());
Assert.assertEquals(8080, NetUtils.parseIpPortFromURI("http://127.0.0.1:8080").getPort());
Assert.assertEquals(80, NetUtils.parseIpPortFromURI("http://127.0.0.1").getPort());
Assert.assertEquals(8080, NetUtils.parseIpPortFromURI("https://127.0.0.1:8080").getPort());
Assert.assertEquals(443, NetUtils.parseIpPortFromURI("https://127.0.0.1").getPort());
+
+ Assert.assertEquals(30000, NetUtils.parseIpPort("http", "127.0.0.1:30000").getPort());
+ Assert.assertEquals("127.0.0.1", NetUtils.parseIpPort("http", "127.0.0.1:30000").getHostOrIp());
+ Assert.assertEquals(30000, NetUtils.parseIpPort("https", "127.0.0.1:30000").getPort());
+ Assert.assertEquals("127.0.0.1", NetUtils.parseIpPort("https", "127.0.0.1:30000").getHostOrIp());
+ Assert.assertEquals(80, NetUtils.parseIpPort("http", "127.0.0.1").getPort());
+ Assert.assertEquals("127.0.0.1", NetUtils.parseIpPort("http", "127.0.0.1").getHostOrIp());
+ Assert.assertEquals(443, NetUtils.parseIpPort("https", "127.0.0.1").getPort());
+ Assert.assertEquals("127.0.0.1", NetUtils.parseIpPort("https", "127.0.0.1").getHostOrIp());
+ Assert.assertNull(NetUtils.parseIpPort("http", null));
+
+ checkException(v -> NetUtils.parseIpPort("127.0.0.18080"));
+ checkException(v -> NetUtils.parseIpPortFromURI("ss"));
+ }
+
+ @Test
+ public void testNetUtilsIPv6() {
+ Assert.assertEquals("[::1]", NetUtils.parseIpPort("[::1]:8080").getHostOrIp());
+ Assert.assertEquals("[::]", NetUtils.parseIpPort("[::]:8080").getHostOrIp());
+ Assert.assertEquals("[fe80::f816:3eff:feda:38cd%eth0]",
+ NetUtils.parseIpPort("[fe80::f816:3eff:feda:38cd%eth0]:8080").getHostOrIp());
+ Assert.assertEquals("[fe80::38f7:44b8:8ab1:468%16]",
+ NetUtils.parseIpPort("[fe80::38f7:44b8:8ab1:468%16]:8080").getHostOrIp());
+ Assert.assertEquals(8080, NetUtils.parseIpPort("[::1]:8080").getPort());
+ Assert.assertEquals(8080, NetUtils.parseIpPort("[::]:8080").getPort());
+ Assert.assertEquals(8080, NetUtils.parseIpPort("[fe80::f816:3eff:feda:38cd%eth0]:8080").getPort());
+ Assert.assertEquals(8080, NetUtils.parseIpPort("[fe80::38f7:44b8:8ab1:468%16]:8080").getPort());
+
+ Assert.assertEquals("[::1]", NetUtils.parseIpPortFromURI("rest://[::1]:8080").getHostOrIp());
+ Assert.assertEquals("[::]", NetUtils.parseIpPortFromURI("rest://[::]:8080").getHostOrIp());
+ Assert.assertEquals("[fe80::f816:3eff:feda:38cd%eth0]",
+ NetUtils.parseIpPortFromURI("rest://[fe80::f816:3eff:feda:38cd%eth0]:8080").getHostOrIp());
+ Assert.assertEquals("[fe80::38f7:44b8:8ab1:468%16]",
+ NetUtils.parseIpPortFromURI("rest://[fe80::38f7:44b8:8ab1:468%16]:8080").getHostOrIp());
+ Assert.assertEquals(8080, NetUtils.parseIpPortFromURI("rest://[::1]:8080").getPort());
+ Assert.assertEquals(80, NetUtils.parseIpPortFromURI("http://[::1]").getPort());
+ Assert.assertEquals(8080, NetUtils.parseIpPortFromURI("https://[::1]:8080").getPort());
+ Assert.assertEquals(443, NetUtils.parseIpPortFromURI("https://[::1]").getPort());
+
+ Assert.assertEquals(30000, NetUtils.parseIpPort("http", "[fe80::f816:3eff:feda:38cd%eth0]:30000").getPort());
+ Assert.assertEquals("[fe80::f816:3eff:feda:38cd%eth0]",
+ NetUtils.parseIpPort("http", "[fe80::f816:3eff:feda:38cd%eth0]:30000").getHostOrIp());
+ Assert.assertEquals(30000, NetUtils.parseIpPort("https", "[fe80::f816:3eff:feda:38cd%eth0]:30000").getPort());
+ Assert.assertEquals("[fe80::f816:3eff:feda:38cd%eth0]",
+ NetUtils.parseIpPort("https", "[fe80::f816:3eff:feda:38cd%eth0]:30000").getHostOrIp());
+ Assert.assertEquals(80, NetUtils.parseIpPort("http", "[fe80::f816:3eff:feda:38cd%eth0]").getPort());
+ Assert.assertEquals("[fe80::f816:3eff:feda:38cd%eth0]",
+ NetUtils.parseIpPort("http", "[fe80::f816:3eff:feda:38cd%eth0]").getHostOrIp());
+ Assert.assertEquals(443, NetUtils.parseIpPort("https", "[fe80::f816:3eff:feda:38cd%eth0]").getPort());
+ Assert.assertEquals("[fe80::f816:3eff:feda:38cd%eth0]",
+ NetUtils.parseIpPort("https", "[fe80::f816:3eff:feda:38cd%eth0]").getHostOrIp());
}
@Test
@@ -64,8 +118,9 @@ public class TestNetUtils {
@Test
public void testGetRealListenAddress() {
Assert.assertNull(NetUtils.getRealListenAddress("http", null));
- Assert.assertNull(NetUtils.getRealListenAddress("http:1", "1.1.1.1:8080"));
Assert.assertEquals("http://1.1.1.1:8080", NetUtils.getRealListenAddress("http", "1.1.1.1:8080"));
+
+ checkException(v -> NetUtils.getRealListenAddress("http:1", "1.1.1.1:8080"));
}
@Test
@@ -82,7 +137,7 @@ public class TestNetUtils {
try {
NetUtils.ensureGetInterfaceAddress("xxx");
- Assert.fail("must throw exception");
+ fail("must throw exception");
} catch (IllegalArgumentException e) {
Assert.assertEquals("Can not find address for interface name: xxx", e.getMessage());
}
@@ -109,7 +164,7 @@ public class TestNetUtils {
}
@Test
- public void humanReadableBytes() throws IOException {
+ public void humanReadableBytes() {
Assert.assertEquals("0", NetUtils.humanReadableBytes(0L));
Assert.assertEquals("1", NetUtils.humanReadableBytes(1L));
Assert.assertEquals("1023", NetUtils.humanReadableBytes(1023L));
@@ -158,4 +213,13 @@ public class TestNetUtils {
Deencapsulation.setField(NetUtils.class, "hostAddress", null);
Assert.assertNotEquals(null, NetUtils.getHostAddress());
}
+
+ public void checkException(Consumer<Void> testedBehavior) {
+ try {
+ testedBehavior.accept(null);
+ fail("IllegalArgumentException is expected!");
+ } catch (Exception e) {
+ Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+ }
+ }
}
diff --git a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/RegistryUtils.java b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/RegistryUtils.java
index 1853578..6787a28 100644
--- a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/RegistryUtils.java
+++ b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/RegistryUtils.java
@@ -146,7 +146,10 @@ public final class RegistryUtils {
}
/**
- * 对于配置为0.0.0.0的地址,通过查询网卡地址,转换为实际监听的地址。
+ * In the case that listening address configured as 0.0.0.0, the publish address will be determined
+ * by the query result for the net interfaces.
+ *
+ * @return the publish address, or {@code null} if the param {@code address} is null.
*/
public static String getPublishAddress(String schema, String address) {
if (address == null) {
@@ -155,7 +158,7 @@ public final class RegistryUtils {
try {
URI originalURI = new URI(schema + "://" + address);
- IpPort ipPort = NetUtils.parseIpPort(originalURI.getAuthority());
+ IpPort ipPort = NetUtils.parseIpPort(originalURI);
if (ipPort == null) {
LOGGER.warn("address {} not valid.", address);
return null;
diff --git a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfig.java b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfig.java
index c4eccdf..98e126d 100644
--- a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfig.java
+++ b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfig.java
@@ -137,7 +137,7 @@ public final class ServiceRegistryConfig {
try {
URI uri = new URI(anUriList.trim());
this.ssl = "https".equals(uri.getScheme());
- ipPortList.add(NetUtils.parseIpPort(uri.getScheme(), uri.getAuthority()));
+ ipPortList.add(NetUtils.parseIpPort(uri));
} catch (Exception e) {
LOGGER.error("servicecomb.service.registry.address invalid : {}", anUriList, e);
}